Xin Zhang / azure-iot-c-sdk-f767zi

Dependents:   samplemqtt

Committer:
XinZhangMS
Date:
Thu Aug 23 06:52:14 2018 +0000
Revision:
0:f7f1f0d76dd6
azure-c-sdk for mbed os supporting NUCLEO_F767ZI

Who changed what in which revision?

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