Azure IoT common library
Fork of azure_c_shared_utility by
httpheaders.c@25:8507bf644fdf, 2017-04-21 (annotated)
- Committer:
- AzureIoTClient
- Date:
- Fri Apr 21 14:51:10 2017 -0700
- Revision:
- 25:8507bf644fdf
- Parent:
- 19:2e0811512ceb
1.1.13
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Azure.IoT Build | 0:fa2de1b79154 | 1 | // Copyright (c) Microsoft. All rights reserved. |
Azure.IoT Build | 0:fa2de1b79154 | 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. |
Azure.IoT Build | 0:fa2de1b79154 | 3 | |
Azure.IoT Build | 0:fa2de1b79154 | 4 | #include <stdlib.h> |
Azure.IoT Build | 0:fa2de1b79154 | 5 | #include "azure_c_shared_utility/gballoc.h" |
Azure.IoT Build | 0:fa2de1b79154 | 6 | #include "azure_c_shared_utility/map.h" |
Azure.IoT Build | 0:fa2de1b79154 | 7 | #include "azure_c_shared_utility/httpheaders.h" |
Azure.IoT Build | 0:fa2de1b79154 | 8 | #include <string.h> |
Azure.IoT Build | 0:fa2de1b79154 | 9 | #include "azure_c_shared_utility/crt_abstractions.h" |
Azure.IoT Build | 6:c55b013dfc2a | 10 | #include "azure_c_shared_utility/xlogging.h" |
Azure.IoT Build | 0:fa2de1b79154 | 11 | |
Azure.IoT Build | 0:fa2de1b79154 | 12 | DEFINE_ENUM_STRINGS(HTTP_HEADERS_RESULT, HTTP_HEADERS_RESULT_VALUES); |
Azure.IoT Build | 0:fa2de1b79154 | 13 | |
Azure.IoT Build | 0:fa2de1b79154 | 14 | typedef struct HTTP_HEADERS_HANDLE_DATA_TAG |
Azure.IoT Build | 0:fa2de1b79154 | 15 | { |
Azure.IoT Build | 0:fa2de1b79154 | 16 | MAP_HANDLE headers; |
Azure.IoT Build | 0:fa2de1b79154 | 17 | } HTTP_HEADERS_HANDLE_DATA; |
Azure.IoT Build | 0:fa2de1b79154 | 18 | |
Azure.IoT Build | 0:fa2de1b79154 | 19 | HTTP_HEADERS_HANDLE HTTPHeaders_Alloc(void) |
Azure.IoT Build | 0:fa2de1b79154 | 20 | { |
Azure.IoT Build | 0:fa2de1b79154 | 21 | /*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 | 22 | HTTP_HEADERS_HANDLE_DATA* result; |
Azure.IoT Build | 0:fa2de1b79154 | 23 | result = (HTTP_HEADERS_HANDLE_DATA*)malloc(sizeof(HTTP_HEADERS_HANDLE_DATA)); |
Azure.IoT Build | 0:fa2de1b79154 | 24 | |
Azure.IoT Build | 0:fa2de1b79154 | 25 | if (result == NULL) |
Azure.IoT Build | 0:fa2de1b79154 | 26 | { |
AzureIoTClient | 1:9190c0f4d23a | 27 | LogError("malloc failed"); |
Azure.IoT Build | 0:fa2de1b79154 | 28 | } |
Azure.IoT Build | 0:fa2de1b79154 | 29 | else |
Azure.IoT Build | 0:fa2de1b79154 | 30 | { |
Azure.IoT Build | 0:fa2de1b79154 | 31 | /*Codes_SRS_HTTP_HEADERS_99_004:[ After a successful init, HTTPHeaders_GetHeaderCount shall report 0 existing headers.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 32 | result->headers = Map_Create(NULL); |
Azure.IoT Build | 0:fa2de1b79154 | 33 | if (result->headers == NULL) |
Azure.IoT Build | 0:fa2de1b79154 | 34 | { |
AzureIoTClient | 1:9190c0f4d23a | 35 | LogError("Map_Create failed"); |
Azure.IoT Build | 0:fa2de1b79154 | 36 | free(result); |
Azure.IoT Build | 0:fa2de1b79154 | 37 | result = NULL; |
Azure.IoT Build | 0:fa2de1b79154 | 38 | } |
Azure.IoT Build | 0:fa2de1b79154 | 39 | else |
Azure.IoT Build | 0:fa2de1b79154 | 40 | { |
Azure.IoT Build | 0:fa2de1b79154 | 41 | /*all is fine*/ |
Azure.IoT Build | 0:fa2de1b79154 | 42 | } |
Azure.IoT Build | 0:fa2de1b79154 | 43 | } |
Azure.IoT Build | 0:fa2de1b79154 | 44 | |
Azure.IoT Build | 0:fa2de1b79154 | 45 | /*Codes_SRS_HTTP_HEADERS_99_003:[ The function shall return NULL when the function cannot execute properly]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 46 | return (HTTP_HEADERS_HANDLE)result; |
Azure.IoT Build | 0:fa2de1b79154 | 47 | } |
Azure.IoT Build | 0:fa2de1b79154 | 48 | |
Azure.IoT Build | 0:fa2de1b79154 | 49 | /*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 | 50 | void HTTPHeaders_Free(HTTP_HEADERS_HANDLE handle) |
Azure.IoT Build | 0:fa2de1b79154 | 51 | { |
Azure.IoT Build | 0:fa2de1b79154 | 52 | /*Codes_SRS_HTTP_HEADERS_02_001: [If httpHeadersHandle is NULL then HTTPHeaders_Free shall perform no action.] */ |
Azure.IoT Build | 0:fa2de1b79154 | 53 | if (handle == NULL) |
Azure.IoT Build | 0:fa2de1b79154 | 54 | { |
Azure.IoT Build | 0:fa2de1b79154 | 55 | /*do nothing*/ |
Azure.IoT Build | 0:fa2de1b79154 | 56 | } |
Azure.IoT Build | 0:fa2de1b79154 | 57 | else |
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 | HTTP_HEADERS_HANDLE_DATA* handleData = (HTTP_HEADERS_HANDLE_DATA*)handle; |
Azure.IoT Build | 0:fa2de1b79154 | 61 | |
Azure.IoT Build | 0:fa2de1b79154 | 62 | Map_Destroy(handleData->headers); |
Azure.IoT Build | 0:fa2de1b79154 | 63 | free(handleData); |
Azure.IoT Build | 0:fa2de1b79154 | 64 | } |
Azure.IoT Build | 0:fa2de1b79154 | 65 | } |
Azure.IoT Build | 0:fa2de1b79154 | 66 | |
Azure.IoT Build | 0:fa2de1b79154 | 67 | /*Codes_SRS_HTTP_HEADERS_99_012:[ Calling this API shall record a header from name and value parameters.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 68 | static HTTP_HEADERS_RESULT headers_ReplaceHeaderNameValuePair(HTTP_HEADERS_HANDLE handle, const char* name, const char* value, bool replace) |
Azure.IoT Build | 0:fa2de1b79154 | 69 | { |
Azure.IoT Build | 0:fa2de1b79154 | 70 | HTTP_HEADERS_RESULT result; |
Azure.IoT Build | 0:fa2de1b79154 | 71 | /*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 | 72 | if ( |
Azure.IoT Build | 0:fa2de1b79154 | 73 | (handle == NULL) || |
Azure.IoT Build | 0:fa2de1b79154 | 74 | (name == NULL) || |
Azure.IoT Build | 0:fa2de1b79154 | 75 | (value == NULL) |
Azure.IoT Build | 0:fa2de1b79154 | 76 | ) |
Azure.IoT Build | 0:fa2de1b79154 | 77 | { |
Azure.IoT Build | 0:fa2de1b79154 | 78 | result = HTTP_HEADERS_INVALID_ARG; |
AzureIoTClient | 1:9190c0f4d23a | 79 | LogError("invalid arg (NULL) , result= %s", ENUM_TO_STRING(HTTP_HEADERS_RESULT, result)); |
Azure.IoT Build | 0:fa2de1b79154 | 80 | } |
Azure.IoT Build | 0:fa2de1b79154 | 81 | else |
Azure.IoT Build | 0:fa2de1b79154 | 82 | { |
Azure.IoT Build | 0:fa2de1b79154 | 83 | /*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 | 84 | /*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 | 85 | size_t i; |
Azure.IoT Build | 0:fa2de1b79154 | 86 | size_t nameLen = strlen(name); |
Azure.IoT Build | 0:fa2de1b79154 | 87 | for (i = 0; i < nameLen; i++) |
Azure.IoT Build | 0:fa2de1b79154 | 88 | { |
Azure.IoT Build | 0:fa2de1b79154 | 89 | if ((name[i] < 33) || (126 < name[i]) || (name[i] == ':')) |
Azure.IoT Build | 0:fa2de1b79154 | 90 | { |
Azure.IoT Build | 0:fa2de1b79154 | 91 | break; |
Azure.IoT Build | 0:fa2de1b79154 | 92 | } |
Azure.IoT Build | 0:fa2de1b79154 | 93 | } |
Azure.IoT Build | 0:fa2de1b79154 | 94 | |
Azure.IoT Build | 0:fa2de1b79154 | 95 | if (i < nameLen) |
Azure.IoT Build | 0:fa2de1b79154 | 96 | { |
Azure.IoT Build | 0:fa2de1b79154 | 97 | result = HTTP_HEADERS_INVALID_ARG; |
AzureIoTClient | 1:9190c0f4d23a | 98 | LogError("(result = %s)", ENUM_TO_STRING(HTTP_HEADERS_RESULT, result)); |
Azure.IoT Build | 0:fa2de1b79154 | 99 | } |
Azure.IoT Build | 0:fa2de1b79154 | 100 | else |
Azure.IoT Build | 0:fa2de1b79154 | 101 | { |
Azure.IoT Build | 0:fa2de1b79154 | 102 | HTTP_HEADERS_HANDLE_DATA* handleData = (HTTP_HEADERS_HANDLE_DATA*)handle; |
Azure.IoT Build | 0:fa2de1b79154 | 103 | const char* existingValue = Map_GetValueFromKey(handleData->headers, name); |
Azure.IoT Build | 0:fa2de1b79154 | 104 | /*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 | 105 | /*Codes_SRS_HTTP_HEADERS_02_002: [The LWS from the beginning of the value shall not be stored.] */ |
Azure.IoT Build | 0:fa2de1b79154 | 106 | while ((value[0] == ' ') || (value[0] == '\t') || (value[0] == '\r') || (value[0] == '\n')) |
Azure.IoT Build | 0:fa2de1b79154 | 107 | { |
Azure.IoT Build | 0:fa2de1b79154 | 108 | value++; |
Azure.IoT Build | 0:fa2de1b79154 | 109 | } |
Azure.IoT Build | 0:fa2de1b79154 | 110 | |
Azure.IoT Build | 0:fa2de1b79154 | 111 | if (!replace && (existingValue != NULL)) |
Azure.IoT Build | 0:fa2de1b79154 | 112 | { |
AzureIoTClient | 11:77df6d7e65ae | 113 | size_t existingValueLen = strlen(existingValue); |
AzureIoTClient | 11:77df6d7e65ae | 114 | size_t valueLen = strlen(value); |
AzureIoTClient | 11:77df6d7e65ae | 115 | char* newValue = (char*)malloc(sizeof(char) * (existingValueLen + /*COMMA_AND_SPACE_LENGTH*/ 2 + valueLen + /*EOL*/ 1)); |
Azure.IoT Build | 0:fa2de1b79154 | 116 | if (newValue == NULL) |
Azure.IoT Build | 0:fa2de1b79154 | 117 | { |
Azure.IoT Build | 0:fa2de1b79154 | 118 | /*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 | 119 | result = HTTP_HEADERS_ALLOC_FAILED; |
AzureIoTClient | 1:9190c0f4d23a | 120 | LogError("failed to malloc , result= %s", ENUM_TO_STRING(HTTP_HEADERS_RESULT, result)); |
Azure.IoT Build | 0:fa2de1b79154 | 121 | } |
Azure.IoT Build | 0:fa2de1b79154 | 122 | else |
Azure.IoT Build | 0:fa2de1b79154 | 123 | { |
AzureIoTClient | 11:77df6d7e65ae | 124 | char* runNewValue; |
Azure.IoT Build | 0:fa2de1b79154 | 125 | /*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 | 126 | (void)memcpy(newValue, existingValue, existingValueLen); |
AzureIoTClient | 11:77df6d7e65ae | 127 | runNewValue = newValue + existingValueLen; |
AzureIoTClient | 11:77df6d7e65ae | 128 | (*runNewValue++) = ','; |
AzureIoTClient | 11:77df6d7e65ae | 129 | (*runNewValue++) = ' '; |
AzureIoTClient | 11:77df6d7e65ae | 130 | (void)memcpy(runNewValue, value, valueLen + /*EOL*/ 1); |
Azure.IoT Build | 0:fa2de1b79154 | 131 | |
Azure.IoT Build | 0:fa2de1b79154 | 132 | /*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 | 133 | if (Map_AddOrUpdate(handleData->headers, name, newValue) != MAP_OK) |
Azure.IoT Build | 0:fa2de1b79154 | 134 | { |
Azure.IoT Build | 0:fa2de1b79154 | 135 | /*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 | 136 | result = HTTP_HEADERS_ERROR; |
AzureIoTClient | 1:9190c0f4d23a | 137 | LogError("failed to Map_AddOrUpdate, result= %s", ENUM_TO_STRING(HTTP_HEADERS_RESULT, result)); |
Azure.IoT Build | 0:fa2de1b79154 | 138 | } |
Azure.IoT Build | 0:fa2de1b79154 | 139 | else |
Azure.IoT Build | 0:fa2de1b79154 | 140 | { |
Azure.IoT Build | 0:fa2de1b79154 | 141 | /*Codes_SRS_HTTP_HEADERS_99_013:[ The function shall return HTTP_HEADERS_OK when execution is successful.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 142 | result = HTTP_HEADERS_OK; |
Azure.IoT Build | 0:fa2de1b79154 | 143 | } |
Azure.IoT Build | 0:fa2de1b79154 | 144 | free(newValue); |
Azure.IoT Build | 0:fa2de1b79154 | 145 | } |
Azure.IoT Build | 0:fa2de1b79154 | 146 | } |
Azure.IoT Build | 0:fa2de1b79154 | 147 | else |
Azure.IoT Build | 0:fa2de1b79154 | 148 | { |
Azure.IoT Build | 0:fa2de1b79154 | 149 | /*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 | 150 | if (Map_AddOrUpdate(handleData->headers, name, value) != MAP_OK) |
Azure.IoT Build | 0:fa2de1b79154 | 151 | { |
Azure.IoT Build | 0:fa2de1b79154 | 152 | /*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 | 153 | result = HTTP_HEADERS_ALLOC_FAILED; |
AzureIoTClient | 1:9190c0f4d23a | 154 | LogError("failed to Map_AddOrUpdate, result= %s", ENUM_TO_STRING(HTTP_HEADERS_RESULT, result)); |
Azure.IoT Build | 0:fa2de1b79154 | 155 | } |
Azure.IoT Build | 0:fa2de1b79154 | 156 | else |
Azure.IoT Build | 0:fa2de1b79154 | 157 | { |
Azure.IoT Build | 0:fa2de1b79154 | 158 | result = HTTP_HEADERS_OK; |
Azure.IoT Build | 0:fa2de1b79154 | 159 | } |
Azure.IoT Build | 0:fa2de1b79154 | 160 | } |
Azure.IoT Build | 0:fa2de1b79154 | 161 | } |
Azure.IoT Build | 0:fa2de1b79154 | 162 | } |
Azure.IoT Build | 0:fa2de1b79154 | 163 | |
Azure.IoT Build | 0:fa2de1b79154 | 164 | return result; |
Azure.IoT Build | 0:fa2de1b79154 | 165 | } |
Azure.IoT Build | 0:fa2de1b79154 | 166 | |
Azure.IoT Build | 0:fa2de1b79154 | 167 | HTTP_HEADERS_RESULT HTTPHeaders_AddHeaderNameValuePair(HTTP_HEADERS_HANDLE httpHeadersHandle, const char* name, const char* value) |
Azure.IoT Build | 0:fa2de1b79154 | 168 | { |
Azure.IoT Build | 0:fa2de1b79154 | 169 | return headers_ReplaceHeaderNameValuePair(httpHeadersHandle, name, value, false); |
Azure.IoT Build | 0:fa2de1b79154 | 170 | } |
Azure.IoT Build | 0:fa2de1b79154 | 171 | |
Azure.IoT Build | 0:fa2de1b79154 | 172 | /* 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 | 173 | HTTP_HEADERS_RESULT HTTPHeaders_ReplaceHeaderNameValuePair(HTTP_HEADERS_HANDLE httpHeadersHandle, const char* name, const char* value) |
Azure.IoT Build | 0:fa2de1b79154 | 174 | { |
Azure.IoT Build | 0:fa2de1b79154 | 175 | return headers_ReplaceHeaderNameValuePair(httpHeadersHandle, name, value, true); |
Azure.IoT Build | 0:fa2de1b79154 | 176 | } |
Azure.IoT Build | 0:fa2de1b79154 | 177 | |
Azure.IoT Build | 0:fa2de1b79154 | 178 | |
Azure.IoT Build | 0:fa2de1b79154 | 179 | const char* HTTPHeaders_FindHeaderValue(HTTP_HEADERS_HANDLE httpHeadersHandle, const char* name) |
Azure.IoT Build | 0:fa2de1b79154 | 180 | { |
Azure.IoT Build | 0:fa2de1b79154 | 181 | const char* result; |
Azure.IoT Build | 0:fa2de1b79154 | 182 | /*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 | 183 | if ( |
Azure.IoT Build | 0:fa2de1b79154 | 184 | (httpHeadersHandle == NULL) || |
Azure.IoT Build | 0:fa2de1b79154 | 185 | (name == NULL) |
Azure.IoT Build | 0:fa2de1b79154 | 186 | ) |
Azure.IoT Build | 0:fa2de1b79154 | 187 | { |
Azure.IoT Build | 0:fa2de1b79154 | 188 | result = NULL; |
Azure.IoT Build | 0:fa2de1b79154 | 189 | } |
Azure.IoT Build | 0:fa2de1b79154 | 190 | else |
Azure.IoT Build | 0:fa2de1b79154 | 191 | { |
Azure.IoT Build | 0:fa2de1b79154 | 192 | /*Codes_SRS_HTTP_HEADERS_99_018:[ Calling this API shall retrieve the value for a previously stored name.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 193 | /*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 | 194 | /*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 | 195 | HTTP_HEADERS_HANDLE_DATA* handleData = (HTTP_HEADERS_HANDLE_DATA*)httpHeadersHandle; |
Azure.IoT Build | 0:fa2de1b79154 | 196 | result = Map_GetValueFromKey(handleData->headers, name); |
Azure.IoT Build | 0:fa2de1b79154 | 197 | } |
Azure.IoT Build | 0:fa2de1b79154 | 198 | return result; |
Azure.IoT Build | 0:fa2de1b79154 | 199 | |
Azure.IoT Build | 0:fa2de1b79154 | 200 | } |
Azure.IoT Build | 0:fa2de1b79154 | 201 | |
Azure.IoT Build | 0:fa2de1b79154 | 202 | HTTP_HEADERS_RESULT HTTPHeaders_GetHeaderCount(HTTP_HEADERS_HANDLE handle, size_t* headerCount) |
Azure.IoT Build | 0:fa2de1b79154 | 203 | { |
Azure.IoT Build | 0:fa2de1b79154 | 204 | HTTP_HEADERS_RESULT result; |
Azure.IoT Build | 0:fa2de1b79154 | 205 | /*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 | 206 | /*Codes_SRS_HTTP_HEADERS_99_025:[ The function shall return HTTP_HEADERS_INVALID_ARG when headersCount is NULL.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 207 | if ((handle == NULL) || |
Azure.IoT Build | 0:fa2de1b79154 | 208 | (headerCount == NULL)) |
Azure.IoT Build | 0:fa2de1b79154 | 209 | { |
Azure.IoT Build | 0:fa2de1b79154 | 210 | result = HTTP_HEADERS_INVALID_ARG; |
AzureIoTClient | 1:9190c0f4d23a | 211 | LogError("(result = %s)", ENUM_TO_STRING(HTTP_HEADERS_RESULT, result)); |
Azure.IoT Build | 0:fa2de1b79154 | 212 | } |
Azure.IoT Build | 0:fa2de1b79154 | 213 | else |
Azure.IoT Build | 0:fa2de1b79154 | 214 | { |
Azure.IoT Build | 0:fa2de1b79154 | 215 | HTTP_HEADERS_HANDLE_DATA *handleData = (HTTP_HEADERS_HANDLE_DATA *)handle; |
Azure.IoT Build | 0:fa2de1b79154 | 216 | const char*const* keys; |
Azure.IoT Build | 0:fa2de1b79154 | 217 | const char*const* values; |
Azure.IoT Build | 0:fa2de1b79154 | 218 | /*Codes_SRS_HTTP_HEADERS_99_023:[ Calling this API shall provide the number of stored headers.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 219 | if (Map_GetInternals(handleData->headers, &keys, &values, headerCount) != MAP_OK) |
Azure.IoT Build | 0:fa2de1b79154 | 220 | { |
Azure.IoT Build | 0:fa2de1b79154 | 221 | /*Codes_SRS_HTTP_HEADERS_99_037:[ The function shall return HTTP_HEADERS_ERROR when an internal error occurs.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 222 | result = HTTP_HEADERS_ERROR; |
AzureIoTClient | 1:9190c0f4d23a | 223 | LogError("Map_GetInternals failed, result= %s", ENUM_TO_STRING(HTTP_HEADERS_RESULT, result)); |
Azure.IoT Build | 0:fa2de1b79154 | 224 | } |
Azure.IoT Build | 0:fa2de1b79154 | 225 | else |
Azure.IoT Build | 0:fa2de1b79154 | 226 | { |
Azure.IoT Build | 0:fa2de1b79154 | 227 | /*Codes_SRS_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 | 228 | result = HTTP_HEADERS_OK; |
Azure.IoT Build | 0:fa2de1b79154 | 229 | } |
Azure.IoT Build | 0:fa2de1b79154 | 230 | } |
Azure.IoT Build | 0:fa2de1b79154 | 231 | |
Azure.IoT Build | 0:fa2de1b79154 | 232 | return result; |
Azure.IoT Build | 0:fa2de1b79154 | 233 | } |
Azure.IoT Build | 0:fa2de1b79154 | 234 | |
Azure.IoT Build | 0:fa2de1b79154 | 235 | /*produces a string in *destination that is equal to name: value*/ |
Azure.IoT Build | 0:fa2de1b79154 | 236 | HTTP_HEADERS_RESULT HTTPHeaders_GetHeader(HTTP_HEADERS_HANDLE handle, size_t index, char** destination) |
Azure.IoT Build | 0:fa2de1b79154 | 237 | { |
Azure.IoT Build | 0:fa2de1b79154 | 238 | HTTP_HEADERS_RESULT result = HTTP_HEADERS_OK; |
Azure.IoT Build | 0:fa2de1b79154 | 239 | |
Azure.IoT Build | 0:fa2de1b79154 | 240 | /*Codes_SRS_HTTP_HEADERS_99_028:[ The function shall return NULL if the handle is invalid.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 241 | /*Codes_SRS_HTTP_HEADERS_99_032:[ The function shall return HTTP_HEADERS_INVALID_ARG if the destination is NULL]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 242 | if ( |
Azure.IoT Build | 0:fa2de1b79154 | 243 | (handle == NULL) || |
Azure.IoT Build | 0:fa2de1b79154 | 244 | (destination == NULL) |
Azure.IoT Build | 0:fa2de1b79154 | 245 | ) |
Azure.IoT Build | 0:fa2de1b79154 | 246 | { |
Azure.IoT Build | 0:fa2de1b79154 | 247 | result = HTTP_HEADERS_INVALID_ARG; |
AzureIoTClient | 1:9190c0f4d23a | 248 | LogError("invalid arg (NULL), result= %s", ENUM_TO_STRING(HTTP_HEADERS_RESULT, result)); |
Azure.IoT Build | 0:fa2de1b79154 | 249 | } |
Azure.IoT Build | 0:fa2de1b79154 | 250 | /*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 | 251 | else |
Azure.IoT Build | 0:fa2de1b79154 | 252 | { |
Azure.IoT Build | 0:fa2de1b79154 | 253 | HTTP_HEADERS_HANDLE_DATA* handleData = (HTTP_HEADERS_HANDLE_DATA*)handle; |
Azure.IoT Build | 0:fa2de1b79154 | 254 | const char*const* keys; |
Azure.IoT Build | 0:fa2de1b79154 | 255 | const char*const* values; |
Azure.IoT Build | 0:fa2de1b79154 | 256 | size_t headerCount; |
Azure.IoT Build | 0:fa2de1b79154 | 257 | if (Map_GetInternals(handleData->headers, &keys, &values, &headerCount) != MAP_OK) |
Azure.IoT Build | 0:fa2de1b79154 | 258 | { |
Azure.IoT Build | 0:fa2de1b79154 | 259 | /*Codes_SRS_HTTP_HEADERS_99_034:[ The function shall return HTTP_HEADERS_ERROR when an internal error occurs]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 260 | result = HTTP_HEADERS_ERROR; |
AzureIoTClient | 1:9190c0f4d23a | 261 | LogError("Map_GetInternals failed, result= %s", ENUM_TO_STRING(HTTP_HEADERS_RESULT, result)); |
Azure.IoT Build | 0:fa2de1b79154 | 262 | } |
Azure.IoT Build | 0:fa2de1b79154 | 263 | else |
Azure.IoT Build | 0:fa2de1b79154 | 264 | { |
Azure.IoT Build | 0:fa2de1b79154 | 265 | /*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 | 266 | if (index >= headerCount) |
Azure.IoT Build | 0:fa2de1b79154 | 267 | { |
Azure.IoT Build | 0:fa2de1b79154 | 268 | result = HTTP_HEADERS_INVALID_ARG; |
AzureIoTClient | 1:9190c0f4d23a | 269 | LogError("index out of bounds, result= %s", ENUM_TO_STRING(HTTP_HEADERS_RESULT, result)); |
Azure.IoT Build | 0:fa2de1b79154 | 270 | } |
Azure.IoT Build | 0:fa2de1b79154 | 271 | else |
Azure.IoT Build | 0:fa2de1b79154 | 272 | { |
AzureIoTClient | 11:77df6d7e65ae | 273 | size_t keyLen = strlen(keys[index]); |
AzureIoTClient | 11:77df6d7e65ae | 274 | size_t valueLen = strlen(values[index]); |
AzureIoTClient | 11:77df6d7e65ae | 275 | *destination = (char*)malloc(sizeof(char) * (keyLen + /*COLON_AND_SPACE_LENGTH*/ 2 + valueLen + /*EOL*/ 1)); |
Azure.IoT Build | 0:fa2de1b79154 | 276 | if (*destination == NULL) |
Azure.IoT Build | 0:fa2de1b79154 | 277 | { |
Azure.IoT Build | 0:fa2de1b79154 | 278 | /*Codes_SRS_HTTP_HEADERS_99_034:[ The function shall return HTTP_HEADERS_ERROR when an internal error occurs]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 279 | result = HTTP_HEADERS_ERROR; |
AzureIoTClient | 1:9190c0f4d23a | 280 | LogError("unable to malloc, result= %s", ENUM_TO_STRING(HTTP_HEADERS_RESULT, result)); |
Azure.IoT Build | 0:fa2de1b79154 | 281 | } |
Azure.IoT Build | 0:fa2de1b79154 | 282 | else |
Azure.IoT Build | 0:fa2de1b79154 | 283 | { |
Azure.IoT Build | 0:fa2de1b79154 | 284 | /*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 | 285 | /*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 | 286 | char* runDestination = (*destination); |
AzureIoTClient | 11:77df6d7e65ae | 287 | (void)memcpy(runDestination, keys[index], keyLen); |
AzureIoTClient | 11:77df6d7e65ae | 288 | runDestination += keyLen; |
AzureIoTClient | 11:77df6d7e65ae | 289 | (*runDestination++) = ':'; |
AzureIoTClient | 11:77df6d7e65ae | 290 | (*runDestination++) = ' '; |
AzureIoTClient | 11:77df6d7e65ae | 291 | (void)memcpy(runDestination, values[index], valueLen + /*EOL*/ 1); |
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.] */ |
AzureIoTClient | 25:8507bf644fdf | 313 | result = (HTTP_HEADERS_HANDLE_DATA*)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 | } |