Demo using MBED TLS

Dependencies:   EthernetInterface NTPClient iothub_amqp_transport iothub_client mbed-rtos mbed

Fork of iothub_client_sample_amqp by Azure IoT

Committer:
markrad
Date:
Thu Jan 05 00:20:03 2017 +0000
Revision:
58:f50b97b08851
Sample using MBED TLS

Who changed what in which revision?

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