Azure IoT common library
Fork of azure_c_shared_utility by
httpheaders.c@11:77df6d7e65ae, 2016-09-09 (annotated)
- Committer:
- AzureIoTClient
- Date:
- Fri Sep 09 13:38:26 2016 -0700
- Revision:
- 11:77df6d7e65ae
- Parent:
- 6:c55b013dfc2a
- Child:
- 19:2e0811512ceb
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 | DEFINE_ENUM_STRINGS(HTTP_HEADERS_RESULT, HTTP_HEADERS_RESULT_VALUES); |
Azure.IoT Build | 0:fa2de1b79154 | 17 | |
Azure.IoT Build | 0:fa2de1b79154 | 18 | typedef struct HTTP_HEADERS_HANDLE_DATA_TAG |
Azure.IoT Build | 0:fa2de1b79154 | 19 | { |
Azure.IoT Build | 0:fa2de1b79154 | 20 | MAP_HANDLE headers; |
Azure.IoT Build | 0:fa2de1b79154 | 21 | } HTTP_HEADERS_HANDLE_DATA; |
Azure.IoT Build | 0:fa2de1b79154 | 22 | |
Azure.IoT Build | 0:fa2de1b79154 | 23 | HTTP_HEADERS_HANDLE HTTPHeaders_Alloc(void) |
Azure.IoT Build | 0:fa2de1b79154 | 24 | { |
Azure.IoT Build | 0:fa2de1b79154 | 25 | /*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 | 26 | HTTP_HEADERS_HANDLE_DATA* result; |
Azure.IoT Build | 0:fa2de1b79154 | 27 | result = (HTTP_HEADERS_HANDLE_DATA*)malloc(sizeof(HTTP_HEADERS_HANDLE_DATA)); |
Azure.IoT Build | 0:fa2de1b79154 | 28 | |
Azure.IoT Build | 0:fa2de1b79154 | 29 | if (result == NULL) |
Azure.IoT Build | 0:fa2de1b79154 | 30 | { |
AzureIoTClient | 1:9190c0f4d23a | 31 | LogError("malloc failed"); |
Azure.IoT Build | 0:fa2de1b79154 | 32 | } |
Azure.IoT Build | 0:fa2de1b79154 | 33 | else |
Azure.IoT Build | 0:fa2de1b79154 | 34 | { |
Azure.IoT Build | 0:fa2de1b79154 | 35 | /*Codes_SRS_HTTP_HEADERS_99_004:[ After a successful init, HTTPHeaders_GetHeaderCount shall report 0 existing headers.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 36 | result->headers = Map_Create(NULL); |
Azure.IoT Build | 0:fa2de1b79154 | 37 | if (result->headers == NULL) |
Azure.IoT Build | 0:fa2de1b79154 | 38 | { |
AzureIoTClient | 1:9190c0f4d23a | 39 | LogError("Map_Create failed"); |
Azure.IoT Build | 0:fa2de1b79154 | 40 | free(result); |
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 | /*all is fine*/ |
Azure.IoT Build | 0:fa2de1b79154 | 46 | } |
Azure.IoT Build | 0:fa2de1b79154 | 47 | } |
Azure.IoT Build | 0:fa2de1b79154 | 48 | |
Azure.IoT Build | 0:fa2de1b79154 | 49 | /*Codes_SRS_HTTP_HEADERS_99_003:[ The function shall return NULL when the function cannot execute properly]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 50 | return (HTTP_HEADERS_HANDLE)result; |
Azure.IoT Build | 0:fa2de1b79154 | 51 | } |
Azure.IoT Build | 0:fa2de1b79154 | 52 | |
Azure.IoT Build | 0:fa2de1b79154 | 53 | /*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 | 54 | void HTTPHeaders_Free(HTTP_HEADERS_HANDLE handle) |
Azure.IoT Build | 0:fa2de1b79154 | 55 | { |
Azure.IoT Build | 0:fa2de1b79154 | 56 | /*Codes_SRS_HTTP_HEADERS_02_001: [If httpHeadersHandle is NULL then HTTPHeaders_Free shall perform no action.] */ |
Azure.IoT Build | 0:fa2de1b79154 | 57 | if (handle == NULL) |
Azure.IoT Build | 0:fa2de1b79154 | 58 | { |
Azure.IoT Build | 0:fa2de1b79154 | 59 | /*do nothing*/ |
Azure.IoT Build | 0:fa2de1b79154 | 60 | } |
Azure.IoT Build | 0:fa2de1b79154 | 61 | else |
Azure.IoT Build | 0:fa2de1b79154 | 62 | { |
Azure.IoT Build | 0:fa2de1b79154 | 63 | /*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 | 64 | HTTP_HEADERS_HANDLE_DATA* handleData = (HTTP_HEADERS_HANDLE_DATA*)handle; |
Azure.IoT Build | 0:fa2de1b79154 | 65 | |
Azure.IoT Build | 0:fa2de1b79154 | 66 | Map_Destroy(handleData->headers); |
Azure.IoT Build | 0:fa2de1b79154 | 67 | free(handleData); |
Azure.IoT Build | 0:fa2de1b79154 | 68 | } |
Azure.IoT Build | 0:fa2de1b79154 | 69 | } |
Azure.IoT Build | 0:fa2de1b79154 | 70 | |
Azure.IoT Build | 0:fa2de1b79154 | 71 | /*Codes_SRS_HTTP_HEADERS_99_012:[ Calling this API shall record a header from name and value parameters.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 72 | static HTTP_HEADERS_RESULT headers_ReplaceHeaderNameValuePair(HTTP_HEADERS_HANDLE handle, const char* name, const char* value, bool replace) |
Azure.IoT Build | 0:fa2de1b79154 | 73 | { |
Azure.IoT Build | 0:fa2de1b79154 | 74 | HTTP_HEADERS_RESULT result; |
Azure.IoT Build | 0:fa2de1b79154 | 75 | /*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 | 76 | if ( |
Azure.IoT Build | 0:fa2de1b79154 | 77 | (handle == NULL) || |
Azure.IoT Build | 0:fa2de1b79154 | 78 | (name == NULL) || |
Azure.IoT Build | 0:fa2de1b79154 | 79 | (value == NULL) |
Azure.IoT Build | 0:fa2de1b79154 | 80 | ) |
Azure.IoT Build | 0:fa2de1b79154 | 81 | { |
Azure.IoT Build | 0:fa2de1b79154 | 82 | result = HTTP_HEADERS_INVALID_ARG; |
AzureIoTClient | 1:9190c0f4d23a | 83 | LogError("invalid arg (NULL) , result= %s", ENUM_TO_STRING(HTTP_HEADERS_RESULT, result)); |
Azure.IoT Build | 0:fa2de1b79154 | 84 | } |
Azure.IoT Build | 0:fa2de1b79154 | 85 | else |
Azure.IoT Build | 0:fa2de1b79154 | 86 | { |
Azure.IoT Build | 0:fa2de1b79154 | 87 | /*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 | 88 | /*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 | 89 | size_t i; |
Azure.IoT Build | 0:fa2de1b79154 | 90 | size_t nameLen = strlen(name); |
Azure.IoT Build | 0:fa2de1b79154 | 91 | for (i = 0; i < nameLen; i++) |
Azure.IoT Build | 0:fa2de1b79154 | 92 | { |
Azure.IoT Build | 0:fa2de1b79154 | 93 | if ((name[i] < 33) || (126 < name[i]) || (name[i] == ':')) |
Azure.IoT Build | 0:fa2de1b79154 | 94 | { |
Azure.IoT Build | 0:fa2de1b79154 | 95 | break; |
Azure.IoT Build | 0:fa2de1b79154 | 96 | } |
Azure.IoT Build | 0:fa2de1b79154 | 97 | } |
Azure.IoT Build | 0:fa2de1b79154 | 98 | |
Azure.IoT Build | 0:fa2de1b79154 | 99 | if (i < nameLen) |
Azure.IoT Build | 0:fa2de1b79154 | 100 | { |
Azure.IoT Build | 0:fa2de1b79154 | 101 | result = HTTP_HEADERS_INVALID_ARG; |
AzureIoTClient | 1:9190c0f4d23a | 102 | LogError("(result = %s)", ENUM_TO_STRING(HTTP_HEADERS_RESULT, result)); |
Azure.IoT Build | 0:fa2de1b79154 | 103 | } |
Azure.IoT Build | 0:fa2de1b79154 | 104 | else |
Azure.IoT Build | 0:fa2de1b79154 | 105 | { |
Azure.IoT Build | 0:fa2de1b79154 | 106 | HTTP_HEADERS_HANDLE_DATA* handleData = (HTTP_HEADERS_HANDLE_DATA*)handle; |
Azure.IoT Build | 0:fa2de1b79154 | 107 | const char* existingValue = Map_GetValueFromKey(handleData->headers, name); |
Azure.IoT Build | 0:fa2de1b79154 | 108 | /*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 | 109 | /*Codes_SRS_HTTP_HEADERS_02_002: [The LWS from the beginning of the value shall not be stored.] */ |
Azure.IoT Build | 0:fa2de1b79154 | 110 | while ((value[0] == ' ') || (value[0] == '\t') || (value[0] == '\r') || (value[0] == '\n')) |
Azure.IoT Build | 0:fa2de1b79154 | 111 | { |
Azure.IoT Build | 0:fa2de1b79154 | 112 | value++; |
Azure.IoT Build | 0:fa2de1b79154 | 113 | } |
Azure.IoT Build | 0:fa2de1b79154 | 114 | |
Azure.IoT Build | 0:fa2de1b79154 | 115 | if (!replace && (existingValue != NULL)) |
Azure.IoT Build | 0:fa2de1b79154 | 116 | { |
AzureIoTClient | 11:77df6d7e65ae | 117 | size_t existingValueLen = strlen(existingValue); |
AzureIoTClient | 11:77df6d7e65ae | 118 | size_t valueLen = strlen(value); |
AzureIoTClient | 11:77df6d7e65ae | 119 | char* newValue = (char*)malloc(sizeof(char) * (existingValueLen + /*COMMA_AND_SPACE_LENGTH*/ 2 + valueLen + /*EOL*/ 1)); |
Azure.IoT Build | 0:fa2de1b79154 | 120 | if (newValue == NULL) |
Azure.IoT Build | 0:fa2de1b79154 | 121 | { |
Azure.IoT Build | 0:fa2de1b79154 | 122 | /*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 | 123 | result = HTTP_HEADERS_ALLOC_FAILED; |
AzureIoTClient | 1:9190c0f4d23a | 124 | LogError("failed to malloc , result= %s", ENUM_TO_STRING(HTTP_HEADERS_RESULT, result)); |
Azure.IoT Build | 0:fa2de1b79154 | 125 | } |
Azure.IoT Build | 0:fa2de1b79154 | 126 | else |
Azure.IoT Build | 0:fa2de1b79154 | 127 | { |
AzureIoTClient | 11:77df6d7e65ae | 128 | char* runNewValue; |
Azure.IoT Build | 0:fa2de1b79154 | 129 | /*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.]*/ |
AzureIoTClient | 11:77df6d7e65ae | 130 | (void)memcpy(newValue, existingValue, existingValueLen); |
AzureIoTClient | 11:77df6d7e65ae | 131 | runNewValue = newValue + existingValueLen; |
AzureIoTClient | 11:77df6d7e65ae | 132 | (*runNewValue++) = ','; |
AzureIoTClient | 11:77df6d7e65ae | 133 | (*runNewValue++) = ' '; |
AzureIoTClient | 11:77df6d7e65ae | 134 | (void)memcpy(runNewValue, value, valueLen + /*EOL*/ 1); |
Azure.IoT Build | 0:fa2de1b79154 | 135 | |
Azure.IoT Build | 0:fa2de1b79154 | 136 | /*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 | 137 | if (Map_AddOrUpdate(handleData->headers, name, newValue) != MAP_OK) |
Azure.IoT Build | 0:fa2de1b79154 | 138 | { |
Azure.IoT Build | 0:fa2de1b79154 | 139 | /*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 | 140 | result = HTTP_HEADERS_ERROR; |
AzureIoTClient | 1:9190c0f4d23a | 141 | LogError("failed to Map_AddOrUpdate, result= %s", ENUM_TO_STRING(HTTP_HEADERS_RESULT, result)); |
Azure.IoT Build | 0:fa2de1b79154 | 142 | } |
Azure.IoT Build | 0:fa2de1b79154 | 143 | else |
Azure.IoT Build | 0:fa2de1b79154 | 144 | { |
Azure.IoT Build | 0:fa2de1b79154 | 145 | /*Codes_SRS_HTTP_HEADERS_99_013:[ The function shall return HTTP_HEADERS_OK when execution is successful.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 146 | result = HTTP_HEADERS_OK; |
Azure.IoT Build | 0:fa2de1b79154 | 147 | } |
Azure.IoT Build | 0:fa2de1b79154 | 148 | free(newValue); |
Azure.IoT Build | 0:fa2de1b79154 | 149 | } |
Azure.IoT Build | 0:fa2de1b79154 | 150 | } |
Azure.IoT Build | 0:fa2de1b79154 | 151 | else |
Azure.IoT Build | 0:fa2de1b79154 | 152 | { |
Azure.IoT Build | 0:fa2de1b79154 | 153 | /*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 | 154 | if (Map_AddOrUpdate(handleData->headers, name, value) != MAP_OK) |
Azure.IoT Build | 0:fa2de1b79154 | 155 | { |
Azure.IoT Build | 0:fa2de1b79154 | 156 | /*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 | 157 | result = HTTP_HEADERS_ALLOC_FAILED; |
AzureIoTClient | 1:9190c0f4d23a | 158 | LogError("failed to Map_AddOrUpdate, result= %s", ENUM_TO_STRING(HTTP_HEADERS_RESULT, result)); |
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 | result = HTTP_HEADERS_OK; |
Azure.IoT Build | 0:fa2de1b79154 | 163 | } |
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 | return result; |
Azure.IoT Build | 0:fa2de1b79154 | 169 | } |
Azure.IoT Build | 0:fa2de1b79154 | 170 | |
Azure.IoT Build | 0:fa2de1b79154 | 171 | HTTP_HEADERS_RESULT HTTPHeaders_AddHeaderNameValuePair(HTTP_HEADERS_HANDLE httpHeadersHandle, const char* name, const char* value) |
Azure.IoT Build | 0:fa2de1b79154 | 172 | { |
Azure.IoT Build | 0:fa2de1b79154 | 173 | return headers_ReplaceHeaderNameValuePair(httpHeadersHandle, name, value, false); |
Azure.IoT Build | 0:fa2de1b79154 | 174 | } |
Azure.IoT Build | 0:fa2de1b79154 | 175 | |
Azure.IoT Build | 0:fa2de1b79154 | 176 | /* 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 | 177 | HTTP_HEADERS_RESULT HTTPHeaders_ReplaceHeaderNameValuePair(HTTP_HEADERS_HANDLE httpHeadersHandle, const char* name, const char* value) |
Azure.IoT Build | 0:fa2de1b79154 | 178 | { |
Azure.IoT Build | 0:fa2de1b79154 | 179 | return headers_ReplaceHeaderNameValuePair(httpHeadersHandle, name, value, true); |
Azure.IoT Build | 0:fa2de1b79154 | 180 | } |
Azure.IoT Build | 0:fa2de1b79154 | 181 | |
Azure.IoT Build | 0:fa2de1b79154 | 182 | |
Azure.IoT Build | 0:fa2de1b79154 | 183 | const char* HTTPHeaders_FindHeaderValue(HTTP_HEADERS_HANDLE httpHeadersHandle, const char* name) |
Azure.IoT Build | 0:fa2de1b79154 | 184 | { |
Azure.IoT Build | 0:fa2de1b79154 | 185 | const char* result; |
Azure.IoT Build | 0:fa2de1b79154 | 186 | /*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 | 187 | if ( |
Azure.IoT Build | 0:fa2de1b79154 | 188 | (httpHeadersHandle == NULL) || |
Azure.IoT Build | 0:fa2de1b79154 | 189 | (name == NULL) |
Azure.IoT Build | 0:fa2de1b79154 | 190 | ) |
Azure.IoT Build | 0:fa2de1b79154 | 191 | { |
Azure.IoT Build | 0:fa2de1b79154 | 192 | result = NULL; |
Azure.IoT Build | 0:fa2de1b79154 | 193 | } |
Azure.IoT Build | 0:fa2de1b79154 | 194 | else |
Azure.IoT Build | 0:fa2de1b79154 | 195 | { |
Azure.IoT Build | 0:fa2de1b79154 | 196 | /*Codes_SRS_HTTP_HEADERS_99_018:[ Calling this API shall retrieve the value for a previously stored name.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 197 | /*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 | 198 | /*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 | 199 | HTTP_HEADERS_HANDLE_DATA* handleData = (HTTP_HEADERS_HANDLE_DATA*)httpHeadersHandle; |
Azure.IoT Build | 0:fa2de1b79154 | 200 | result = Map_GetValueFromKey(handleData->headers, name); |
Azure.IoT Build | 0:fa2de1b79154 | 201 | } |
Azure.IoT Build | 0:fa2de1b79154 | 202 | return result; |
Azure.IoT Build | 0:fa2de1b79154 | 203 | |
Azure.IoT Build | 0:fa2de1b79154 | 204 | } |
Azure.IoT Build | 0:fa2de1b79154 | 205 | |
Azure.IoT Build | 0:fa2de1b79154 | 206 | HTTP_HEADERS_RESULT HTTPHeaders_GetHeaderCount(HTTP_HEADERS_HANDLE handle, size_t* headerCount) |
Azure.IoT Build | 0:fa2de1b79154 | 207 | { |
Azure.IoT Build | 0:fa2de1b79154 | 208 | HTTP_HEADERS_RESULT result; |
Azure.IoT Build | 0:fa2de1b79154 | 209 | /*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 | 210 | /*Codes_SRS_HTTP_HEADERS_99_025:[ The function shall return HTTP_HEADERS_INVALID_ARG when headersCount is NULL.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 211 | if ((handle == NULL) || |
Azure.IoT Build | 0:fa2de1b79154 | 212 | (headerCount == NULL)) |
Azure.IoT Build | 0:fa2de1b79154 | 213 | { |
Azure.IoT Build | 0:fa2de1b79154 | 214 | result = HTTP_HEADERS_INVALID_ARG; |
AzureIoTClient | 1:9190c0f4d23a | 215 | LogError("(result = %s)", ENUM_TO_STRING(HTTP_HEADERS_RESULT, result)); |
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 | HTTP_HEADERS_HANDLE_DATA *handleData = (HTTP_HEADERS_HANDLE_DATA *)handle; |
Azure.IoT Build | 0:fa2de1b79154 | 220 | const char*const* keys; |
Azure.IoT Build | 0:fa2de1b79154 | 221 | const char*const* values; |
Azure.IoT Build | 0:fa2de1b79154 | 222 | /*Codes_SRS_HTTP_HEADERS_99_023:[ Calling this API shall provide the number of stored headers.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 223 | if (Map_GetInternals(handleData->headers, &keys, &values, headerCount) != MAP_OK) |
Azure.IoT Build | 0:fa2de1b79154 | 224 | { |
Azure.IoT Build | 0:fa2de1b79154 | 225 | /*Codes_SRS_HTTP_HEADERS_99_037:[ The function shall return HTTP_HEADERS_ERROR when an internal error occurs.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 226 | result = HTTP_HEADERS_ERROR; |
AzureIoTClient | 1:9190c0f4d23a | 227 | LogError("Map_GetInternals failed, result= %s", ENUM_TO_STRING(HTTP_HEADERS_RESULT, result)); |
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_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 | 232 | result = HTTP_HEADERS_OK; |
Azure.IoT Build | 0:fa2de1b79154 | 233 | } |
Azure.IoT Build | 0:fa2de1b79154 | 234 | } |
Azure.IoT Build | 0:fa2de1b79154 | 235 | |
Azure.IoT Build | 0:fa2de1b79154 | 236 | return result; |
Azure.IoT Build | 0:fa2de1b79154 | 237 | } |
Azure.IoT Build | 0:fa2de1b79154 | 238 | |
Azure.IoT Build | 0:fa2de1b79154 | 239 | /*produces a string in *destination that is equal to name: value*/ |
Azure.IoT Build | 0:fa2de1b79154 | 240 | HTTP_HEADERS_RESULT HTTPHeaders_GetHeader(HTTP_HEADERS_HANDLE handle, size_t index, char** destination) |
Azure.IoT Build | 0:fa2de1b79154 | 241 | { |
Azure.IoT Build | 0:fa2de1b79154 | 242 | HTTP_HEADERS_RESULT result = HTTP_HEADERS_OK; |
Azure.IoT Build | 0:fa2de1b79154 | 243 | |
Azure.IoT Build | 0:fa2de1b79154 | 244 | /*Codes_SRS_HTTP_HEADERS_99_028:[ The function shall return NULL if the handle is invalid.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 245 | /*Codes_SRS_HTTP_HEADERS_99_032:[ The function shall return HTTP_HEADERS_INVALID_ARG if the destination is NULL]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 246 | if ( |
Azure.IoT Build | 0:fa2de1b79154 | 247 | (handle == NULL) || |
Azure.IoT Build | 0:fa2de1b79154 | 248 | (destination == NULL) |
Azure.IoT Build | 0:fa2de1b79154 | 249 | ) |
Azure.IoT Build | 0:fa2de1b79154 | 250 | { |
Azure.IoT Build | 0:fa2de1b79154 | 251 | result = HTTP_HEADERS_INVALID_ARG; |
AzureIoTClient | 1:9190c0f4d23a | 252 | LogError("invalid arg (NULL), result= %s", ENUM_TO_STRING(HTTP_HEADERS_RESULT, result)); |
Azure.IoT Build | 0:fa2de1b79154 | 253 | } |
Azure.IoT Build | 0:fa2de1b79154 | 254 | /*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 | 255 | else |
Azure.IoT Build | 0:fa2de1b79154 | 256 | { |
Azure.IoT Build | 0:fa2de1b79154 | 257 | HTTP_HEADERS_HANDLE_DATA* handleData = (HTTP_HEADERS_HANDLE_DATA*)handle; |
Azure.IoT Build | 0:fa2de1b79154 | 258 | const char*const* keys; |
Azure.IoT Build | 0:fa2de1b79154 | 259 | const char*const* values; |
Azure.IoT Build | 0:fa2de1b79154 | 260 | size_t headerCount; |
Azure.IoT Build | 0:fa2de1b79154 | 261 | if (Map_GetInternals(handleData->headers, &keys, &values, &headerCount) != MAP_OK) |
Azure.IoT Build | 0:fa2de1b79154 | 262 | { |
Azure.IoT Build | 0:fa2de1b79154 | 263 | /*Codes_SRS_HTTP_HEADERS_99_034:[ The function shall return HTTP_HEADERS_ERROR when an internal error occurs]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 264 | result = HTTP_HEADERS_ERROR; |
AzureIoTClient | 1:9190c0f4d23a | 265 | LogError("Map_GetInternals failed, result= %s", ENUM_TO_STRING(HTTP_HEADERS_RESULT, result)); |
Azure.IoT Build | 0:fa2de1b79154 | 266 | } |
Azure.IoT Build | 0:fa2de1b79154 | 267 | else |
Azure.IoT Build | 0:fa2de1b79154 | 268 | { |
Azure.IoT Build | 0:fa2de1b79154 | 269 | /*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 | 270 | if (index >= headerCount) |
Azure.IoT Build | 0:fa2de1b79154 | 271 | { |
Azure.IoT Build | 0:fa2de1b79154 | 272 | result = HTTP_HEADERS_INVALID_ARG; |
AzureIoTClient | 1:9190c0f4d23a | 273 | LogError("index out of bounds, result= %s", ENUM_TO_STRING(HTTP_HEADERS_RESULT, result)); |
Azure.IoT Build | 0:fa2de1b79154 | 274 | } |
Azure.IoT Build | 0:fa2de1b79154 | 275 | else |
Azure.IoT Build | 0:fa2de1b79154 | 276 | { |
AzureIoTClient | 11:77df6d7e65ae | 277 | size_t keyLen = strlen(keys[index]); |
AzureIoTClient | 11:77df6d7e65ae | 278 | size_t valueLen = strlen(values[index]); |
AzureIoTClient | 11:77df6d7e65ae | 279 | *destination = (char*)malloc(sizeof(char) * (keyLen + /*COLON_AND_SPACE_LENGTH*/ 2 + valueLen + /*EOL*/ 1)); |
Azure.IoT Build | 0:fa2de1b79154 | 280 | if (*destination == NULL) |
Azure.IoT Build | 0:fa2de1b79154 | 281 | { |
Azure.IoT Build | 0:fa2de1b79154 | 282 | /*Codes_SRS_HTTP_HEADERS_99_034:[ The function shall return HTTP_HEADERS_ERROR when an internal error occurs]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 283 | result = HTTP_HEADERS_ERROR; |
AzureIoTClient | 1:9190c0f4d23a | 284 | LogError("unable to malloc, result= %s", ENUM_TO_STRING(HTTP_HEADERS_RESULT, result)); |
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 | /*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 | 289 | /*Codes_SRS_HTTP_HEADERS_99_027:[ Calling this API shall produce the string value+": "+pair) for the index header in the *destination parameter.]*/ |
AzureIoTClient | 11:77df6d7e65ae | 290 | char* runDestination = (*destination); |
AzureIoTClient | 11:77df6d7e65ae | 291 | (void)memcpy(runDestination, keys[index], keyLen); |
AzureIoTClient | 11:77df6d7e65ae | 292 | runDestination += keyLen; |
AzureIoTClient | 11:77df6d7e65ae | 293 | (*runDestination++) = ':'; |
AzureIoTClient | 11:77df6d7e65ae | 294 | (*runDestination++) = ' '; |
AzureIoTClient | 11:77df6d7e65ae | 295 | (void)memcpy(runDestination, values[index], valueLen + /*EOL*/ 1); |
Azure.IoT Build | 0:fa2de1b79154 | 296 | /*Codes_SRS_HTTP_HEADERS_99_035:[ The function shall return HTTP_HEADERS_OK when the function executed without error.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 297 | result = HTTP_HEADERS_OK; |
Azure.IoT Build | 0:fa2de1b79154 | 298 | } |
Azure.IoT Build | 0:fa2de1b79154 | 299 | } |
Azure.IoT Build | 0:fa2de1b79154 | 300 | } |
Azure.IoT Build | 0:fa2de1b79154 | 301 | } |
Azure.IoT Build | 0:fa2de1b79154 | 302 | |
Azure.IoT Build | 0:fa2de1b79154 | 303 | return result; |
Azure.IoT Build | 0:fa2de1b79154 | 304 | } |
Azure.IoT Build | 0:fa2de1b79154 | 305 | |
Azure.IoT Build | 0:fa2de1b79154 | 306 | HTTP_HEADERS_HANDLE HTTPHeaders_Clone(HTTP_HEADERS_HANDLE handle) |
Azure.IoT Build | 0:fa2de1b79154 | 307 | { |
Azure.IoT Build | 0:fa2de1b79154 | 308 | HTTP_HEADERS_HANDLE_DATA* result; |
Azure.IoT Build | 0:fa2de1b79154 | 309 | /*Codes_SRS_HTTP_HEADERS_02_003: [If handle is NULL then HTTPHeaders_Clone shall return NULL.] */ |
Azure.IoT Build | 0:fa2de1b79154 | 310 | if (handle == NULL) |
Azure.IoT Build | 0:fa2de1b79154 | 311 | { |
Azure.IoT Build | 0:fa2de1b79154 | 312 | result = NULL; |
Azure.IoT Build | 0:fa2de1b79154 | 313 | } |
Azure.IoT Build | 0:fa2de1b79154 | 314 | else |
Azure.IoT Build | 0:fa2de1b79154 | 315 | { |
Azure.IoT Build | 0:fa2de1b79154 | 316 | /*Codes_SRS_HTTP_HEADERS_02_004: [Otherwise HTTPHeaders_Clone shall clone the content of handle to a new handle.] */ |
Azure.IoT Build | 0:fa2de1b79154 | 317 | result = malloc(sizeof(HTTP_HEADERS_HANDLE_DATA)); |
Azure.IoT Build | 0:fa2de1b79154 | 318 | if (result == NULL) |
Azure.IoT Build | 0:fa2de1b79154 | 319 | { |
Azure.IoT Build | 0:fa2de1b79154 | 320 | /*Codes_SRS_HTTP_HEADERS_02_005: [If cloning fails for any reason, then HTTPHeaders_Clone shall return NULL.] */ |
Azure.IoT Build | 0:fa2de1b79154 | 321 | } |
Azure.IoT Build | 0:fa2de1b79154 | 322 | else |
Azure.IoT Build | 0:fa2de1b79154 | 323 | { |
Azure.IoT Build | 0:fa2de1b79154 | 324 | HTTP_HEADERS_HANDLE_DATA* handleData = handle; |
Azure.IoT Build | 0:fa2de1b79154 | 325 | result->headers = Map_Clone(handleData->headers); |
Azure.IoT Build | 0:fa2de1b79154 | 326 | if (result->headers == NULL) |
Azure.IoT Build | 0:fa2de1b79154 | 327 | { |
Azure.IoT Build | 0:fa2de1b79154 | 328 | /*Codes_SRS_HTTP_HEADERS_02_005: [If cloning fails for any reason, then HTTPHeaders_Clone shall return NULL.] */ |
Azure.IoT Build | 0:fa2de1b79154 | 329 | free(result); |
Azure.IoT Build | 0:fa2de1b79154 | 330 | result = NULL; |
Azure.IoT Build | 0:fa2de1b79154 | 331 | } |
Azure.IoT Build | 0:fa2de1b79154 | 332 | else |
Azure.IoT Build | 0:fa2de1b79154 | 333 | { |
Azure.IoT Build | 0:fa2de1b79154 | 334 | /*all is fine*/ |
Azure.IoT Build | 0:fa2de1b79154 | 335 | } |
Azure.IoT Build | 0:fa2de1b79154 | 336 | } |
Azure.IoT Build | 0:fa2de1b79154 | 337 | } |
Azure.IoT Build | 0:fa2de1b79154 | 338 | return result; |
Azure.IoT Build | 0:fa2de1b79154 | 339 | } |