Azure IoT common library

Dependents:   STM32F746_iothub_client_sample_mqtt f767zi_mqtt iothub_client_sample_amqp iothub_client_sample_http ... more

Committer:
Azure.IoT Build
Date:
Fri Apr 08 12:01:36 2016 -0700
Revision:
0:fa2de1b79154
Child:
1:9190c0f4d23a
1.0.4

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