Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of azure_c_shared_utility by
httpapiex.c@2:20b88da3e604, 2016-05-09 (annotated)
- Committer:
- AzureIoTClient
- Date:
- Mon May 09 14:37:45 2016 -0700
- Revision:
- 2:20b88da3e604
- Parent:
- 1:9190c0f4d23a
- Child:
- 6:c55b013dfc2a
1.0.6
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Azure.IoT Build | 0:fa2de1b79154 | 1 | // Copyright (c) Microsoft. All rights reserved. |
Azure.IoT Build | 0:fa2de1b79154 | 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. |
Azure.IoT Build | 0:fa2de1b79154 | 3 | |
Azure.IoT Build | 0:fa2de1b79154 | 4 | #include <stdlib.h> |
Azure.IoT Build | 0:fa2de1b79154 | 5 | #ifdef _CRTDBG_MAP_ALLOC |
Azure.IoT Build | 0:fa2de1b79154 | 6 | #include <crtdbg.h> |
Azure.IoT Build | 0:fa2de1b79154 | 7 | #endif |
Azure.IoT Build | 0:fa2de1b79154 | 8 | #include "azure_c_shared_utility/gballoc.h" |
Azure.IoT Build | 0:fa2de1b79154 | 9 | |
Azure.IoT Build | 0:fa2de1b79154 | 10 | #include "azure_c_shared_utility/httpapiex.h" |
Azure.IoT Build | 0:fa2de1b79154 | 11 | #include "azure_c_shared_utility/iot_logging.h" |
Azure.IoT Build | 0:fa2de1b79154 | 12 | #include "azure_c_shared_utility/strings.h" |
Azure.IoT Build | 0:fa2de1b79154 | 13 | #include "azure_c_shared_utility/crt_abstractions.h" |
Azure.IoT Build | 0:fa2de1b79154 | 14 | #include "azure_c_shared_utility/vector.h" |
Azure.IoT Build | 0:fa2de1b79154 | 15 | |
Azure.IoT Build | 0:fa2de1b79154 | 16 | typedef struct HTTPAPIEX_SAVED_OPTION_TAG |
Azure.IoT Build | 0:fa2de1b79154 | 17 | { |
Azure.IoT Build | 0:fa2de1b79154 | 18 | const char* optionName; |
Azure.IoT Build | 0:fa2de1b79154 | 19 | const void* value; |
Azure.IoT Build | 0:fa2de1b79154 | 20 | }HTTPAPIEX_SAVED_OPTION; |
Azure.IoT Build | 0:fa2de1b79154 | 21 | |
Azure.IoT Build | 0:fa2de1b79154 | 22 | typedef struct HTTPAPIEX_HANDLE_DATA_TAG |
Azure.IoT Build | 0:fa2de1b79154 | 23 | { |
Azure.IoT Build | 0:fa2de1b79154 | 24 | STRING_HANDLE hostName; |
Azure.IoT Build | 0:fa2de1b79154 | 25 | int k; |
Azure.IoT Build | 0:fa2de1b79154 | 26 | HTTP_HANDLE httpHandle; |
Azure.IoT Build | 0:fa2de1b79154 | 27 | VECTOR_HANDLE savedOptions; |
Azure.IoT Build | 0:fa2de1b79154 | 28 | }HTTPAPIEX_HANDLE_DATA; |
Azure.IoT Build | 0:fa2de1b79154 | 29 | |
Azure.IoT Build | 0:fa2de1b79154 | 30 | DEFINE_ENUM_STRINGS(HTTPAPIEX_RESULT, HTTPAPIEX_RESULT_VALUES); |
Azure.IoT Build | 0:fa2de1b79154 | 31 | |
AzureIoTClient | 1:9190c0f4d23a | 32 | #define LOG_HTTAPIEX_ERROR() LogError("error code = %s", ENUM_TO_STRING(HTTPAPIEX_RESULT, result)) |
Azure.IoT Build | 0:fa2de1b79154 | 33 | |
Azure.IoT Build | 0:fa2de1b79154 | 34 | HTTPAPIEX_HANDLE HTTPAPIEX_Create(const char* hostName) |
Azure.IoT Build | 0:fa2de1b79154 | 35 | { |
Azure.IoT Build | 0:fa2de1b79154 | 36 | HTTPAPIEX_HANDLE result; |
Azure.IoT Build | 0:fa2de1b79154 | 37 | /*Codes_SRS_HTTPAPIEX_02_001: [If parameter hostName is NULL then HTTPAPIEX_Create shall return NULL.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 38 | if (hostName == NULL) |
Azure.IoT Build | 0:fa2de1b79154 | 39 | { |
AzureIoTClient | 1:9190c0f4d23a | 40 | LogError("invalid (NULL) parameter"); |
Azure.IoT Build | 0:fa2de1b79154 | 41 | result = NULL; |
Azure.IoT Build | 0:fa2de1b79154 | 42 | } |
Azure.IoT Build | 0:fa2de1b79154 | 43 | else |
Azure.IoT Build | 0:fa2de1b79154 | 44 | { |
Azure.IoT Build | 0:fa2de1b79154 | 45 | /*Codes_SRS_HTTPAPIEX_02_005: [If creating the handle fails for any reason, then HTTAPIEX_Create shall return NULL.] */ |
Azure.IoT Build | 0:fa2de1b79154 | 46 | HTTPAPIEX_HANDLE_DATA* handleData = (HTTPAPIEX_HANDLE_DATA*)malloc(sizeof(HTTPAPIEX_HANDLE_DATA)); |
Azure.IoT Build | 0:fa2de1b79154 | 47 | if (handleData == NULL) |
Azure.IoT Build | 0:fa2de1b79154 | 48 | { |
AzureIoTClient | 1:9190c0f4d23a | 49 | LogError("malloc failed."); |
Azure.IoT Build | 0:fa2de1b79154 | 50 | result = NULL; |
Azure.IoT Build | 0:fa2de1b79154 | 51 | } |
Azure.IoT Build | 0:fa2de1b79154 | 52 | else |
Azure.IoT Build | 0:fa2de1b79154 | 53 | { |
Azure.IoT Build | 0:fa2de1b79154 | 54 | /*Codes_SRS_HTTPAPIEX_02_002: [Parameter hostName shall be saved.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 55 | handleData->hostName = STRING_construct(hostName); |
Azure.IoT Build | 0:fa2de1b79154 | 56 | if (handleData->hostName == NULL) |
Azure.IoT Build | 0:fa2de1b79154 | 57 | { |
Azure.IoT Build | 0:fa2de1b79154 | 58 | free(handleData); |
AzureIoTClient | 1:9190c0f4d23a | 59 | LogError("unable to STRING_construct"); |
Azure.IoT Build | 0:fa2de1b79154 | 60 | result = NULL; |
Azure.IoT Build | 0:fa2de1b79154 | 61 | } |
Azure.IoT Build | 0:fa2de1b79154 | 62 | else |
Azure.IoT Build | 0:fa2de1b79154 | 63 | { |
Azure.IoT Build | 0:fa2de1b79154 | 64 | /*Codes_SRS_HTTPAPIEX_02_004: [Otherwise, HTTPAPIEX_Create shall return a HTTAPIEX_HANDLE suitable for further calls to the module.] */ |
Azure.IoT Build | 0:fa2de1b79154 | 65 | handleData->savedOptions = VECTOR_create(sizeof(HTTPAPIEX_SAVED_OPTION)); |
Azure.IoT Build | 0:fa2de1b79154 | 66 | if (handleData->savedOptions == NULL) |
Azure.IoT Build | 0:fa2de1b79154 | 67 | { |
Azure.IoT Build | 0:fa2de1b79154 | 68 | STRING_delete(handleData->hostName); |
Azure.IoT Build | 0:fa2de1b79154 | 69 | free(handleData); |
Azure.IoT Build | 0:fa2de1b79154 | 70 | result = NULL; |
Azure.IoT Build | 0:fa2de1b79154 | 71 | } |
Azure.IoT Build | 0:fa2de1b79154 | 72 | else |
Azure.IoT Build | 0:fa2de1b79154 | 73 | { |
Azure.IoT Build | 0:fa2de1b79154 | 74 | handleData->k = -1; |
Azure.IoT Build | 0:fa2de1b79154 | 75 | handleData->httpHandle = NULL; |
Azure.IoT Build | 0:fa2de1b79154 | 76 | result = handleData; |
Azure.IoT Build | 0:fa2de1b79154 | 77 | } |
Azure.IoT Build | 0:fa2de1b79154 | 78 | } |
Azure.IoT Build | 0:fa2de1b79154 | 79 | } |
Azure.IoT Build | 0:fa2de1b79154 | 80 | } |
Azure.IoT Build | 0:fa2de1b79154 | 81 | return result; |
Azure.IoT Build | 0:fa2de1b79154 | 82 | } |
Azure.IoT Build | 0:fa2de1b79154 | 83 | |
Azure.IoT Build | 0:fa2de1b79154 | 84 | /*this function builds the default request http headers if none are specified*/ |
Azure.IoT Build | 0:fa2de1b79154 | 85 | /*returns 0 if no error*/ |
Azure.IoT Build | 0:fa2de1b79154 | 86 | /*any other code is error*/ |
Azure.IoT Build | 0:fa2de1b79154 | 87 | static int buildRequestHttpHeadersHandle(HTTPAPIEX_HANDLE_DATA *handleData, BUFFER_HANDLE requestContent, HTTP_HEADERS_HANDLE originalRequestHttpHeadersHandle, bool* isOriginalRequestHttpHeadersHandle, HTTP_HEADERS_HANDLE* toBeUsedRequestHttpHeadersHandle) |
Azure.IoT Build | 0:fa2de1b79154 | 88 | { |
Azure.IoT Build | 0:fa2de1b79154 | 89 | int result; |
Azure.IoT Build | 0:fa2de1b79154 | 90 | |
Azure.IoT Build | 0:fa2de1b79154 | 91 | |
Azure.IoT Build | 0:fa2de1b79154 | 92 | if (originalRequestHttpHeadersHandle != NULL) |
Azure.IoT Build | 0:fa2de1b79154 | 93 | { |
Azure.IoT Build | 0:fa2de1b79154 | 94 | *toBeUsedRequestHttpHeadersHandle = originalRequestHttpHeadersHandle; |
Azure.IoT Build | 0:fa2de1b79154 | 95 | *isOriginalRequestHttpHeadersHandle = true; |
Azure.IoT Build | 0:fa2de1b79154 | 96 | |
Azure.IoT Build | 0:fa2de1b79154 | 97 | } |
Azure.IoT Build | 0:fa2de1b79154 | 98 | else |
Azure.IoT Build | 0:fa2de1b79154 | 99 | { |
Azure.IoT Build | 0:fa2de1b79154 | 100 | /*Codes_SRS_HTTPAPIEX_02_009: [If parameter requestHttpHeadersHandle is NULL then HTTPAPIEX_ExecuteRequest shall allocate a temporary internal instance of HTTPHEADERS, shall add to that instance the following headers |
Azure.IoT Build | 0:fa2de1b79154 | 101 | Host:{hostname} - as it was indicated by the call to HTTPAPIEX_Create API call |
Azure.IoT Build | 0:fa2de1b79154 | 102 | Content-Length:the size of the requestContent parameter, and use this instance to all the subsequent calls to HTTPAPI_ExecuteRequest as parameter httpHeadersHandle.] |
Azure.IoT Build | 0:fa2de1b79154 | 103 | */ |
Azure.IoT Build | 0:fa2de1b79154 | 104 | *isOriginalRequestHttpHeadersHandle = false; |
Azure.IoT Build | 0:fa2de1b79154 | 105 | *toBeUsedRequestHttpHeadersHandle = HTTPHeaders_Alloc(); |
Azure.IoT Build | 0:fa2de1b79154 | 106 | } |
Azure.IoT Build | 0:fa2de1b79154 | 107 | |
Azure.IoT Build | 0:fa2de1b79154 | 108 | if (*toBeUsedRequestHttpHeadersHandle == NULL) |
Azure.IoT Build | 0:fa2de1b79154 | 109 | { |
Azure.IoT Build | 0:fa2de1b79154 | 110 | result = __LINE__; |
AzureIoTClient | 1:9190c0f4d23a | 111 | LogError("unable to HTTPHeaders_Alloc"); |
Azure.IoT Build | 0:fa2de1b79154 | 112 | } |
Azure.IoT Build | 0:fa2de1b79154 | 113 | else |
Azure.IoT Build | 0:fa2de1b79154 | 114 | { |
AzureIoTClient | 2:20b88da3e604 | 115 | char temp[22] = { 0 }; |
Azure.IoT Build | 0:fa2de1b79154 | 116 | (void)size_tToString(temp, 22, BUFFER_length(requestContent)); /*cannot fail, MAX_uint64 has 19 digits*/ |
Azure.IoT Build | 0:fa2de1b79154 | 117 | /*Codes_SRS_HTTPAPIEX_02_011: [If parameter requestHttpHeadersHandle is not NULL then HTTPAPIEX_ExecuteRequest shall create or update the following headers of the request: |
Azure.IoT Build | 0:fa2de1b79154 | 118 | Host:{hostname} |
Azure.IoT Build | 0:fa2de1b79154 | 119 | Content-Length:the size of the requestContent parameter, and shall use the so constructed HTTPHEADERS object to all calls to HTTPAPI_ExecuteRequest as parameter httpHeadersHandle.] |
Azure.IoT Build | 0:fa2de1b79154 | 120 | */ |
Azure.IoT Build | 0:fa2de1b79154 | 121 | /*Codes_SRS_HTTPAPIEX_02_009: [If parameter requestHttpHeadersHandle is NULL then HTTPAPIEX_ExecuteRequest shall allocate a temporary internal instance of HTTPHEADERS, shall add to that instance the following headers |
Azure.IoT Build | 0:fa2de1b79154 | 122 | Host:{hostname} - as it was indicated by the call to HTTPAPIEX_Create API call |
Azure.IoT Build | 0:fa2de1b79154 | 123 | Content-Length:the size of the requestContent parameter, and use this instance to all the subsequent calls to HTTPAPI_ExecuteRequest as parameter httpHeadersHandle.] |
Azure.IoT Build | 0:fa2de1b79154 | 124 | */ |
Azure.IoT Build | 0:fa2de1b79154 | 125 | if (!( |
Azure.IoT Build | 0:fa2de1b79154 | 126 | (HTTPHeaders_ReplaceHeaderNameValuePair(*toBeUsedRequestHttpHeadersHandle, "Host", STRING_c_str(handleData->hostName)) == HTTP_HEADERS_OK) && |
Azure.IoT Build | 0:fa2de1b79154 | 127 | (HTTPHeaders_ReplaceHeaderNameValuePair(*toBeUsedRequestHttpHeadersHandle, "Content-Length", temp) == HTTP_HEADERS_OK) |
Azure.IoT Build | 0:fa2de1b79154 | 128 | )) |
Azure.IoT Build | 0:fa2de1b79154 | 129 | { |
Azure.IoT Build | 0:fa2de1b79154 | 130 | if (! *isOriginalRequestHttpHeadersHandle) |
Azure.IoT Build | 0:fa2de1b79154 | 131 | { |
Azure.IoT Build | 0:fa2de1b79154 | 132 | HTTPHeaders_Free(*toBeUsedRequestHttpHeadersHandle); |
Azure.IoT Build | 0:fa2de1b79154 | 133 | } |
Azure.IoT Build | 0:fa2de1b79154 | 134 | *toBeUsedRequestHttpHeadersHandle = NULL; |
Azure.IoT Build | 0:fa2de1b79154 | 135 | result = __LINE__; |
Azure.IoT Build | 0:fa2de1b79154 | 136 | } |
Azure.IoT Build | 0:fa2de1b79154 | 137 | else |
Azure.IoT Build | 0:fa2de1b79154 | 138 | { |
Azure.IoT Build | 0:fa2de1b79154 | 139 | result = 0; |
Azure.IoT Build | 0:fa2de1b79154 | 140 | } |
Azure.IoT Build | 0:fa2de1b79154 | 141 | } |
Azure.IoT Build | 0:fa2de1b79154 | 142 | return result; |
Azure.IoT Build | 0:fa2de1b79154 | 143 | } |
Azure.IoT Build | 0:fa2de1b79154 | 144 | |
Azure.IoT Build | 0:fa2de1b79154 | 145 | static int buildResponseHttpHeadersHandle(HTTP_HEADERS_HANDLE originalResponsetHttpHeadersHandle, bool* isOriginalResponseHttpHeadersHandle, HTTP_HEADERS_HANDLE* toBeUsedResponsetHttpHeadersHandle) |
Azure.IoT Build | 0:fa2de1b79154 | 146 | { |
Azure.IoT Build | 0:fa2de1b79154 | 147 | int result; |
Azure.IoT Build | 0:fa2de1b79154 | 148 | if (originalResponsetHttpHeadersHandle == NULL) |
Azure.IoT Build | 0:fa2de1b79154 | 149 | { |
Azure.IoT Build | 0:fa2de1b79154 | 150 | if ((*toBeUsedResponsetHttpHeadersHandle = HTTPHeaders_Alloc()) == NULL) |
Azure.IoT Build | 0:fa2de1b79154 | 151 | { |
Azure.IoT Build | 0:fa2de1b79154 | 152 | result = __LINE__; |
Azure.IoT Build | 0:fa2de1b79154 | 153 | } |
Azure.IoT Build | 0:fa2de1b79154 | 154 | else |
Azure.IoT Build | 0:fa2de1b79154 | 155 | { |
Azure.IoT Build | 0:fa2de1b79154 | 156 | *isOriginalResponseHttpHeadersHandle = false; |
Azure.IoT Build | 0:fa2de1b79154 | 157 | result = 0; |
Azure.IoT Build | 0:fa2de1b79154 | 158 | } |
Azure.IoT Build | 0:fa2de1b79154 | 159 | } |
Azure.IoT Build | 0:fa2de1b79154 | 160 | else |
Azure.IoT Build | 0:fa2de1b79154 | 161 | { |
Azure.IoT Build | 0:fa2de1b79154 | 162 | *isOriginalResponseHttpHeadersHandle = true; |
Azure.IoT Build | 0:fa2de1b79154 | 163 | *toBeUsedResponsetHttpHeadersHandle = originalResponsetHttpHeadersHandle; |
Azure.IoT Build | 0:fa2de1b79154 | 164 | result = 0; |
Azure.IoT Build | 0:fa2de1b79154 | 165 | } |
Azure.IoT Build | 0:fa2de1b79154 | 166 | return result; |
Azure.IoT Build | 0:fa2de1b79154 | 167 | } |
Azure.IoT Build | 0:fa2de1b79154 | 168 | |
Azure.IoT Build | 0:fa2de1b79154 | 169 | |
Azure.IoT Build | 0:fa2de1b79154 | 170 | static int buildBufferIfNotExist(BUFFER_HANDLE originalRequestContent, bool* isOriginalRequestContent, BUFFER_HANDLE* toBeUsedRequestContent) |
Azure.IoT Build | 0:fa2de1b79154 | 171 | { |
Azure.IoT Build | 0:fa2de1b79154 | 172 | int result; |
Azure.IoT Build | 0:fa2de1b79154 | 173 | if (originalRequestContent == NULL) |
Azure.IoT Build | 0:fa2de1b79154 | 174 | { |
Azure.IoT Build | 0:fa2de1b79154 | 175 | *toBeUsedRequestContent = BUFFER_new(); |
Azure.IoT Build | 0:fa2de1b79154 | 176 | if (*toBeUsedRequestContent == NULL) |
Azure.IoT Build | 0:fa2de1b79154 | 177 | { |
Azure.IoT Build | 0:fa2de1b79154 | 178 | result = __LINE__; |
Azure.IoT Build | 0:fa2de1b79154 | 179 | } |
Azure.IoT Build | 0:fa2de1b79154 | 180 | else |
Azure.IoT Build | 0:fa2de1b79154 | 181 | { |
Azure.IoT Build | 0:fa2de1b79154 | 182 | *isOriginalRequestContent = false; |
Azure.IoT Build | 0:fa2de1b79154 | 183 | result = 0; |
Azure.IoT Build | 0:fa2de1b79154 | 184 | } |
Azure.IoT Build | 0:fa2de1b79154 | 185 | } |
Azure.IoT Build | 0:fa2de1b79154 | 186 | else |
Azure.IoT Build | 0:fa2de1b79154 | 187 | { |
Azure.IoT Build | 0:fa2de1b79154 | 188 | *isOriginalRequestContent = true; |
Azure.IoT Build | 0:fa2de1b79154 | 189 | *toBeUsedRequestContent = originalRequestContent; |
Azure.IoT Build | 0:fa2de1b79154 | 190 | result = 0; |
Azure.IoT Build | 0:fa2de1b79154 | 191 | } |
Azure.IoT Build | 0:fa2de1b79154 | 192 | return result; |
Azure.IoT Build | 0:fa2de1b79154 | 193 | } |
Azure.IoT Build | 0:fa2de1b79154 | 194 | |
Azure.IoT Build | 0:fa2de1b79154 | 195 | static unsigned int dummyStatusCode; |
Azure.IoT Build | 0:fa2de1b79154 | 196 | |
Azure.IoT Build | 0:fa2de1b79154 | 197 | static int buildAllRequests(HTTPAPIEX_HANDLE_DATA* handle, HTTPAPI_REQUEST_TYPE requestType, const char* relativePath, |
Azure.IoT Build | 0:fa2de1b79154 | 198 | HTTP_HEADERS_HANDLE requestHttpHeadersHandle, BUFFER_HANDLE requestContent, unsigned int* statusCode, |
Azure.IoT Build | 0:fa2de1b79154 | 199 | HTTP_HEADERS_HANDLE responseHttpHeadersHandle, BUFFER_HANDLE responseContent, |
Azure.IoT Build | 0:fa2de1b79154 | 200 | |
Azure.IoT Build | 0:fa2de1b79154 | 201 | const char** toBeUsedRelativePath, |
Azure.IoT Build | 0:fa2de1b79154 | 202 | HTTP_HEADERS_HANDLE *toBeUsedRequestHttpHeadersHandle, bool *isOriginalRequestHttpHeadersHandle, |
Azure.IoT Build | 0:fa2de1b79154 | 203 | BUFFER_HANDLE *toBeUsedRequestContent, bool *isOriginalRequestContent, |
Azure.IoT Build | 0:fa2de1b79154 | 204 | unsigned int** toBeUsedStatusCode, |
Azure.IoT Build | 0:fa2de1b79154 | 205 | HTTP_HEADERS_HANDLE *toBeUsedResponseHttpHeadersHandle, bool *isOriginalResponseHttpHeadersHandle, |
Azure.IoT Build | 0:fa2de1b79154 | 206 | BUFFER_HANDLE *toBeUsedResponseContent, bool *isOriginalResponseContent) |
Azure.IoT Build | 0:fa2de1b79154 | 207 | { |
Azure.IoT Build | 0:fa2de1b79154 | 208 | int result; |
Azure.IoT Build | 0:fa2de1b79154 | 209 | (void)requestType; |
Azure.IoT Build | 0:fa2de1b79154 | 210 | /*Codes_SRS_HTTPAPIEX_02_013: [If requestContent is NULL then HTTPAPIEX_ExecuteRequest shall behave as if a buffer of zero size would have been used, that is, it shall call HTTPAPI_ExecuteRequest with parameter content = NULL and contentLength = 0.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 211 | /*Codes_SRS_HTTPAPIEX_02_014: [If requestContent is not NULL then its content and its size shall be used for parameters content and contentLength of HTTPAPI_ExecuteRequest.] */ |
Azure.IoT Build | 0:fa2de1b79154 | 212 | if (buildBufferIfNotExist(requestContent, isOriginalRequestContent, toBeUsedRequestContent) != 0) |
Azure.IoT Build | 0:fa2de1b79154 | 213 | { |
Azure.IoT Build | 0:fa2de1b79154 | 214 | result = __LINE__; |
AzureIoTClient | 1:9190c0f4d23a | 215 | LogError("unable to build the request content"); |
Azure.IoT Build | 0:fa2de1b79154 | 216 | } |
Azure.IoT Build | 0:fa2de1b79154 | 217 | else |
Azure.IoT Build | 0:fa2de1b79154 | 218 | { |
Azure.IoT Build | 0:fa2de1b79154 | 219 | if (buildRequestHttpHeadersHandle(handle, *toBeUsedRequestContent, requestHttpHeadersHandle, isOriginalRequestHttpHeadersHandle, toBeUsedRequestHttpHeadersHandle) != 0) |
Azure.IoT Build | 0:fa2de1b79154 | 220 | { |
Azure.IoT Build | 0:fa2de1b79154 | 221 | /*Codes_SRS_HTTPAPIEX_02_010: [If any of the operations in SRS_HTTAPIEX_02_009 fails, then HTTPAPIEX_ExecuteRequest shall return HTTPAPIEX_ERROR.] */ |
Azure.IoT Build | 0:fa2de1b79154 | 222 | result = __LINE__; |
Azure.IoT Build | 0:fa2de1b79154 | 223 | if (*isOriginalRequestContent == false) |
Azure.IoT Build | 0:fa2de1b79154 | 224 | { |
Azure.IoT Build | 0:fa2de1b79154 | 225 | BUFFER_delete(*toBeUsedRequestContent); |
Azure.IoT Build | 0:fa2de1b79154 | 226 | } |
AzureIoTClient | 1:9190c0f4d23a | 227 | LogError("unable to build the request http headers handle"); |
Azure.IoT Build | 0:fa2de1b79154 | 228 | } |
Azure.IoT Build | 0:fa2de1b79154 | 229 | else |
Azure.IoT Build | 0:fa2de1b79154 | 230 | { |
Azure.IoT Build | 0:fa2de1b79154 | 231 | /*Codes_SRS_HTTPAPIEX_02_008: [If parameter relativePath is NULL then HTTPAPIEX_INVALID_ARG shall not assume a relative path - that is, it will assume an empty path ("").] */ |
Azure.IoT Build | 0:fa2de1b79154 | 232 | if (relativePath == NULL) |
Azure.IoT Build | 0:fa2de1b79154 | 233 | { |
Azure.IoT Build | 0:fa2de1b79154 | 234 | *toBeUsedRelativePath = ""; |
Azure.IoT Build | 0:fa2de1b79154 | 235 | } |
Azure.IoT Build | 0:fa2de1b79154 | 236 | else |
Azure.IoT Build | 0:fa2de1b79154 | 237 | { |
Azure.IoT Build | 0:fa2de1b79154 | 238 | *toBeUsedRelativePath = relativePath; |
Azure.IoT Build | 0:fa2de1b79154 | 239 | } |
Azure.IoT Build | 0:fa2de1b79154 | 240 | |
Azure.IoT Build | 0:fa2de1b79154 | 241 | /*Codes_SRS_HTTPAPIEX_02_015: [If statusCode is NULL then HTTPAPIEX_ExecuteRequest shall not write in statusCode the HTTP status code, and it will use a temporary internal int for parameter statusCode to the calls of HTTPAPI_ExecuteRequest.] */ |
Azure.IoT Build | 0:fa2de1b79154 | 242 | if (statusCode == NULL) |
Azure.IoT Build | 0:fa2de1b79154 | 243 | { |
Azure.IoT Build | 0:fa2de1b79154 | 244 | /*Codes_SRS_HTTPAPIEX_02_016: [If statusCode is not NULL then If statusCode is NULL then HTTPAPIEX_ExecuteRequest shall use it for parameter statusCode to the calls of HTTPAPI_ExecuteRequest.] */ |
Azure.IoT Build | 0:fa2de1b79154 | 245 | *toBeUsedStatusCode = &dummyStatusCode; |
Azure.IoT Build | 0:fa2de1b79154 | 246 | } |
Azure.IoT Build | 0:fa2de1b79154 | 247 | else |
Azure.IoT Build | 0:fa2de1b79154 | 248 | { |
Azure.IoT Build | 0:fa2de1b79154 | 249 | *toBeUsedStatusCode = statusCode; |
Azure.IoT Build | 0:fa2de1b79154 | 250 | } |
Azure.IoT Build | 0:fa2de1b79154 | 251 | |
Azure.IoT Build | 0:fa2de1b79154 | 252 | /*Codes_SRS_HTTPAPIEX_02_017: [If responseHeaders handle is NULL then HTTPAPIEX_ExecuteRequest shall create a temporary internal instance of HTTPHEADERS object and use that for responseHeaders parameter of HTTPAPI_ExecuteRequest call.] */ |
Azure.IoT Build | 0:fa2de1b79154 | 253 | /*Codes_SRS_HTTPAPIEX_02_019: [If responseHeaders is not NULL, then then HTTPAPIEX_ExecuteRequest shall use that object as parameter responseHeaders of HTTPAPI_ExecuteRequest call.] */ |
Azure.IoT Build | 0:fa2de1b79154 | 254 | if (buildResponseHttpHeadersHandle(responseHttpHeadersHandle, isOriginalResponseHttpHeadersHandle, toBeUsedResponseHttpHeadersHandle) != 0) |
Azure.IoT Build | 0:fa2de1b79154 | 255 | { |
Azure.IoT Build | 0:fa2de1b79154 | 256 | /*Codes_SRS_HTTPAPIEX_02_018: [If creating the temporary http headers in SRS_HTTPAPIEX_02_017 fails then HTTPAPIEX_ExecuteRequest shall return HTTPAPIEX_ERROR.] */ |
Azure.IoT Build | 0:fa2de1b79154 | 257 | result = __LINE__; |
Azure.IoT Build | 0:fa2de1b79154 | 258 | if (*isOriginalRequestContent == false) |
Azure.IoT Build | 0:fa2de1b79154 | 259 | { |
Azure.IoT Build | 0:fa2de1b79154 | 260 | BUFFER_delete(*toBeUsedRequestContent); |
Azure.IoT Build | 0:fa2de1b79154 | 261 | } |
Azure.IoT Build | 0:fa2de1b79154 | 262 | if (*isOriginalRequestHttpHeadersHandle == false) |
Azure.IoT Build | 0:fa2de1b79154 | 263 | { |
Azure.IoT Build | 0:fa2de1b79154 | 264 | HTTPHeaders_Free(*toBeUsedRequestHttpHeadersHandle); |
Azure.IoT Build | 0:fa2de1b79154 | 265 | } |
AzureIoTClient | 1:9190c0f4d23a | 266 | LogError("unable to build response content"); |
Azure.IoT Build | 0:fa2de1b79154 | 267 | } |
Azure.IoT Build | 0:fa2de1b79154 | 268 | else |
Azure.IoT Build | 0:fa2de1b79154 | 269 | { |
Azure.IoT Build | 0:fa2de1b79154 | 270 | /*Codes_SRS_HTTPAPIEX_02_020: [If responseContent is NULL then HTTPAPIEX_ExecuteRequest shall create a temporary internal BUFFER object and use that as parameter responseContent of HTTPAPI_ExecuteRequest call.] */ |
Azure.IoT Build | 0:fa2de1b79154 | 271 | /*Codes_SRS_HTTPAPIEX_02_022: [If responseContent is not NULL then HTTPAPIEX_ExecuteRequest use that as parameter responseContent of HTTPAPI_ExecuteRequest call.] */ |
Azure.IoT Build | 0:fa2de1b79154 | 272 | if (buildBufferIfNotExist(responseContent, isOriginalResponseContent, toBeUsedResponseContent) != 0) |
Azure.IoT Build | 0:fa2de1b79154 | 273 | { |
Azure.IoT Build | 0:fa2de1b79154 | 274 | /*Codes_SRS_HTTPAPIEX_02_021: [If creating the BUFFER_HANDLE in SRS_HTTPAPIEX_02_020 fails, then HTTPAPIEX_ExecuteRequest shall return HTTPAPIEX_ERROR.] */ |
Azure.IoT Build | 0:fa2de1b79154 | 275 | result = __LINE__; |
Azure.IoT Build | 0:fa2de1b79154 | 276 | if (*isOriginalRequestContent == false) |
Azure.IoT Build | 0:fa2de1b79154 | 277 | { |
Azure.IoT Build | 0:fa2de1b79154 | 278 | BUFFER_delete(*toBeUsedRequestContent); |
Azure.IoT Build | 0:fa2de1b79154 | 279 | } |
Azure.IoT Build | 0:fa2de1b79154 | 280 | if (*isOriginalRequestHttpHeadersHandle == false) |
Azure.IoT Build | 0:fa2de1b79154 | 281 | { |
Azure.IoT Build | 0:fa2de1b79154 | 282 | HTTPHeaders_Free(*toBeUsedRequestHttpHeadersHandle); |
Azure.IoT Build | 0:fa2de1b79154 | 283 | } |
Azure.IoT Build | 0:fa2de1b79154 | 284 | if (*isOriginalResponseHttpHeadersHandle == false) |
Azure.IoT Build | 0:fa2de1b79154 | 285 | { |
Azure.IoT Build | 0:fa2de1b79154 | 286 | HTTPHeaders_Free(*toBeUsedResponseHttpHeadersHandle); |
Azure.IoT Build | 0:fa2de1b79154 | 287 | } |
AzureIoTClient | 1:9190c0f4d23a | 288 | LogError("unable to build response content"); |
Azure.IoT Build | 0:fa2de1b79154 | 289 | } |
Azure.IoT Build | 0:fa2de1b79154 | 290 | else |
Azure.IoT Build | 0:fa2de1b79154 | 291 | { |
Azure.IoT Build | 0:fa2de1b79154 | 292 | result = 0; |
Azure.IoT Build | 0:fa2de1b79154 | 293 | } |
Azure.IoT Build | 0:fa2de1b79154 | 294 | } |
Azure.IoT Build | 0:fa2de1b79154 | 295 | } |
Azure.IoT Build | 0:fa2de1b79154 | 296 | } |
Azure.IoT Build | 0:fa2de1b79154 | 297 | return result; |
Azure.IoT Build | 0:fa2de1b79154 | 298 | } |
Azure.IoT Build | 0:fa2de1b79154 | 299 | |
Azure.IoT Build | 0:fa2de1b79154 | 300 | HTTPAPIEX_RESULT HTTPAPIEX_ExecuteRequest(HTTPAPIEX_HANDLE handle, HTTPAPI_REQUEST_TYPE requestType, const char* relativePath, |
Azure.IoT Build | 0:fa2de1b79154 | 301 | HTTP_HEADERS_HANDLE requestHttpHeadersHandle, BUFFER_HANDLE requestContent, unsigned int* statusCode, |
Azure.IoT Build | 0:fa2de1b79154 | 302 | HTTP_HEADERS_HANDLE responseHttpHeadersHandle, BUFFER_HANDLE responseContent) |
Azure.IoT Build | 0:fa2de1b79154 | 303 | { |
Azure.IoT Build | 0:fa2de1b79154 | 304 | HTTPAPIEX_RESULT result; |
Azure.IoT Build | 0:fa2de1b79154 | 305 | /*Codes_SRS_HTTPAPIEX_02_006: [If parameter handle is NULL then HTTPAPIEX_ExecuteRequest shall fail and return HTTPAPIEX_INVALID_ARG.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 306 | if (handle == NULL) |
Azure.IoT Build | 0:fa2de1b79154 | 307 | { |
Azure.IoT Build | 0:fa2de1b79154 | 308 | result = HTTPAPIEX_INVALID_ARG; |
Azure.IoT Build | 0:fa2de1b79154 | 309 | LOG_HTTAPIEX_ERROR(); |
Azure.IoT Build | 0:fa2de1b79154 | 310 | } |
Azure.IoT Build | 0:fa2de1b79154 | 311 | else |
Azure.IoT Build | 0:fa2de1b79154 | 312 | { |
Azure.IoT Build | 0:fa2de1b79154 | 313 | /*Codes_SRS_HTTPAPIEX_02_007: [If parameter requestType does not indicate a valid request, HTTPAPIEX_ExecuteRequest shall fail and return HTTPAPIEX_INVALID_ARG.] */ |
Azure.IoT Build | 0:fa2de1b79154 | 314 | if (requestType >= COUNT_ARG(HTTPAPI_REQUEST_TYPE_VALUES)) |
Azure.IoT Build | 0:fa2de1b79154 | 315 | { |
Azure.IoT Build | 0:fa2de1b79154 | 316 | result = HTTPAPIEX_INVALID_ARG; |
Azure.IoT Build | 0:fa2de1b79154 | 317 | LOG_HTTAPIEX_ERROR(); |
Azure.IoT Build | 0:fa2de1b79154 | 318 | } |
Azure.IoT Build | 0:fa2de1b79154 | 319 | else |
Azure.IoT Build | 0:fa2de1b79154 | 320 | { |
Azure.IoT Build | 0:fa2de1b79154 | 321 | HTTPAPIEX_HANDLE_DATA *handleData = (HTTPAPIEX_HANDLE_DATA *)handle; |
Azure.IoT Build | 0:fa2de1b79154 | 322 | |
Azure.IoT Build | 0:fa2de1b79154 | 323 | /*call to buildAll*/ |
Azure.IoT Build | 0:fa2de1b79154 | 324 | const char* toBeUsedRelativePath; |
Azure.IoT Build | 0:fa2de1b79154 | 325 | HTTP_HEADERS_HANDLE toBeUsedRequestHttpHeadersHandle; bool isOriginalRequestHttpHeadersHandle; |
Azure.IoT Build | 0:fa2de1b79154 | 326 | BUFFER_HANDLE toBeUsedRequestContent; bool isOriginalRequestContent; |
Azure.IoT Build | 0:fa2de1b79154 | 327 | unsigned int* toBeUsedStatusCode; |
Azure.IoT Build | 0:fa2de1b79154 | 328 | HTTP_HEADERS_HANDLE toBeUsedResponseHttpHeadersHandle; bool isOriginalResponseHttpHeadersHandle; |
Azure.IoT Build | 0:fa2de1b79154 | 329 | BUFFER_HANDLE toBeUsedResponseContent; bool isOriginalResponseContent; |
Azure.IoT Build | 0:fa2de1b79154 | 330 | |
Azure.IoT Build | 0:fa2de1b79154 | 331 | if (buildAllRequests(handleData, requestType, relativePath, requestHttpHeadersHandle, requestContent, statusCode, responseHttpHeadersHandle, responseContent, |
Azure.IoT Build | 0:fa2de1b79154 | 332 | &toBeUsedRelativePath, |
Azure.IoT Build | 0:fa2de1b79154 | 333 | &toBeUsedRequestHttpHeadersHandle, &isOriginalRequestHttpHeadersHandle, |
Azure.IoT Build | 0:fa2de1b79154 | 334 | &toBeUsedRequestContent, &isOriginalRequestContent, |
Azure.IoT Build | 0:fa2de1b79154 | 335 | &toBeUsedStatusCode, |
Azure.IoT Build | 0:fa2de1b79154 | 336 | &toBeUsedResponseHttpHeadersHandle, &isOriginalResponseHttpHeadersHandle, |
Azure.IoT Build | 0:fa2de1b79154 | 337 | &toBeUsedResponseContent, &isOriginalResponseContent) != 0) |
Azure.IoT Build | 0:fa2de1b79154 | 338 | { |
Azure.IoT Build | 0:fa2de1b79154 | 339 | result = HTTPAPIEX_ERROR; |
Azure.IoT Build | 0:fa2de1b79154 | 340 | LOG_HTTAPIEX_ERROR(); |
Azure.IoT Build | 0:fa2de1b79154 | 341 | } |
Azure.IoT Build | 0:fa2de1b79154 | 342 | else |
Azure.IoT Build | 0:fa2de1b79154 | 343 | { |
Azure.IoT Build | 0:fa2de1b79154 | 344 | |
Azure.IoT Build | 0:fa2de1b79154 | 345 | /*Codes_SRS_HTTPAPIEX_02_023: [HTTPAPIEX_ExecuteRequest shall try to execute the HTTP call by ensuring the following API call sequence is respected:]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 346 | /*Codes_SRS_HTTPAPIEX_02_024: [If any point in the sequence fails, HTTPAPIEX_ExecuteRequest shall attempt to recover by going back to the previous step and retrying that step.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 347 | /*Codes_SRS_HTTPAPIEX_02_025: [If the first step fails, then the sequence fails.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 348 | /*Codes_SRS_HTTPAPIEX_02_026: [A step shall be retried at most once.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 349 | /*Codes_SRS_HTTPAPIEX_02_027: [If a step has been retried then all subsequent steps shall be retried too.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 350 | bool st[3] = { false, false, false }; /*the three levels of possible failure in resilient send: HTTAPI_Init, HTTPAPI_CreateConnection, HTTPAPI_ExecuteRequest*/ |
Azure.IoT Build | 0:fa2de1b79154 | 351 | if (handleData->k == -1) |
Azure.IoT Build | 0:fa2de1b79154 | 352 | { |
Azure.IoT Build | 0:fa2de1b79154 | 353 | handleData->k = 0; |
Azure.IoT Build | 0:fa2de1b79154 | 354 | } |
Azure.IoT Build | 0:fa2de1b79154 | 355 | |
Azure.IoT Build | 0:fa2de1b79154 | 356 | do |
Azure.IoT Build | 0:fa2de1b79154 | 357 | { |
Azure.IoT Build | 0:fa2de1b79154 | 358 | bool goOn; |
Azure.IoT Build | 0:fa2de1b79154 | 359 | |
Azure.IoT Build | 0:fa2de1b79154 | 360 | if (handleData->k > 2) |
Azure.IoT Build | 0:fa2de1b79154 | 361 | { |
Azure.IoT Build | 0:fa2de1b79154 | 362 | /* error */ |
Azure.IoT Build | 0:fa2de1b79154 | 363 | break; |
Azure.IoT Build | 0:fa2de1b79154 | 364 | } |
Azure.IoT Build | 0:fa2de1b79154 | 365 | |
Azure.IoT Build | 0:fa2de1b79154 | 366 | if (st[handleData->k] == true) /*already been tried*/ |
Azure.IoT Build | 0:fa2de1b79154 | 367 | { |
Azure.IoT Build | 0:fa2de1b79154 | 368 | goOn = false; |
Azure.IoT Build | 0:fa2de1b79154 | 369 | } |
Azure.IoT Build | 0:fa2de1b79154 | 370 | else |
Azure.IoT Build | 0:fa2de1b79154 | 371 | { |
Azure.IoT Build | 0:fa2de1b79154 | 372 | switch (handleData->k) |
Azure.IoT Build | 0:fa2de1b79154 | 373 | { |
Azure.IoT Build | 0:fa2de1b79154 | 374 | case 0: |
Azure.IoT Build | 0:fa2de1b79154 | 375 | { |
Azure.IoT Build | 0:fa2de1b79154 | 376 | if (HTTPAPI_Init() != HTTPAPI_OK) |
Azure.IoT Build | 0:fa2de1b79154 | 377 | { |
Azure.IoT Build | 0:fa2de1b79154 | 378 | goOn = false; |
Azure.IoT Build | 0:fa2de1b79154 | 379 | } |
Azure.IoT Build | 0:fa2de1b79154 | 380 | else |
Azure.IoT Build | 0:fa2de1b79154 | 381 | { |
Azure.IoT Build | 0:fa2de1b79154 | 382 | goOn = true; |
Azure.IoT Build | 0:fa2de1b79154 | 383 | } |
Azure.IoT Build | 0:fa2de1b79154 | 384 | break; |
Azure.IoT Build | 0:fa2de1b79154 | 385 | } |
Azure.IoT Build | 0:fa2de1b79154 | 386 | case 1: |
Azure.IoT Build | 0:fa2de1b79154 | 387 | { |
Azure.IoT Build | 0:fa2de1b79154 | 388 | if ((handleData->httpHandle = HTTPAPI_CreateConnection(STRING_c_str(handleData->hostName))) == NULL) |
Azure.IoT Build | 0:fa2de1b79154 | 389 | { |
Azure.IoT Build | 0:fa2de1b79154 | 390 | goOn = false; |
Azure.IoT Build | 0:fa2de1b79154 | 391 | } |
Azure.IoT Build | 0:fa2de1b79154 | 392 | else |
Azure.IoT Build | 0:fa2de1b79154 | 393 | { |
Azure.IoT Build | 0:fa2de1b79154 | 394 | size_t i; |
Azure.IoT Build | 0:fa2de1b79154 | 395 | size_t vectorSize = VECTOR_size(handleData->savedOptions); |
Azure.IoT Build | 0:fa2de1b79154 | 396 | for (i = 0; i < vectorSize; i++) |
Azure.IoT Build | 0:fa2de1b79154 | 397 | { |
Azure.IoT Build | 0:fa2de1b79154 | 398 | /*Codes_SRS_HTTPAPIEX_02_035: [HTTPAPIEX_ExecuteRequest shall pass all the saved options (see HTTPAPIEX_SetOption) to the newly create HTTPAPI_HANDLE in step 2 by calling HTTPAPI_SetOption.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 399 | /*Codes_SRS_HTTPAPIEX_02_036: [If setting the option fails, then the failure shall be ignored.] */ |
Azure.IoT Build | 0:fa2de1b79154 | 400 | HTTPAPIEX_SAVED_OPTION* option = VECTOR_element(handleData->savedOptions, i); |
Azure.IoT Build | 0:fa2de1b79154 | 401 | if (HTTPAPI_SetOption(handleData->httpHandle, option->optionName, option->value) != HTTPAPI_OK) |
Azure.IoT Build | 0:fa2de1b79154 | 402 | { |
AzureIoTClient | 1:9190c0f4d23a | 403 | LogError("HTTPAPI_SetOption failed when called for option %s", option->optionName); |
Azure.IoT Build | 0:fa2de1b79154 | 404 | } |
Azure.IoT Build | 0:fa2de1b79154 | 405 | } |
Azure.IoT Build | 0:fa2de1b79154 | 406 | goOn = true; |
Azure.IoT Build | 0:fa2de1b79154 | 407 | } |
Azure.IoT Build | 0:fa2de1b79154 | 408 | break; |
Azure.IoT Build | 0:fa2de1b79154 | 409 | } |
Azure.IoT Build | 0:fa2de1b79154 | 410 | case 2: |
Azure.IoT Build | 0:fa2de1b79154 | 411 | { |
Azure.IoT Build | 0:fa2de1b79154 | 412 | if (HTTPAPI_ExecuteRequest(handleData->httpHandle, requestType, toBeUsedRelativePath, toBeUsedRequestHttpHeadersHandle, BUFFER_u_char(toBeUsedRequestContent), BUFFER_length(toBeUsedRequestContent), toBeUsedStatusCode, toBeUsedResponseHttpHeadersHandle, toBeUsedResponseContent) != HTTPAPI_OK) |
Azure.IoT Build | 0:fa2de1b79154 | 413 | { |
Azure.IoT Build | 0:fa2de1b79154 | 414 | goOn = false; |
Azure.IoT Build | 0:fa2de1b79154 | 415 | } |
Azure.IoT Build | 0:fa2de1b79154 | 416 | else |
Azure.IoT Build | 0:fa2de1b79154 | 417 | { |
Azure.IoT Build | 0:fa2de1b79154 | 418 | goOn = true; |
Azure.IoT Build | 0:fa2de1b79154 | 419 | } |
Azure.IoT Build | 0:fa2de1b79154 | 420 | break; |
Azure.IoT Build | 0:fa2de1b79154 | 421 | } |
Azure.IoT Build | 0:fa2de1b79154 | 422 | default: |
Azure.IoT Build | 0:fa2de1b79154 | 423 | { |
Azure.IoT Build | 0:fa2de1b79154 | 424 | /*serious error*/ |
Azure.IoT Build | 0:fa2de1b79154 | 425 | goOn = false; |
Azure.IoT Build | 0:fa2de1b79154 | 426 | break; |
Azure.IoT Build | 0:fa2de1b79154 | 427 | } |
Azure.IoT Build | 0:fa2de1b79154 | 428 | } |
Azure.IoT Build | 0:fa2de1b79154 | 429 | } |
Azure.IoT Build | 0:fa2de1b79154 | 430 | |
Azure.IoT Build | 0:fa2de1b79154 | 431 | if (goOn) |
Azure.IoT Build | 0:fa2de1b79154 | 432 | { |
Azure.IoT Build | 0:fa2de1b79154 | 433 | if (handleData->k == 2) |
Azure.IoT Build | 0:fa2de1b79154 | 434 | { |
Azure.IoT Build | 0:fa2de1b79154 | 435 | /*Codes_SRS_HTTPAPIEX_02_028: [HTTPAPIEX_ExecuteRequest shall return HTTPAPIEX_OK when a call to HTTPAPI_ExecuteRequest has been completed successfully.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 436 | result = HTTPAPIEX_OK; |
Azure.IoT Build | 0:fa2de1b79154 | 437 | goto out; |
Azure.IoT Build | 0:fa2de1b79154 | 438 | } |
Azure.IoT Build | 0:fa2de1b79154 | 439 | else |
Azure.IoT Build | 0:fa2de1b79154 | 440 | { |
Azure.IoT Build | 0:fa2de1b79154 | 441 | st[handleData->k] = true; |
Azure.IoT Build | 0:fa2de1b79154 | 442 | handleData->k++; |
Azure.IoT Build | 0:fa2de1b79154 | 443 | st[handleData->k] = false; |
Azure.IoT Build | 0:fa2de1b79154 | 444 | } |
Azure.IoT Build | 0:fa2de1b79154 | 445 | } |
Azure.IoT Build | 0:fa2de1b79154 | 446 | else |
Azure.IoT Build | 0:fa2de1b79154 | 447 | { |
Azure.IoT Build | 0:fa2de1b79154 | 448 | st[handleData->k] = false; |
Azure.IoT Build | 0:fa2de1b79154 | 449 | handleData->k--; |
Azure.IoT Build | 0:fa2de1b79154 | 450 | switch (handleData->k) |
Azure.IoT Build | 0:fa2de1b79154 | 451 | { |
Azure.IoT Build | 0:fa2de1b79154 | 452 | case 0: |
Azure.IoT Build | 0:fa2de1b79154 | 453 | { |
Azure.IoT Build | 0:fa2de1b79154 | 454 | HTTPAPI_Deinit(); |
Azure.IoT Build | 0:fa2de1b79154 | 455 | break; |
Azure.IoT Build | 0:fa2de1b79154 | 456 | } |
Azure.IoT Build | 0:fa2de1b79154 | 457 | case 1: |
Azure.IoT Build | 0:fa2de1b79154 | 458 | { |
Azure.IoT Build | 0:fa2de1b79154 | 459 | HTTPAPI_CloseConnection(handleData->httpHandle); |
Azure.IoT Build | 0:fa2de1b79154 | 460 | handleData->httpHandle = NULL; |
Azure.IoT Build | 0:fa2de1b79154 | 461 | break; |
Azure.IoT Build | 0:fa2de1b79154 | 462 | } |
Azure.IoT Build | 0:fa2de1b79154 | 463 | case 2: |
Azure.IoT Build | 0:fa2de1b79154 | 464 | { |
Azure.IoT Build | 0:fa2de1b79154 | 465 | break; |
Azure.IoT Build | 0:fa2de1b79154 | 466 | } |
Azure.IoT Build | 0:fa2de1b79154 | 467 | default: |
Azure.IoT Build | 0:fa2de1b79154 | 468 | { |
Azure.IoT Build | 0:fa2de1b79154 | 469 | break; |
Azure.IoT Build | 0:fa2de1b79154 | 470 | } |
Azure.IoT Build | 0:fa2de1b79154 | 471 | } |
Azure.IoT Build | 0:fa2de1b79154 | 472 | } |
Azure.IoT Build | 0:fa2de1b79154 | 473 | } while (handleData->k >= 0); |
Azure.IoT Build | 0:fa2de1b79154 | 474 | /*Codes_SRS_HTTPAPIEX_02_029: [Otherwise, HTTAPIEX_ExecuteRequest shall return HTTPAPIEX_RECOVERYFAILED.] */ |
Azure.IoT Build | 0:fa2de1b79154 | 475 | result = HTTPAPIEX_RECOVERYFAILED; |
AzureIoTClient | 1:9190c0f4d23a | 476 | LogError("unable to recover sending to a working state"); |
Azure.IoT Build | 0:fa2de1b79154 | 477 | out:; |
Azure.IoT Build | 0:fa2de1b79154 | 478 | /*in all cases, unbuild the temporaries*/ |
Azure.IoT Build | 0:fa2de1b79154 | 479 | if (isOriginalRequestContent == false) |
Azure.IoT Build | 0:fa2de1b79154 | 480 | { |
Azure.IoT Build | 0:fa2de1b79154 | 481 | BUFFER_delete(toBeUsedRequestContent); |
Azure.IoT Build | 0:fa2de1b79154 | 482 | } |
Azure.IoT Build | 0:fa2de1b79154 | 483 | if (isOriginalRequestHttpHeadersHandle == false) |
Azure.IoT Build | 0:fa2de1b79154 | 484 | { |
Azure.IoT Build | 0:fa2de1b79154 | 485 | HTTPHeaders_Free(toBeUsedRequestHttpHeadersHandle); |
Azure.IoT Build | 0:fa2de1b79154 | 486 | } |
Azure.IoT Build | 0:fa2de1b79154 | 487 | if (isOriginalResponseContent == false) |
Azure.IoT Build | 0:fa2de1b79154 | 488 | { |
Azure.IoT Build | 0:fa2de1b79154 | 489 | BUFFER_delete(toBeUsedResponseContent); |
Azure.IoT Build | 0:fa2de1b79154 | 490 | } |
Azure.IoT Build | 0:fa2de1b79154 | 491 | if (isOriginalResponseHttpHeadersHandle == false) |
Azure.IoT Build | 0:fa2de1b79154 | 492 | { |
Azure.IoT Build | 0:fa2de1b79154 | 493 | HTTPHeaders_Free(toBeUsedResponseHttpHeadersHandle); |
Azure.IoT Build | 0:fa2de1b79154 | 494 | } |
Azure.IoT Build | 0:fa2de1b79154 | 495 | } |
Azure.IoT Build | 0:fa2de1b79154 | 496 | } |
Azure.IoT Build | 0:fa2de1b79154 | 497 | } |
Azure.IoT Build | 0:fa2de1b79154 | 498 | return result; |
Azure.IoT Build | 0:fa2de1b79154 | 499 | } |
Azure.IoT Build | 0:fa2de1b79154 | 500 | |
Azure.IoT Build | 0:fa2de1b79154 | 501 | |
Azure.IoT Build | 0:fa2de1b79154 | 502 | void HTTPAPIEX_Destroy(HTTPAPIEX_HANDLE handle) |
Azure.IoT Build | 0:fa2de1b79154 | 503 | { |
Azure.IoT Build | 0:fa2de1b79154 | 504 | if (handle != NULL) |
Azure.IoT Build | 0:fa2de1b79154 | 505 | { |
Azure.IoT Build | 0:fa2de1b79154 | 506 | /*Codes_SRS_HTTPAPIEX_02_042: [HTTPAPIEX_Destroy shall free all the resources used by HTTAPIEX_HANDLE.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 507 | size_t i; |
Azure.IoT Build | 0:fa2de1b79154 | 508 | size_t vectorSize; |
Azure.IoT Build | 0:fa2de1b79154 | 509 | HTTPAPIEX_HANDLE_DATA* handleData = (HTTPAPIEX_HANDLE_DATA*)handle; |
Azure.IoT Build | 0:fa2de1b79154 | 510 | |
Azure.IoT Build | 0:fa2de1b79154 | 511 | if (handleData->k == 2) |
Azure.IoT Build | 0:fa2de1b79154 | 512 | { |
Azure.IoT Build | 0:fa2de1b79154 | 513 | HTTPAPI_CloseConnection(handleData->httpHandle); |
Azure.IoT Build | 0:fa2de1b79154 | 514 | HTTPAPI_Deinit(); |
Azure.IoT Build | 0:fa2de1b79154 | 515 | } |
Azure.IoT Build | 0:fa2de1b79154 | 516 | STRING_delete(handleData->hostName); |
Azure.IoT Build | 0:fa2de1b79154 | 517 | |
Azure.IoT Build | 0:fa2de1b79154 | 518 | vectorSize = VECTOR_size(handleData->savedOptions); |
Azure.IoT Build | 0:fa2de1b79154 | 519 | for (i = 0; i < vectorSize; i++) |
Azure.IoT Build | 0:fa2de1b79154 | 520 | { |
Azure.IoT Build | 0:fa2de1b79154 | 521 | HTTPAPIEX_SAVED_OPTION*savedOption = VECTOR_element(handleData->savedOptions, i); |
Azure.IoT Build | 0:fa2de1b79154 | 522 | free((void*)savedOption->optionName); |
Azure.IoT Build | 0:fa2de1b79154 | 523 | free((void*)savedOption->value); |
Azure.IoT Build | 0:fa2de1b79154 | 524 | } |
Azure.IoT Build | 0:fa2de1b79154 | 525 | VECTOR_destroy(handleData->savedOptions); |
Azure.IoT Build | 0:fa2de1b79154 | 526 | |
Azure.IoT Build | 0:fa2de1b79154 | 527 | free(handle); |
Azure.IoT Build | 0:fa2de1b79154 | 528 | } |
Azure.IoT Build | 0:fa2de1b79154 | 529 | else |
Azure.IoT Build | 0:fa2de1b79154 | 530 | { |
Azure.IoT Build | 0:fa2de1b79154 | 531 | /*Codes_SRS_HTTPAPIEX_02_043: [If parameter handle is NULL then HTTPAPIEX_Destroy shall take no action.] */ |
Azure.IoT Build | 0:fa2de1b79154 | 532 | } |
Azure.IoT Build | 0:fa2de1b79154 | 533 | } |
Azure.IoT Build | 0:fa2de1b79154 | 534 | |
Azure.IoT Build | 0:fa2de1b79154 | 535 | static bool sameName(const void* element, const void* value) |
Azure.IoT Build | 0:fa2de1b79154 | 536 | { |
Azure.IoT Build | 0:fa2de1b79154 | 537 | return (strcmp(((HTTPAPIEX_SAVED_OPTION*)element)->optionName, value) == 0) ? true : false; |
Azure.IoT Build | 0:fa2de1b79154 | 538 | } |
Azure.IoT Build | 0:fa2de1b79154 | 539 | |
Azure.IoT Build | 0:fa2de1b79154 | 540 | /*return 0 on success, any other value is error*/ |
Azure.IoT Build | 0:fa2de1b79154 | 541 | /*obs: value is already cloned at the time of calling this function */ |
Azure.IoT Build | 0:fa2de1b79154 | 542 | static int createOrUpdateOption(HTTPAPIEX_HANDLE_DATA* handleData, const char* optionName, const void* value) |
Azure.IoT Build | 0:fa2de1b79154 | 543 | { |
Azure.IoT Build | 0:fa2de1b79154 | 544 | /*this function is called after the option value has been saved (cloned)*/ |
Azure.IoT Build | 0:fa2de1b79154 | 545 | int result; |
Azure.IoT Build | 0:fa2de1b79154 | 546 | |
Azure.IoT Build | 0:fa2de1b79154 | 547 | /*decide bwtween update or create*/ |
Azure.IoT Build | 0:fa2de1b79154 | 548 | HTTPAPIEX_SAVED_OPTION* whereIsIt = VECTOR_find_if(handleData->savedOptions, sameName, optionName); |
Azure.IoT Build | 0:fa2de1b79154 | 549 | if (whereIsIt != NULL) |
Azure.IoT Build | 0:fa2de1b79154 | 550 | { |
Azure.IoT Build | 0:fa2de1b79154 | 551 | free((void*)(whereIsIt->value)); |
Azure.IoT Build | 0:fa2de1b79154 | 552 | whereIsIt->value = value; |
Azure.IoT Build | 0:fa2de1b79154 | 553 | result = 0; |
Azure.IoT Build | 0:fa2de1b79154 | 554 | } |
Azure.IoT Build | 0:fa2de1b79154 | 555 | else |
Azure.IoT Build | 0:fa2de1b79154 | 556 | { |
Azure.IoT Build | 0:fa2de1b79154 | 557 | HTTPAPIEX_SAVED_OPTION newOption; |
Azure.IoT Build | 0:fa2de1b79154 | 558 | if (mallocAndStrcpy_s((char**)&(newOption.optionName), optionName) != 0) |
Azure.IoT Build | 0:fa2de1b79154 | 559 | { |
Azure.IoT Build | 0:fa2de1b79154 | 560 | free((void*)value); |
Azure.IoT Build | 0:fa2de1b79154 | 561 | result = __LINE__; |
Azure.IoT Build | 0:fa2de1b79154 | 562 | } |
Azure.IoT Build | 0:fa2de1b79154 | 563 | else |
Azure.IoT Build | 0:fa2de1b79154 | 564 | { |
Azure.IoT Build | 0:fa2de1b79154 | 565 | newOption.value = value; |
Azure.IoT Build | 0:fa2de1b79154 | 566 | if (VECTOR_push_back(handleData->savedOptions, &newOption, 1) != 0) |
Azure.IoT Build | 0:fa2de1b79154 | 567 | { |
AzureIoTClient | 1:9190c0f4d23a | 568 | LogError("unable to VECTOR_push_back"); |
Azure.IoT Build | 0:fa2de1b79154 | 569 | free((void*)newOption.optionName); |
Azure.IoT Build | 0:fa2de1b79154 | 570 | free((void*)value); |
Azure.IoT Build | 0:fa2de1b79154 | 571 | result = __LINE__; |
Azure.IoT Build | 0:fa2de1b79154 | 572 | } |
Azure.IoT Build | 0:fa2de1b79154 | 573 | else |
Azure.IoT Build | 0:fa2de1b79154 | 574 | { |
Azure.IoT Build | 0:fa2de1b79154 | 575 | result = 0; |
Azure.IoT Build | 0:fa2de1b79154 | 576 | } |
Azure.IoT Build | 0:fa2de1b79154 | 577 | } |
Azure.IoT Build | 0:fa2de1b79154 | 578 | } |
Azure.IoT Build | 0:fa2de1b79154 | 579 | |
Azure.IoT Build | 0:fa2de1b79154 | 580 | return result; |
Azure.IoT Build | 0:fa2de1b79154 | 581 | } |
Azure.IoT Build | 0:fa2de1b79154 | 582 | |
Azure.IoT Build | 0:fa2de1b79154 | 583 | HTTPAPIEX_RESULT HTTPAPIEX_SetOption(HTTPAPIEX_HANDLE handle, const char* optionName, const void* value) |
Azure.IoT Build | 0:fa2de1b79154 | 584 | { |
Azure.IoT Build | 0:fa2de1b79154 | 585 | HTTPAPIEX_RESULT result; |
Azure.IoT Build | 0:fa2de1b79154 | 586 | /*Codes_SRS_HTTPAPIEX_02_032: [If parameter handle is NULL then HTTPAPIEX_SetOption shall return HTTPAPIEX_INVALID_ARG.] */ |
Azure.IoT Build | 0:fa2de1b79154 | 587 | /*Codes_SRS_HTTPAPIEX_02_033: [If parameter optionName is NULL then HTTPAPIEX_SetOption shall return HTTPAPIEX_INVALID_ARG.] */ |
Azure.IoT Build | 0:fa2de1b79154 | 588 | /*Codes_SRS_HTTPAPIEX_02_034: [If parameter value is NULL then HTTPAPIEX_SetOption shall return HTTPAPIEX_INVALID_ARG.] */ |
Azure.IoT Build | 0:fa2de1b79154 | 589 | if ( |
Azure.IoT Build | 0:fa2de1b79154 | 590 | (handle == NULL) || |
Azure.IoT Build | 0:fa2de1b79154 | 591 | (optionName == NULL) || |
Azure.IoT Build | 0:fa2de1b79154 | 592 | (value == NULL) |
Azure.IoT Build | 0:fa2de1b79154 | 593 | ) |
Azure.IoT Build | 0:fa2de1b79154 | 594 | { |
Azure.IoT Build | 0:fa2de1b79154 | 595 | result = HTTPAPIEX_INVALID_ARG; |
Azure.IoT Build | 0:fa2de1b79154 | 596 | LOG_HTTAPIEX_ERROR(); |
Azure.IoT Build | 0:fa2de1b79154 | 597 | } |
Azure.IoT Build | 0:fa2de1b79154 | 598 | else |
Azure.IoT Build | 0:fa2de1b79154 | 599 | { |
Azure.IoT Build | 0:fa2de1b79154 | 600 | const void* savedOption; |
Azure.IoT Build | 0:fa2de1b79154 | 601 | HTTPAPI_RESULT saveOptionResult; |
Azure.IoT Build | 0:fa2de1b79154 | 602 | |
Azure.IoT Build | 0:fa2de1b79154 | 603 | /*Codes_SRS_HTTPAPIEX_02_037: [HTTPAPIEX_SetOption shall attempt to save the value of the option by calling HTTPAPI_CloneOption passing optionName and value, irrespective of the existence of a HTTPAPI_HANDLE] */ |
Azure.IoT Build | 0:fa2de1b79154 | 604 | saveOptionResult = HTTPAPI_CloneOption(optionName, value, &savedOption); |
Azure.IoT Build | 0:fa2de1b79154 | 605 | |
Azure.IoT Build | 0:fa2de1b79154 | 606 | if(saveOptionResult == HTTPAPI_INVALID_ARG) |
Azure.IoT Build | 0:fa2de1b79154 | 607 | { |
Azure.IoT Build | 0:fa2de1b79154 | 608 | /*Codes_SRS_HTTPAPIEX_02_038: [If HTTPAPI_CloneOption returns HTTPAPI_INVALID_ARG then HTTPAPIEX shall return HTTPAPIEX_INVALID_ARG.] */ |
Azure.IoT Build | 0:fa2de1b79154 | 609 | result = HTTPAPIEX_INVALID_ARG; |
Azure.IoT Build | 0:fa2de1b79154 | 610 | LOG_HTTAPIEX_ERROR(); |
Azure.IoT Build | 0:fa2de1b79154 | 611 | } |
Azure.IoT Build | 0:fa2de1b79154 | 612 | else if (saveOptionResult != HTTPAPI_OK) |
Azure.IoT Build | 0:fa2de1b79154 | 613 | { |
Azure.IoT Build | 0:fa2de1b79154 | 614 | /*Codes_SRS_HTTPAPIEX_02_040: [For all other return values of HTTPAPI_SetOption, HTTPIAPIEX_SetOption shall return HTTPAPIEX_ERROR.] */ |
Azure.IoT Build | 0:fa2de1b79154 | 615 | result = HTTPAPIEX_ERROR; |
Azure.IoT Build | 0:fa2de1b79154 | 616 | LOG_HTTAPIEX_ERROR(); |
Azure.IoT Build | 0:fa2de1b79154 | 617 | } |
Azure.IoT Build | 0:fa2de1b79154 | 618 | else |
Azure.IoT Build | 0:fa2de1b79154 | 619 | { |
Azure.IoT Build | 0:fa2de1b79154 | 620 | HTTPAPIEX_HANDLE_DATA* handleData = (HTTPAPIEX_HANDLE_DATA*)handle; |
Azure.IoT Build | 0:fa2de1b79154 | 621 | /*Codes_SRS_HTTPAPIEX_02_039: [If HTTPAPI_CloneOption returns HTTPAPI_OK then HTTPAPIEX_SetOption shall create or update the pair optionName/value.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 622 | if (createOrUpdateOption(handleData, optionName, savedOption) != 0) |
Azure.IoT Build | 0:fa2de1b79154 | 623 | { |
Azure.IoT Build | 0:fa2de1b79154 | 624 | /*Codes_SRS_HTTPAPIEX_02_041: [If creating or updating the pair optionName/value fails then shall return HTTPAPIEX_ERROR.] */ |
Azure.IoT Build | 0:fa2de1b79154 | 625 | result = HTTPAPIEX_ERROR; |
Azure.IoT Build | 0:fa2de1b79154 | 626 | LOG_HTTAPIEX_ERROR(); |
Azure.IoT Build | 0:fa2de1b79154 | 627 | |
Azure.IoT Build | 0:fa2de1b79154 | 628 | } |
Azure.IoT Build | 0:fa2de1b79154 | 629 | else |
Azure.IoT Build | 0:fa2de1b79154 | 630 | { |
Azure.IoT Build | 0:fa2de1b79154 | 631 | /*Codes_SRS_HTTPAPIEX_02_031: [If HTTPAPI_HANDLE exists then HTTPAPIEX_SetOption shall call HTTPAPI_SetOption passing the same optionName and value and shall return a value conforming to the below table:] */ |
Azure.IoT Build | 0:fa2de1b79154 | 632 | if (handleData->httpHandle != NULL) |
Azure.IoT Build | 0:fa2de1b79154 | 633 | { |
Azure.IoT Build | 0:fa2de1b79154 | 634 | HTTPAPI_RESULT HTTPAPI_result = HTTPAPI_SetOption(handleData->httpHandle, optionName, value); |
Azure.IoT Build | 0:fa2de1b79154 | 635 | if (HTTPAPI_result == HTTPAPI_OK) |
Azure.IoT Build | 0:fa2de1b79154 | 636 | { |
Azure.IoT Build | 0:fa2de1b79154 | 637 | result = HTTPAPIEX_OK; |
Azure.IoT Build | 0:fa2de1b79154 | 638 | } |
Azure.IoT Build | 0:fa2de1b79154 | 639 | else if (HTTPAPI_result == HTTPAPI_INVALID_ARG) |
Azure.IoT Build | 0:fa2de1b79154 | 640 | { |
Azure.IoT Build | 0:fa2de1b79154 | 641 | result = HTTPAPIEX_INVALID_ARG; |
Azure.IoT Build | 0:fa2de1b79154 | 642 | LOG_HTTAPIEX_ERROR(); |
Azure.IoT Build | 0:fa2de1b79154 | 643 | } |
Azure.IoT Build | 0:fa2de1b79154 | 644 | else |
Azure.IoT Build | 0:fa2de1b79154 | 645 | { |
Azure.IoT Build | 0:fa2de1b79154 | 646 | result = HTTPAPIEX_ERROR; |
Azure.IoT Build | 0:fa2de1b79154 | 647 | LOG_HTTAPIEX_ERROR(); |
Azure.IoT Build | 0:fa2de1b79154 | 648 | } |
Azure.IoT Build | 0:fa2de1b79154 | 649 | } |
Azure.IoT Build | 0:fa2de1b79154 | 650 | else |
Azure.IoT Build | 0:fa2de1b79154 | 651 | { |
Azure.IoT Build | 0:fa2de1b79154 | 652 | result = HTTPAPIEX_OK; |
Azure.IoT Build | 0:fa2de1b79154 | 653 | } |
Azure.IoT Build | 0:fa2de1b79154 | 654 | } |
Azure.IoT Build | 0:fa2de1b79154 | 655 | } |
Azure.IoT Build | 0:fa2de1b79154 | 656 | } |
Azure.IoT Build | 0:fa2de1b79154 | 657 | return result; |
Azure.IoT Build | 0:fa2de1b79154 | 658 | } |