Azure IoT common library
Fork of azure_c_shared_utility by
httpapiex.c@0:fa2de1b79154, 2016-04-08 (annotated)
- Committer:
- Azure.IoT Build
- Date:
- Fri Apr 08 12:01:36 2016 -0700
- Revision:
- 0:fa2de1b79154
- Child:
- 1:9190c0f4d23a
1.0.4
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 | |
Azure.IoT Build | 0:fa2de1b79154 | 32 | #define LOG_HTTAPIEX_ERROR() LogError("error code = %s\r\n", 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 | { |
Azure.IoT Build | 0:fa2de1b79154 | 40 | LogError("invalid (NULL) parameter\r\n"); |
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 | { |
Azure.IoT Build | 0:fa2de1b79154 | 49 | LogError("malloc failed.\r\n"); |
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); |
Azure.IoT Build | 0:fa2de1b79154 | 59 | LogError("unable to STRING_construct\r\n"); |
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__; |
Azure.IoT Build | 0:fa2de1b79154 | 111 | LogError("unable to HTTPHeaders_Alloc\r\n"); |
Azure.IoT Build | 0:fa2de1b79154 | 112 | } |
Azure.IoT Build | 0:fa2de1b79154 | 113 | else |
Azure.IoT Build | 0:fa2de1b79154 | 114 | { |
Azure.IoT Build | 0:fa2de1b79154 | 115 | char temp[22]; |
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__; |
Azure.IoT Build | 0:fa2de1b79154 | 215 | LogError("unable to build the request content\r\n"); |
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 | } |
Azure.IoT Build | 0:fa2de1b79154 | 227 | LogError("unable to build the request http headers handle\r\n"); |
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 | } |
Azure.IoT Build | 0:fa2de1b79154 | 266 | LogError("unable to build response content\r\n"); |
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 | } |
Azure.IoT Build | 0:fa2de1b79154 | 288 | LogError("unable to build response content\r\n"); |
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 | { |
Azure.IoT Build | 0:fa2de1b79154 | 403 | LogError("HTTPAPI_SetOption failed when called for option %s\r\n", 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; |
Azure.IoT Build | 0:fa2de1b79154 | 476 | LogError("unable to recover sending to a working state\r\n"); |
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 | { |
Azure.IoT Build | 0:fa2de1b79154 | 568 | LogError("unable to VECTOR_push_back\r\n"); |
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 | } |