Azure IoT common library
Dependents: STM32F746_iothub_client_sample_mqtt f767zi_mqtt iothub_client_sample_amqp iothub_client_sample_http ... more
httpheaders.c@6:c55b013dfc2a, 2016-07-01 (annotated)
- Committer:
- Azure.IoT Build
- Date:
- Fri Jul 01 10:43:23 2016 -0700
- Revision:
- 6:c55b013dfc2a
- Parent:
- 1:9190c0f4d23a
- Child:
- 11:77df6d7e65ae
1.0.10
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/map.h" |
Azure.IoT Build | 0:fa2de1b79154 | 11 | #include "azure_c_shared_utility/httpheaders.h" |
Azure.IoT Build | 0:fa2de1b79154 | 12 | #include <string.h> |
Azure.IoT Build | 0:fa2de1b79154 | 13 | #include "azure_c_shared_utility/crt_abstractions.h" |
Azure.IoT Build | 6:c55b013dfc2a | 14 | #include "azure_c_shared_utility/xlogging.h" |
Azure.IoT Build | 0:fa2de1b79154 | 15 | |
Azure.IoT Build | 0:fa2de1b79154 | 16 | static const char COLON_AND_SPACE[] = { ':', ' ', '\0' }; |
Azure.IoT Build | 0:fa2de1b79154 | 17 | #define COLON_AND_SPACE_LENGTH ((sizeof(COLON_AND_SPACE)/sizeof(COLON_AND_SPACE[0]))-1) |
Azure.IoT Build | 0:fa2de1b79154 | 18 | |
Azure.IoT Build | 0:fa2de1b79154 | 19 | static const char COMMA_AND_SPACE[] = { ',', ' ', '\0' }; |
Azure.IoT Build | 0:fa2de1b79154 | 20 | #define COMMA_AND_SPACE_LENGTH ((sizeof(COMMA_AND_SPACE)/sizeof(COMMA_AND_SPACE[0]))-1) |
Azure.IoT Build | 0:fa2de1b79154 | 21 | |
Azure.IoT Build | 0:fa2de1b79154 | 22 | DEFINE_ENUM_STRINGS(HTTP_HEADERS_RESULT, HTTP_HEADERS_RESULT_VALUES); |
Azure.IoT Build | 0:fa2de1b79154 | 23 | |
Azure.IoT Build | 0:fa2de1b79154 | 24 | typedef struct HTTP_HEADERS_HANDLE_DATA_TAG |
Azure.IoT Build | 0:fa2de1b79154 | 25 | { |
Azure.IoT Build | 0:fa2de1b79154 | 26 | MAP_HANDLE headers; |
Azure.IoT Build | 0:fa2de1b79154 | 27 | } HTTP_HEADERS_HANDLE_DATA; |
Azure.IoT Build | 0:fa2de1b79154 | 28 | |
Azure.IoT Build | 0:fa2de1b79154 | 29 | HTTP_HEADERS_HANDLE HTTPHeaders_Alloc(void) |
Azure.IoT Build | 0:fa2de1b79154 | 30 | { |
Azure.IoT Build | 0:fa2de1b79154 | 31 | /*Codes_SRS_HTTP_HEADERS_99_002:[ This API shall produce a HTTP_HANDLE that can later be used in subsequent calls to the module.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 32 | HTTP_HEADERS_HANDLE_DATA* result; |
Azure.IoT Build | 0:fa2de1b79154 | 33 | result = (HTTP_HEADERS_HANDLE_DATA*)malloc(sizeof(HTTP_HEADERS_HANDLE_DATA)); |
Azure.IoT Build | 0:fa2de1b79154 | 34 | |
Azure.IoT Build | 0:fa2de1b79154 | 35 | if (result == NULL) |
Azure.IoT Build | 0:fa2de1b79154 | 36 | { |
AzureIoTClient | 1:9190c0f4d23a | 37 | LogError("malloc failed"); |
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_HTTP_HEADERS_99_004:[ After a successful init, HTTPHeaders_GetHeaderCount shall report 0 existing headers.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 42 | result->headers = Map_Create(NULL); |
Azure.IoT Build | 0:fa2de1b79154 | 43 | if (result->headers == NULL) |
Azure.IoT Build | 0:fa2de1b79154 | 44 | { |
AzureIoTClient | 1:9190c0f4d23a | 45 | LogError("Map_Create failed"); |
Azure.IoT Build | 0:fa2de1b79154 | 46 | free(result); |
Azure.IoT Build | 0:fa2de1b79154 | 47 | result = NULL; |
Azure.IoT Build | 0:fa2de1b79154 | 48 | } |
Azure.IoT Build | 0:fa2de1b79154 | 49 | else |
Azure.IoT Build | 0:fa2de1b79154 | 50 | { |
Azure.IoT Build | 0:fa2de1b79154 | 51 | /*all is fine*/ |
Azure.IoT Build | 0:fa2de1b79154 | 52 | } |
Azure.IoT Build | 0:fa2de1b79154 | 53 | } |
Azure.IoT Build | 0:fa2de1b79154 | 54 | |
Azure.IoT Build | 0:fa2de1b79154 | 55 | /*Codes_SRS_HTTP_HEADERS_99_003:[ The function shall return NULL when the function cannot execute properly]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 56 | return (HTTP_HEADERS_HANDLE)result; |
Azure.IoT Build | 0:fa2de1b79154 | 57 | } |
Azure.IoT Build | 0:fa2de1b79154 | 58 | |
Azure.IoT Build | 0:fa2de1b79154 | 59 | /*Codes_SRS_HTTP_HEADERS_99_005:[ Calling this API shall de-allocate the data structures allocated by previous API calls to the same handle.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 60 | void HTTPHeaders_Free(HTTP_HEADERS_HANDLE handle) |
Azure.IoT Build | 0:fa2de1b79154 | 61 | { |
Azure.IoT Build | 0:fa2de1b79154 | 62 | /*Codes_SRS_HTTP_HEADERS_02_001: [If httpHeadersHandle is NULL then HTTPHeaders_Free shall perform no action.] */ |
Azure.IoT Build | 0:fa2de1b79154 | 63 | if (handle == NULL) |
Azure.IoT Build | 0:fa2de1b79154 | 64 | { |
Azure.IoT Build | 0:fa2de1b79154 | 65 | /*do nothing*/ |
Azure.IoT Build | 0:fa2de1b79154 | 66 | } |
Azure.IoT Build | 0:fa2de1b79154 | 67 | else |
Azure.IoT Build | 0:fa2de1b79154 | 68 | { |
Azure.IoT Build | 0:fa2de1b79154 | 69 | /*Codes_SRS_HTTP_HEADERS_99_005:[ Calling this API shall de-allocate the data structures allocated by previous API calls to the same handle.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 70 | HTTP_HEADERS_HANDLE_DATA* handleData = (HTTP_HEADERS_HANDLE_DATA*)handle; |
Azure.IoT Build | 0:fa2de1b79154 | 71 | |
Azure.IoT Build | 0:fa2de1b79154 | 72 | Map_Destroy(handleData->headers); |
Azure.IoT Build | 0:fa2de1b79154 | 73 | free(handleData); |
Azure.IoT Build | 0:fa2de1b79154 | 74 | } |
Azure.IoT Build | 0:fa2de1b79154 | 75 | } |
Azure.IoT Build | 0:fa2de1b79154 | 76 | |
Azure.IoT Build | 0:fa2de1b79154 | 77 | /*Codes_SRS_HTTP_HEADERS_99_012:[ Calling this API shall record a header from name and value parameters.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 78 | static HTTP_HEADERS_RESULT headers_ReplaceHeaderNameValuePair(HTTP_HEADERS_HANDLE handle, const char* name, const char* value, bool replace) |
Azure.IoT Build | 0:fa2de1b79154 | 79 | { |
Azure.IoT Build | 0:fa2de1b79154 | 80 | HTTP_HEADERS_RESULT result; |
Azure.IoT Build | 0:fa2de1b79154 | 81 | /*Codes_SRS_HTTP_HEADERS_99_014:[ The function shall return when the handle is not valid or when name parameter is NULL or when value parameter is NULL.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 82 | if ( |
Azure.IoT Build | 0:fa2de1b79154 | 83 | (handle == NULL) || |
Azure.IoT Build | 0:fa2de1b79154 | 84 | (name == NULL) || |
Azure.IoT Build | 0:fa2de1b79154 | 85 | (value == NULL) |
Azure.IoT Build | 0:fa2de1b79154 | 86 | ) |
Azure.IoT Build | 0:fa2de1b79154 | 87 | { |
Azure.IoT Build | 0:fa2de1b79154 | 88 | result = HTTP_HEADERS_INVALID_ARG; |
AzureIoTClient | 1:9190c0f4d23a | 89 | LogError("invalid arg (NULL) , result= %s", ENUM_TO_STRING(HTTP_HEADERS_RESULT, result)); |
Azure.IoT Build | 0:fa2de1b79154 | 90 | } |
Azure.IoT Build | 0:fa2de1b79154 | 91 | else |
Azure.IoT Build | 0:fa2de1b79154 | 92 | { |
Azure.IoT Build | 0:fa2de1b79154 | 93 | /*Codes_SRS_HTTP_HEADERS_99_036:[ If name contains the characters outside character codes 33 to 126 then the return value shall be HTTP_HEADERS_INVALID_ARG]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 94 | /*Codes_SRS_HTTP_HEADERS_99_031:[ If name contains the character ":" then the return value shall be HTTP_HEADERS_INVALID_ARG.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 95 | size_t i; |
Azure.IoT Build | 0:fa2de1b79154 | 96 | size_t nameLen = strlen(name); |
Azure.IoT Build | 0:fa2de1b79154 | 97 | for (i = 0; i < nameLen; i++) |
Azure.IoT Build | 0:fa2de1b79154 | 98 | { |
Azure.IoT Build | 0:fa2de1b79154 | 99 | if ((name[i] < 33) || (126 < name[i]) || (name[i] == ':')) |
Azure.IoT Build | 0:fa2de1b79154 | 100 | { |
Azure.IoT Build | 0:fa2de1b79154 | 101 | break; |
Azure.IoT Build | 0:fa2de1b79154 | 102 | } |
Azure.IoT Build | 0:fa2de1b79154 | 103 | } |
Azure.IoT Build | 0:fa2de1b79154 | 104 | |
Azure.IoT Build | 0:fa2de1b79154 | 105 | if (i < nameLen) |
Azure.IoT Build | 0:fa2de1b79154 | 106 | { |
Azure.IoT Build | 0:fa2de1b79154 | 107 | result = HTTP_HEADERS_INVALID_ARG; |
AzureIoTClient | 1:9190c0f4d23a | 108 | LogError("(result = %s)", ENUM_TO_STRING(HTTP_HEADERS_RESULT, result)); |
Azure.IoT Build | 0:fa2de1b79154 | 109 | } |
Azure.IoT Build | 0:fa2de1b79154 | 110 | else |
Azure.IoT Build | 0:fa2de1b79154 | 111 | { |
Azure.IoT Build | 0:fa2de1b79154 | 112 | HTTP_HEADERS_HANDLE_DATA* handleData = (HTTP_HEADERS_HANDLE_DATA*)handle; |
Azure.IoT Build | 0:fa2de1b79154 | 113 | const char* existingValue = Map_GetValueFromKey(handleData->headers, name); |
Azure.IoT Build | 0:fa2de1b79154 | 114 | /*eat up the whitespaces from value, as per RFC 2616, chapter 4.2 "The field value MAY be preceded by any amount of LWS, though a single SP is preferred."*/ |
Azure.IoT Build | 0:fa2de1b79154 | 115 | /*Codes_SRS_HTTP_HEADERS_02_002: [The LWS from the beginning of the value shall not be stored.] */ |
Azure.IoT Build | 0:fa2de1b79154 | 116 | while ((value[0] == ' ') || (value[0] == '\t') || (value[0] == '\r') || (value[0] == '\n')) |
Azure.IoT Build | 0:fa2de1b79154 | 117 | { |
Azure.IoT Build | 0:fa2de1b79154 | 118 | value++; |
Azure.IoT Build | 0:fa2de1b79154 | 119 | } |
Azure.IoT Build | 0:fa2de1b79154 | 120 | |
Azure.IoT Build | 0:fa2de1b79154 | 121 | if (!replace && (existingValue != NULL)) |
Azure.IoT Build | 0:fa2de1b79154 | 122 | { |
Azure.IoT Build | 0:fa2de1b79154 | 123 | char* newValue = (char*)malloc(strlen(existingValue) + COMMA_AND_SPACE_LENGTH + strlen(value) + 1); |
Azure.IoT Build | 0:fa2de1b79154 | 124 | if (newValue == NULL) |
Azure.IoT Build | 0:fa2de1b79154 | 125 | { |
Azure.IoT Build | 0:fa2de1b79154 | 126 | /*Codes_SRS_HTTP_HEADERS_99_015:[ The function shall return HTTP_HEADERS_ALLOC_FAILED when an internal request to allocate memory fails.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 127 | result = HTTP_HEADERS_ALLOC_FAILED; |
AzureIoTClient | 1:9190c0f4d23a | 128 | LogError("failed to malloc , result= %s", ENUM_TO_STRING(HTTP_HEADERS_RESULT, result)); |
Azure.IoT Build | 0:fa2de1b79154 | 129 | } |
Azure.IoT Build | 0:fa2de1b79154 | 130 | else |
Azure.IoT Build | 0:fa2de1b79154 | 131 | { |
Azure.IoT Build | 0:fa2de1b79154 | 132 | /*Codes_SRS_HTTP_HEADERS_99_017:[ If the name already exists in the collection of headers, the function shall concatenate the new value after the existing value, separated by a comma and a space as in: old-value+", "+new-value.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 133 | (void)strcpy(newValue, existingValue); |
Azure.IoT Build | 0:fa2de1b79154 | 134 | (void)strcat(newValue, COMMA_AND_SPACE); |
Azure.IoT Build | 0:fa2de1b79154 | 135 | (void)strcat(newValue, value); |
Azure.IoT Build | 0:fa2de1b79154 | 136 | |
Azure.IoT Build | 0:fa2de1b79154 | 137 | /*Codes_SRS_HTTP_HEADERS_99_016:[ The function shall store the name:value pair in such a way that when later retrieved by a call to GetHeader it will return a string that shall strcmp equal to the name+": "+value.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 138 | if (Map_AddOrUpdate(handleData->headers, name, newValue) != MAP_OK) |
Azure.IoT Build | 0:fa2de1b79154 | 139 | { |
Azure.IoT Build | 0:fa2de1b79154 | 140 | /*Codes_SRS_HTTP_HEADERS_99_015:[ The function shall return HTTP_HEADERS_ALLOC_FAILED when an internal request to allocate memory fails.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 141 | result = HTTP_HEADERS_ERROR; |
AzureIoTClient | 1:9190c0f4d23a | 142 | LogError("failed to Map_AddOrUpdate, result= %s", ENUM_TO_STRING(HTTP_HEADERS_RESULT, result)); |
Azure.IoT Build | 0:fa2de1b79154 | 143 | } |
Azure.IoT Build | 0:fa2de1b79154 | 144 | else |
Azure.IoT Build | 0:fa2de1b79154 | 145 | { |
Azure.IoT Build | 0:fa2de1b79154 | 146 | /*Codes_SRS_HTTP_HEADERS_99_013:[ The function shall return HTTP_HEADERS_OK when execution is successful.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 147 | result = HTTP_HEADERS_OK; |
Azure.IoT Build | 0:fa2de1b79154 | 148 | } |
Azure.IoT Build | 0:fa2de1b79154 | 149 | free(newValue); |
Azure.IoT Build | 0:fa2de1b79154 | 150 | } |
Azure.IoT Build | 0:fa2de1b79154 | 151 | } |
Azure.IoT Build | 0:fa2de1b79154 | 152 | else |
Azure.IoT Build | 0:fa2de1b79154 | 153 | { |
Azure.IoT Build | 0:fa2de1b79154 | 154 | /*Codes_SRS_HTTP_HEADERS_99_016:[ The function shall store the name:value pair in such a way that when later retrieved by a call to GetHeader it will return a string that shall strcmp equal to the name+": "+value.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 155 | if (Map_AddOrUpdate(handleData->headers, name, value) != MAP_OK) |
Azure.IoT Build | 0:fa2de1b79154 | 156 | { |
Azure.IoT Build | 0:fa2de1b79154 | 157 | /*Codes_SRS_HTTP_HEADERS_99_015:[ The function shall return HTTP_HEADERS_ALLOC_FAILED when an internal request to allocate memory fails.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 158 | result = HTTP_HEADERS_ALLOC_FAILED; |
AzureIoTClient | 1:9190c0f4d23a | 159 | LogError("failed to Map_AddOrUpdate, result= %s", ENUM_TO_STRING(HTTP_HEADERS_RESULT, result)); |
Azure.IoT Build | 0:fa2de1b79154 | 160 | } |
Azure.IoT Build | 0:fa2de1b79154 | 161 | else |
Azure.IoT Build | 0:fa2de1b79154 | 162 | { |
Azure.IoT Build | 0:fa2de1b79154 | 163 | result = HTTP_HEADERS_OK; |
Azure.IoT Build | 0:fa2de1b79154 | 164 | } |
Azure.IoT Build | 0:fa2de1b79154 | 165 | } |
Azure.IoT Build | 0:fa2de1b79154 | 166 | } |
Azure.IoT Build | 0:fa2de1b79154 | 167 | } |
Azure.IoT Build | 0:fa2de1b79154 | 168 | |
Azure.IoT Build | 0:fa2de1b79154 | 169 | return result; |
Azure.IoT Build | 0:fa2de1b79154 | 170 | } |
Azure.IoT Build | 0:fa2de1b79154 | 171 | |
Azure.IoT Build | 0:fa2de1b79154 | 172 | HTTP_HEADERS_RESULT HTTPHeaders_AddHeaderNameValuePair(HTTP_HEADERS_HANDLE httpHeadersHandle, const char* name, const char* value) |
Azure.IoT Build | 0:fa2de1b79154 | 173 | { |
Azure.IoT Build | 0:fa2de1b79154 | 174 | return headers_ReplaceHeaderNameValuePair(httpHeadersHandle, name, value, false); |
Azure.IoT Build | 0:fa2de1b79154 | 175 | } |
Azure.IoT Build | 0:fa2de1b79154 | 176 | |
Azure.IoT Build | 0:fa2de1b79154 | 177 | /* Codes_SRS_HTTP_HEADERS_06_001: [This API will perform exactly as HTTPHeaders_AddHeaderNameValuePair except that if the header name already exists the already existing value will be replaced as opposed to concatenated to.] */ |
Azure.IoT Build | 0:fa2de1b79154 | 178 | HTTP_HEADERS_RESULT HTTPHeaders_ReplaceHeaderNameValuePair(HTTP_HEADERS_HANDLE httpHeadersHandle, const char* name, const char* value) |
Azure.IoT Build | 0:fa2de1b79154 | 179 | { |
Azure.IoT Build | 0:fa2de1b79154 | 180 | return headers_ReplaceHeaderNameValuePair(httpHeadersHandle, name, value, true); |
Azure.IoT Build | 0:fa2de1b79154 | 181 | } |
Azure.IoT Build | 0:fa2de1b79154 | 182 | |
Azure.IoT Build | 0:fa2de1b79154 | 183 | |
Azure.IoT Build | 0:fa2de1b79154 | 184 | const char* HTTPHeaders_FindHeaderValue(HTTP_HEADERS_HANDLE httpHeadersHandle, const char* name) |
Azure.IoT Build | 0:fa2de1b79154 | 185 | { |
Azure.IoT Build | 0:fa2de1b79154 | 186 | const char* result; |
Azure.IoT Build | 0:fa2de1b79154 | 187 | /*Codes_SRS_HTTP_HEADERS_99_022:[ The return value shall be NULL if name parameter is NULL or if httpHeadersHandle is NULL]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 188 | if ( |
Azure.IoT Build | 0:fa2de1b79154 | 189 | (httpHeadersHandle == NULL) || |
Azure.IoT Build | 0:fa2de1b79154 | 190 | (name == NULL) |
Azure.IoT Build | 0:fa2de1b79154 | 191 | ) |
Azure.IoT Build | 0:fa2de1b79154 | 192 | { |
Azure.IoT Build | 0:fa2de1b79154 | 193 | result = NULL; |
Azure.IoT Build | 0:fa2de1b79154 | 194 | } |
Azure.IoT Build | 0:fa2de1b79154 | 195 | else |
Azure.IoT Build | 0:fa2de1b79154 | 196 | { |
Azure.IoT Build | 0:fa2de1b79154 | 197 | /*Codes_SRS_HTTP_HEADERS_99_018:[ Calling this API shall retrieve the value for a previously stored name.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 198 | /*Codes_SRS_HTTP_HEADERS_99_020:[ The return value shall be different than NULL when the name matches the name of a previously stored name:value pair.] */ |
Azure.IoT Build | 0:fa2de1b79154 | 199 | /*Codes_SRS_HTTP_HEADERS_99_021:[ In this case the return value shall point to a string that shall strcmp equal to the original stored string.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 200 | HTTP_HEADERS_HANDLE_DATA* handleData = (HTTP_HEADERS_HANDLE_DATA*)httpHeadersHandle; |
Azure.IoT Build | 0:fa2de1b79154 | 201 | result = Map_GetValueFromKey(handleData->headers, name); |
Azure.IoT Build | 0:fa2de1b79154 | 202 | } |
Azure.IoT Build | 0:fa2de1b79154 | 203 | return result; |
Azure.IoT Build | 0:fa2de1b79154 | 204 | |
Azure.IoT Build | 0:fa2de1b79154 | 205 | } |
Azure.IoT Build | 0:fa2de1b79154 | 206 | |
Azure.IoT Build | 0:fa2de1b79154 | 207 | HTTP_HEADERS_RESULT HTTPHeaders_GetHeaderCount(HTTP_HEADERS_HANDLE handle, size_t* headerCount) |
Azure.IoT Build | 0:fa2de1b79154 | 208 | { |
Azure.IoT Build | 0:fa2de1b79154 | 209 | HTTP_HEADERS_RESULT result; |
Azure.IoT Build | 0:fa2de1b79154 | 210 | /*Codes_SRS_HTTP_HEADERS_99_024:[ The function shall return HTTP_HEADERS_INVALID_ARG when an invalid handle is passed.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 211 | /*Codes_SRS_HTTP_HEADERS_99_025:[ The function shall return HTTP_HEADERS_INVALID_ARG when headersCount is NULL.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 212 | if ((handle == NULL) || |
Azure.IoT Build | 0:fa2de1b79154 | 213 | (headerCount == NULL)) |
Azure.IoT Build | 0:fa2de1b79154 | 214 | { |
Azure.IoT Build | 0:fa2de1b79154 | 215 | result = HTTP_HEADERS_INVALID_ARG; |
AzureIoTClient | 1:9190c0f4d23a | 216 | LogError("(result = %s)", ENUM_TO_STRING(HTTP_HEADERS_RESULT, result)); |
Azure.IoT Build | 0:fa2de1b79154 | 217 | } |
Azure.IoT Build | 0:fa2de1b79154 | 218 | else |
Azure.IoT Build | 0:fa2de1b79154 | 219 | { |
Azure.IoT Build | 0:fa2de1b79154 | 220 | HTTP_HEADERS_HANDLE_DATA *handleData = (HTTP_HEADERS_HANDLE_DATA *)handle; |
Azure.IoT Build | 0:fa2de1b79154 | 221 | const char*const* keys; |
Azure.IoT Build | 0:fa2de1b79154 | 222 | const char*const* values; |
Azure.IoT Build | 0:fa2de1b79154 | 223 | /*Codes_SRS_HTTP_HEADERS_99_023:[ Calling this API shall provide the number of stored headers.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 224 | if (Map_GetInternals(handleData->headers, &keys, &values, headerCount) != MAP_OK) |
Azure.IoT Build | 0:fa2de1b79154 | 225 | { |
Azure.IoT Build | 0:fa2de1b79154 | 226 | /*Codes_SRS_HTTP_HEADERS_99_037:[ The function shall return HTTP_HEADERS_ERROR when an internal error occurs.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 227 | result = HTTP_HEADERS_ERROR; |
AzureIoTClient | 1:9190c0f4d23a | 228 | LogError("Map_GetInternals failed, result= %s", ENUM_TO_STRING(HTTP_HEADERS_RESULT, result)); |
Azure.IoT Build | 0:fa2de1b79154 | 229 | } |
Azure.IoT Build | 0:fa2de1b79154 | 230 | else |
Azure.IoT Build | 0:fa2de1b79154 | 231 | { |
Azure.IoT Build | 0:fa2de1b79154 | 232 | /*Codes_SRS_HTTP_HEADERS_99_026:[ The function shall write in *headersCount the number of currently stored headers and shall return HTTP_HEADERS_OK]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 233 | result = HTTP_HEADERS_OK; |
Azure.IoT Build | 0:fa2de1b79154 | 234 | } |
Azure.IoT Build | 0:fa2de1b79154 | 235 | } |
Azure.IoT Build | 0:fa2de1b79154 | 236 | |
Azure.IoT Build | 0:fa2de1b79154 | 237 | return result; |
Azure.IoT Build | 0:fa2de1b79154 | 238 | } |
Azure.IoT Build | 0:fa2de1b79154 | 239 | |
Azure.IoT Build | 0:fa2de1b79154 | 240 | /*produces a string in *destination that is equal to name: value*/ |
Azure.IoT Build | 0:fa2de1b79154 | 241 | HTTP_HEADERS_RESULT HTTPHeaders_GetHeader(HTTP_HEADERS_HANDLE handle, size_t index, char** destination) |
Azure.IoT Build | 0:fa2de1b79154 | 242 | { |
Azure.IoT Build | 0:fa2de1b79154 | 243 | HTTP_HEADERS_RESULT result = HTTP_HEADERS_OK; |
Azure.IoT Build | 0:fa2de1b79154 | 244 | |
Azure.IoT Build | 0:fa2de1b79154 | 245 | /*Codes_SRS_HTTP_HEADERS_99_028:[ The function shall return NULL if the handle is invalid.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 246 | /*Codes_SRS_HTTP_HEADERS_99_032:[ The function shall return HTTP_HEADERS_INVALID_ARG if the destination is NULL]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 247 | if ( |
Azure.IoT Build | 0:fa2de1b79154 | 248 | (handle == NULL) || |
Azure.IoT Build | 0:fa2de1b79154 | 249 | (destination == NULL) |
Azure.IoT Build | 0:fa2de1b79154 | 250 | ) |
Azure.IoT Build | 0:fa2de1b79154 | 251 | { |
Azure.IoT Build | 0:fa2de1b79154 | 252 | result = HTTP_HEADERS_INVALID_ARG; |
AzureIoTClient | 1:9190c0f4d23a | 253 | LogError("invalid arg (NULL), result= %s", ENUM_TO_STRING(HTTP_HEADERS_RESULT, result)); |
Azure.IoT Build | 0:fa2de1b79154 | 254 | } |
Azure.IoT Build | 0:fa2de1b79154 | 255 | /*Codes_SRS_HTTP_HEADERS_99_029:[ The function shall return HTTP_HEADERS_INVALID_ARG if index is not valid (for example, out of range) for the currently stored headers.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 256 | else |
Azure.IoT Build | 0:fa2de1b79154 | 257 | { |
Azure.IoT Build | 0:fa2de1b79154 | 258 | HTTP_HEADERS_HANDLE_DATA* handleData = (HTTP_HEADERS_HANDLE_DATA*)handle; |
Azure.IoT Build | 0:fa2de1b79154 | 259 | const char*const* keys; |
Azure.IoT Build | 0:fa2de1b79154 | 260 | const char*const* values; |
Azure.IoT Build | 0:fa2de1b79154 | 261 | size_t headerCount; |
Azure.IoT Build | 0:fa2de1b79154 | 262 | if (Map_GetInternals(handleData->headers, &keys, &values, &headerCount) != MAP_OK) |
Azure.IoT Build | 0:fa2de1b79154 | 263 | { |
Azure.IoT Build | 0:fa2de1b79154 | 264 | /*Codes_SRS_HTTP_HEADERS_99_034:[ The function shall return HTTP_HEADERS_ERROR when an internal error occurs]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 265 | result = HTTP_HEADERS_ERROR; |
AzureIoTClient | 1:9190c0f4d23a | 266 | LogError("Map_GetInternals failed, result= %s", ENUM_TO_STRING(HTTP_HEADERS_RESULT, result)); |
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_HTTP_HEADERS_99_029:[ The function shall return HTTP_HEADERS_INVALID_ARG if index is not valid (for example, out of range) for the currently stored headers.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 271 | if (index >= headerCount) |
Azure.IoT Build | 0:fa2de1b79154 | 272 | { |
Azure.IoT Build | 0:fa2de1b79154 | 273 | result = HTTP_HEADERS_INVALID_ARG; |
AzureIoTClient | 1:9190c0f4d23a | 274 | LogError("index out of bounds, result= %s", ENUM_TO_STRING(HTTP_HEADERS_RESULT, result)); |
Azure.IoT Build | 0:fa2de1b79154 | 275 | } |
Azure.IoT Build | 0:fa2de1b79154 | 276 | else |
Azure.IoT Build | 0:fa2de1b79154 | 277 | { |
Azure.IoT Build | 0:fa2de1b79154 | 278 | *destination = (char*)malloc(strlen(keys[index]) + COLON_AND_SPACE_LENGTH + strlen(values[index]) + 1); |
Azure.IoT Build | 0:fa2de1b79154 | 279 | if (*destination == NULL) |
Azure.IoT Build | 0:fa2de1b79154 | 280 | { |
Azure.IoT Build | 0:fa2de1b79154 | 281 | /*Codes_SRS_HTTP_HEADERS_99_034:[ The function shall return HTTP_HEADERS_ERROR when an internal error occurs]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 282 | result = HTTP_HEADERS_ERROR; |
AzureIoTClient | 1:9190c0f4d23a | 283 | LogError("unable to malloc, result= %s", ENUM_TO_STRING(HTTP_HEADERS_RESULT, result)); |
Azure.IoT Build | 0:fa2de1b79154 | 284 | } |
Azure.IoT Build | 0:fa2de1b79154 | 285 | else |
Azure.IoT Build | 0:fa2de1b79154 | 286 | { |
Azure.IoT Build | 0:fa2de1b79154 | 287 | /*Codes_SRS_HTTP_HEADERS_99_016:[ The function shall store the name:value pair in such a way that when later retrieved by a call to GetHeader it will return a string that shall strcmp equal to the name+": "+value.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 288 | /*Codes_SRS_HTTP_HEADERS_99_027:[ Calling this API shall produce the string value+": "+pair) for the index header in the *destination parameter.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 289 | strcpy(*destination, keys[index]); |
Azure.IoT Build | 0:fa2de1b79154 | 290 | strcat(*destination, COLON_AND_SPACE); |
Azure.IoT Build | 0:fa2de1b79154 | 291 | strcat(*destination, values[index]); |
Azure.IoT Build | 0:fa2de1b79154 | 292 | /*Codes_SRS_HTTP_HEADERS_99_035:[ The function shall return HTTP_HEADERS_OK when the function executed without error.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 293 | result = HTTP_HEADERS_OK; |
Azure.IoT Build | 0:fa2de1b79154 | 294 | } |
Azure.IoT Build | 0:fa2de1b79154 | 295 | } |
Azure.IoT Build | 0:fa2de1b79154 | 296 | } |
Azure.IoT Build | 0:fa2de1b79154 | 297 | } |
Azure.IoT Build | 0:fa2de1b79154 | 298 | |
Azure.IoT Build | 0:fa2de1b79154 | 299 | return result; |
Azure.IoT Build | 0:fa2de1b79154 | 300 | } |
Azure.IoT Build | 0:fa2de1b79154 | 301 | |
Azure.IoT Build | 0:fa2de1b79154 | 302 | HTTP_HEADERS_HANDLE HTTPHeaders_Clone(HTTP_HEADERS_HANDLE handle) |
Azure.IoT Build | 0:fa2de1b79154 | 303 | { |
Azure.IoT Build | 0:fa2de1b79154 | 304 | HTTP_HEADERS_HANDLE_DATA* result; |
Azure.IoT Build | 0:fa2de1b79154 | 305 | /*Codes_SRS_HTTP_HEADERS_02_003: [If handle is NULL then HTTPHeaders_Clone shall return NULL.] */ |
Azure.IoT Build | 0:fa2de1b79154 | 306 | if (handle == NULL) |
Azure.IoT Build | 0:fa2de1b79154 | 307 | { |
Azure.IoT Build | 0:fa2de1b79154 | 308 | result = NULL; |
Azure.IoT Build | 0:fa2de1b79154 | 309 | } |
Azure.IoT Build | 0:fa2de1b79154 | 310 | else |
Azure.IoT Build | 0:fa2de1b79154 | 311 | { |
Azure.IoT Build | 0:fa2de1b79154 | 312 | /*Codes_SRS_HTTP_HEADERS_02_004: [Otherwise HTTPHeaders_Clone shall clone the content of handle to a new handle.] */ |
Azure.IoT Build | 0:fa2de1b79154 | 313 | result = malloc(sizeof(HTTP_HEADERS_HANDLE_DATA)); |
Azure.IoT Build | 0:fa2de1b79154 | 314 | if (result == NULL) |
Azure.IoT Build | 0:fa2de1b79154 | 315 | { |
Azure.IoT Build | 0:fa2de1b79154 | 316 | /*Codes_SRS_HTTP_HEADERS_02_005: [If cloning fails for any reason, then HTTPHeaders_Clone shall return NULL.] */ |
Azure.IoT Build | 0:fa2de1b79154 | 317 | } |
Azure.IoT Build | 0:fa2de1b79154 | 318 | else |
Azure.IoT Build | 0:fa2de1b79154 | 319 | { |
Azure.IoT Build | 0:fa2de1b79154 | 320 | HTTP_HEADERS_HANDLE_DATA* handleData = handle; |
Azure.IoT Build | 0:fa2de1b79154 | 321 | result->headers = Map_Clone(handleData->headers); |
Azure.IoT Build | 0:fa2de1b79154 | 322 | if (result->headers == NULL) |
Azure.IoT Build | 0:fa2de1b79154 | 323 | { |
Azure.IoT Build | 0:fa2de1b79154 | 324 | /*Codes_SRS_HTTP_HEADERS_02_005: [If cloning fails for any reason, then HTTPHeaders_Clone shall return NULL.] */ |
Azure.IoT Build | 0:fa2de1b79154 | 325 | free(result); |
Azure.IoT Build | 0:fa2de1b79154 | 326 | result = NULL; |
Azure.IoT Build | 0:fa2de1b79154 | 327 | } |
Azure.IoT Build | 0:fa2de1b79154 | 328 | else |
Azure.IoT Build | 0:fa2de1b79154 | 329 | { |
Azure.IoT Build | 0:fa2de1b79154 | 330 | /*all is fine*/ |
Azure.IoT Build | 0:fa2de1b79154 | 331 | } |
Azure.IoT Build | 0:fa2de1b79154 | 332 | } |
Azure.IoT Build | 0:fa2de1b79154 | 333 | } |
Azure.IoT Build | 0:fa2de1b79154 | 334 | return result; |
Azure.IoT Build | 0:fa2de1b79154 | 335 | } |