Azure IoT common library

Fork of azure_c_shared_utility by Azure IoT

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?

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 #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 }