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