Azure IoT common library

Dependents:   STM32F746_iothub_client_sample_mqtt f767zi_mqtt iothub_client_sample_amqp iothub_client_sample_http ... more

Committer:
AzureIoTClient
Date:
Thu Oct 04 09:17:16 2018 -0700
Revision:
49:6bb8b9a66642
Parent:
25:8507bf644fdf
1.2.10

Who changed what in which revision?

UserRevisionLine numberNew 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 }