Azure IoT common library
Dependents: STM32F746_iothub_client_sample_mqtt f767zi_mqtt iothub_client_sample_amqp iothub_client_sample_http ... more
httpapiexsas.c@49:6bb8b9a66642, 2018-10-04 (annotated)
- Committer:
- AzureIoTClient
- Date:
- Thu Oct 04 09:17:16 2018 -0700
- Revision:
- 49:6bb8b9a66642
- Parent:
- 38:ed9c888e5e12
1.2.10
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Azure.IoT Build | 0:fa2de1b79154 | 1 | // Copyright (c) Microsoft. All rights reserved. |
Azure.IoT Build | 0:fa2de1b79154 | 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. |
Azure.IoT Build | 0:fa2de1b79154 | 3 | |
Azure.IoT Build | 0:fa2de1b79154 | 4 | #include <stdlib.h> |
Azure.IoT Build | 0:fa2de1b79154 | 5 | #include "azure_c_shared_utility/gballoc.h" |
Azure.IoT Build | 0:fa2de1b79154 | 6 | #include <stddef.h> |
Azure.IoT Build | 0:fa2de1b79154 | 7 | #include <time.h> |
Azure.IoT Build | 0:fa2de1b79154 | 8 | #include "azure_c_shared_utility/agenttime.h" |
Azure.IoT Build | 0:fa2de1b79154 | 9 | #include "azure_c_shared_utility/strings.h" |
Azure.IoT Build | 0:fa2de1b79154 | 10 | #include "azure_c_shared_utility/buffer_.h" |
Azure.IoT Build | 0:fa2de1b79154 | 11 | #include "azure_c_shared_utility/sastoken.h" |
Azure.IoT Build | 0:fa2de1b79154 | 12 | #include "azure_c_shared_utility/httpheaders.h" |
Azure.IoT Build | 0:fa2de1b79154 | 13 | #include "azure_c_shared_utility/httpapiex.h" |
Azure.IoT Build | 0:fa2de1b79154 | 14 | #include "azure_c_shared_utility/httpapiexsas.h" |
Azure.IoT Build | 6:c55b013dfc2a | 15 | #include "azure_c_shared_utility/xlogging.h" |
AzureIoTClient | 38:ed9c888e5e12 | 16 | #include "azure_c_shared_utility/crt_abstractions.h" |
Azure.IoT Build | 0:fa2de1b79154 | 17 | |
Azure.IoT Build | 0:fa2de1b79154 | 18 | typedef struct HTTPAPIEX_SAS_STATE_TAG |
Azure.IoT Build | 0:fa2de1b79154 | 19 | { |
AzureIoTClient | 38:ed9c888e5e12 | 20 | char* key; |
AzureIoTClient | 38:ed9c888e5e12 | 21 | char* uriResource; |
AzureIoTClient | 38:ed9c888e5e12 | 22 | char* keyName; |
AzureIoTClient | 38:ed9c888e5e12 | 23 | } HTTPAPIEX_SAS_STATE; |
AzureIoTClient | 38:ed9c888e5e12 | 24 | |
AzureIoTClient | 38:ed9c888e5e12 | 25 | static HTTPAPIEX_SAS_STATE* construct_httpex_sas(const char* key, const char* uriResource, const char* keyName) |
AzureIoTClient | 38:ed9c888e5e12 | 26 | { |
AzureIoTClient | 38:ed9c888e5e12 | 27 | HTTPAPIEX_SAS_STATE* result; |
Azure.IoT Build | 0:fa2de1b79154 | 28 | |
AzureIoTClient | 38:ed9c888e5e12 | 29 | result = (HTTPAPIEX_SAS_STATE*)malloc(sizeof(HTTPAPIEX_SAS_STATE)); |
AzureIoTClient | 38:ed9c888e5e12 | 30 | if (result == NULL) |
AzureIoTClient | 38:ed9c888e5e12 | 31 | { |
AzureIoTClient | 38:ed9c888e5e12 | 32 | LogError("Failure allocating HTTPAPIEX_SAS_Create."); |
AzureIoTClient | 38:ed9c888e5e12 | 33 | } |
AzureIoTClient | 38:ed9c888e5e12 | 34 | else |
AzureIoTClient | 38:ed9c888e5e12 | 35 | { |
AzureIoTClient | 38:ed9c888e5e12 | 36 | (void)memset(result, 0, sizeof(HTTPAPIEX_SAS_STATE)); |
AzureIoTClient | 38:ed9c888e5e12 | 37 | if (mallocAndStrcpy_s(&result->key, key) != 0) |
AzureIoTClient | 38:ed9c888e5e12 | 38 | { |
AzureIoTClient | 38:ed9c888e5e12 | 39 | /*Codes_SRS_HTTPAPIEXSAS_06_004: [If there are any other errors in the instantiation of this handle then HTTPAPIEX_SAS_Create shall return NULL.]*/ |
AzureIoTClient | 38:ed9c888e5e12 | 40 | LogError("Failure allocating sas key."); |
AzureIoTClient | 38:ed9c888e5e12 | 41 | HTTPAPIEX_SAS_Destroy(result); |
AzureIoTClient | 38:ed9c888e5e12 | 42 | result = NULL; |
AzureIoTClient | 38:ed9c888e5e12 | 43 | } |
AzureIoTClient | 38:ed9c888e5e12 | 44 | else if (mallocAndStrcpy_s(&result->uriResource, uriResource) != 0) |
AzureIoTClient | 38:ed9c888e5e12 | 45 | { |
AzureIoTClient | 38:ed9c888e5e12 | 46 | /*Codes_SRS_HTTPAPIEXSAS_06_004: [If there are any other errors in the instantiation of this handle then HTTPAPIEX_SAS_Create shall return NULL.]*/ |
AzureIoTClient | 38:ed9c888e5e12 | 47 | LogError("Failure allocating sas uriResource."); |
AzureIoTClient | 38:ed9c888e5e12 | 48 | HTTPAPIEX_SAS_Destroy(result); |
AzureIoTClient | 38:ed9c888e5e12 | 49 | result = NULL; |
AzureIoTClient | 38:ed9c888e5e12 | 50 | } |
AzureIoTClient | 38:ed9c888e5e12 | 51 | else if (keyName != NULL && mallocAndStrcpy_s(&result->keyName, keyName) != 0) |
AzureIoTClient | 38:ed9c888e5e12 | 52 | { |
AzureIoTClient | 38:ed9c888e5e12 | 53 | /*Codes_SRS_HTTPAPIEXSAS_06_004: [If there are any other errors in the instantiation of this handle then HTTPAPIEX_SAS_Create shall return NULL.]*/ |
AzureIoTClient | 38:ed9c888e5e12 | 54 | LogError("Failure allocating sas keyName."); |
AzureIoTClient | 38:ed9c888e5e12 | 55 | HTTPAPIEX_SAS_Destroy(result); |
AzureIoTClient | 38:ed9c888e5e12 | 56 | result = NULL; |
AzureIoTClient | 38:ed9c888e5e12 | 57 | } |
AzureIoTClient | 38:ed9c888e5e12 | 58 | } |
AzureIoTClient | 38:ed9c888e5e12 | 59 | return result; |
AzureIoTClient | 38:ed9c888e5e12 | 60 | } |
AzureIoTClient | 38:ed9c888e5e12 | 61 | |
AzureIoTClient | 38:ed9c888e5e12 | 62 | HTTPAPIEX_SAS_HANDLE HTTPAPIEX_SAS_Create_From_String(const char* key, const char* uriResource, const char* keyName) |
AzureIoTClient | 38:ed9c888e5e12 | 63 | { |
AzureIoTClient | 38:ed9c888e5e12 | 64 | HTTPAPIEX_SAS_HANDLE result = NULL; |
AzureIoTClient | 38:ed9c888e5e12 | 65 | if (key == NULL || uriResource == NULL) |
AzureIoTClient | 38:ed9c888e5e12 | 66 | { |
AzureIoTClient | 38:ed9c888e5e12 | 67 | /* Codes_SRS_HTTPAPIEXSAS_07_001: [ If the parameter key or uriResource is NULL then HTTPAPIEX_SAS_Create_From_String shall return NULL. ] */ |
AzureIoTClient | 38:ed9c888e5e12 | 68 | LogError("Invalid parameter key: %p, uriResource: %p", key, uriResource); |
AzureIoTClient | 38:ed9c888e5e12 | 69 | result = NULL; |
AzureIoTClient | 38:ed9c888e5e12 | 70 | } |
AzureIoTClient | 38:ed9c888e5e12 | 71 | else |
AzureIoTClient | 38:ed9c888e5e12 | 72 | { |
AzureIoTClient | 38:ed9c888e5e12 | 73 | /* Codes_SRS_HTTPAPIEXSAS_07_002: [ If there are any other errors in the instantiation of this handle then HTTPAPIEX_SAS_Create_From_String shall return NULL. ] */ |
AzureIoTClient | 38:ed9c888e5e12 | 74 | result = construct_httpex_sas(key, uriResource, keyName); |
AzureIoTClient | 38:ed9c888e5e12 | 75 | } |
AzureIoTClient | 38:ed9c888e5e12 | 76 | /* Codes_SRS_HTTPAPIEXSAS_07_003: [ HTTPAPIEX_SAS_Create_From_String shall create a new instance of HTTPAPIEX_SAS and return a non-NULL handle to it ] */ |
AzureIoTClient | 38:ed9c888e5e12 | 77 | return result; |
AzureIoTClient | 38:ed9c888e5e12 | 78 | } |
Azure.IoT Build | 0:fa2de1b79154 | 79 | |
Azure.IoT Build | 0:fa2de1b79154 | 80 | HTTPAPIEX_SAS_HANDLE HTTPAPIEX_SAS_Create(STRING_HANDLE key, STRING_HANDLE uriResource, STRING_HANDLE keyName) |
Azure.IoT Build | 0:fa2de1b79154 | 81 | { |
Azure.IoT Build | 0:fa2de1b79154 | 82 | HTTPAPIEX_SAS_HANDLE result = NULL; |
Azure.IoT Build | 0:fa2de1b79154 | 83 | if (key == NULL) |
Azure.IoT Build | 0:fa2de1b79154 | 84 | { |
Azure.IoT Build | 0:fa2de1b79154 | 85 | /*Codes_SRS_HTTPAPIEXSAS_06_001: [If the parameter key is NULL then HTTPAPIEX_SAS_Create shall return NULL.]*/ |
AzureIoTClient | 1:9190c0f4d23a | 86 | LogError("No key passed to HTTPAPIEX_SAS_Create."); |
Azure.IoT Build | 0:fa2de1b79154 | 87 | } |
Azure.IoT Build | 0:fa2de1b79154 | 88 | else if (uriResource == NULL) |
Azure.IoT Build | 0:fa2de1b79154 | 89 | { |
Azure.IoT Build | 0:fa2de1b79154 | 90 | /*Codes_SRS_HTTPAPIEXSAS_06_002: [If the parameter uriResource is NULL then HTTPAPIEX_SAS_Create shall return NULL.]*/ |
AzureIoTClient | 1:9190c0f4d23a | 91 | LogError("No uri resource passed to HTTPAPIEX_SAS_Create."); |
Azure.IoT Build | 0:fa2de1b79154 | 92 | } |
Azure.IoT Build | 0:fa2de1b79154 | 93 | else |
Azure.IoT Build | 0:fa2de1b79154 | 94 | { |
AzureIoTClient | 38:ed9c888e5e12 | 95 | /*Codes_SRS_HTTPAPIEXSAS_06_003: [The parameter keyName for HTTPAPIEX_SAS_Create is optional and can be NULL.]*/ |
AzureIoTClient | 7:1af47e3a19b6 | 96 | /*Codes_SRS_HTTPAPIEXSAS_01_001: [ HTTPAPIEX_SAS_Create shall create a new instance of HTTPAPIEX_SAS and return a non-NULL handle to it. ]*/ |
AzureIoTClient | 38:ed9c888e5e12 | 97 | result = construct_httpex_sas(STRING_c_str(key), STRING_c_str(uriResource), STRING_c_str(keyName) ); |
Azure.IoT Build | 0:fa2de1b79154 | 98 | } |
Azure.IoT Build | 0:fa2de1b79154 | 99 | return result; |
Azure.IoT Build | 0:fa2de1b79154 | 100 | } |
Azure.IoT Build | 0:fa2de1b79154 | 101 | |
Azure.IoT Build | 0:fa2de1b79154 | 102 | void HTTPAPIEX_SAS_Destroy(HTTPAPIEX_SAS_HANDLE handle) |
Azure.IoT Build | 0:fa2de1b79154 | 103 | { |
Azure.IoT Build | 0:fa2de1b79154 | 104 | /*Codes_SRS_HTTPAPIEXSAS_06_005: [If the parameter handle is NULL then HTTAPIEX_SAS_Destroy shall do nothing and return.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 105 | if (handle) |
Azure.IoT Build | 0:fa2de1b79154 | 106 | { |
Azure.IoT Build | 0:fa2de1b79154 | 107 | HTTPAPIEX_SAS_STATE* state = (HTTPAPIEX_SAS_STATE*)handle; |
Azure.IoT Build | 0:fa2de1b79154 | 108 | /*Codes_SRS_HTTPAPIEXSAS_06_006: [HTTAPIEX_SAS_Destroy shall deallocate any structures denoted by the parameter handle.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 109 | if (state->key) |
Azure.IoT Build | 0:fa2de1b79154 | 110 | { |
AzureIoTClient | 38:ed9c888e5e12 | 111 | free(state->key); |
Azure.IoT Build | 0:fa2de1b79154 | 112 | } |
Azure.IoT Build | 0:fa2de1b79154 | 113 | if (state->uriResource) |
Azure.IoT Build | 0:fa2de1b79154 | 114 | { |
AzureIoTClient | 38:ed9c888e5e12 | 115 | free(state->uriResource); |
Azure.IoT Build | 0:fa2de1b79154 | 116 | } |
Azure.IoT Build | 0:fa2de1b79154 | 117 | if (state->keyName) |
Azure.IoT Build | 0:fa2de1b79154 | 118 | { |
AzureIoTClient | 38:ed9c888e5e12 | 119 | free(state->keyName); |
Azure.IoT Build | 0:fa2de1b79154 | 120 | } |
Azure.IoT Build | 0:fa2de1b79154 | 121 | free(state); |
Azure.IoT Build | 0:fa2de1b79154 | 122 | } |
Azure.IoT Build | 0:fa2de1b79154 | 123 | } |
Azure.IoT Build | 0:fa2de1b79154 | 124 | |
Azure.IoT Build | 0:fa2de1b79154 | 125 | HTTPAPIEX_RESULT HTTPAPIEX_SAS_ExecuteRequest(HTTPAPIEX_SAS_HANDLE sasHandle, HTTPAPIEX_HANDLE handle, HTTPAPI_REQUEST_TYPE requestType, const char* relativePath, HTTP_HEADERS_HANDLE requestHttpHeadersHandle, BUFFER_HANDLE requestContent, unsigned int* statusCode, HTTP_HEADERS_HANDLE responseHeadersHandle, BUFFER_HANDLE responseContent) |
Azure.IoT Build | 0:fa2de1b79154 | 126 | { |
Azure.IoT Build | 0:fa2de1b79154 | 127 | /*Codes_SRS_HTTPAPIEXSAS_06_007: [If the parameter sasHandle is NULL then HTTPAPIEX_SAS_ExecuteRequest shall simply invoke HTTPAPIEX_ExecuteRequest with the remaining parameters (following sasHandle) as its arguments and shall return immediately with the result of that call as the result of HTTPAPIEX_SAS_ExecuteRequest.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 128 | if (sasHandle != NULL) |
Azure.IoT Build | 0:fa2de1b79154 | 129 | { |
Azure.IoT Build | 0:fa2de1b79154 | 130 | /*Codes_SRS_HTTPAPIEXSAS_06_008: [if the parameter requestHttpHeadersHandle is NULL then fallthrough.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 131 | if (requestHttpHeadersHandle != NULL) |
Azure.IoT Build | 0:fa2de1b79154 | 132 | { |
Azure.IoT Build | 0:fa2de1b79154 | 133 | /*Codes_SRS_HTTPAPIEXSAS_06_009: [HTTPHeaders_FindHeaderValue shall be invoked with the requestHttpHeadersHandle as its first argument and the string "Authorization" as its second argument.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 134 | /*Codes_SRS_HTTPAPIEXSAS_06_010: [If the return result of the invocation of HTTPHeaders_FindHeaderValue is NULL then fallthrough.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 135 | if (HTTPHeaders_FindHeaderValue(requestHttpHeadersHandle, "Authorization") != NULL) |
Azure.IoT Build | 0:fa2de1b79154 | 136 | { |
Azure.IoT Build | 0:fa2de1b79154 | 137 | HTTPAPIEX_SAS_STATE* state = (HTTPAPIEX_SAS_STATE*)sasHandle; |
Azure.IoT Build | 0:fa2de1b79154 | 138 | /*Codes_SRS_HTTPAPIEXSAS_06_018: [A value of type time_t that shall be known as currentTime is obtained from calling get_time.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 139 | time_t currentTime = get_time(NULL); |
Azure.IoT Build | 0:fa2de1b79154 | 140 | /*Codes_SRS_HTTPAPIEXSAS_06_019: [If the value of currentTime is (time_t)-1 is then fallthrough.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 141 | if (currentTime == (time_t)-1) |
Azure.IoT Build | 0:fa2de1b79154 | 142 | { |
AzureIoTClient | 1:9190c0f4d23a | 143 | LogError("Time does not appear to be working."); |
Azure.IoT Build | 0:fa2de1b79154 | 144 | } |
Azure.IoT Build | 0:fa2de1b79154 | 145 | else |
Azure.IoT Build | 0:fa2de1b79154 | 146 | { |
Azure.IoT Build | 0:fa2de1b79154 | 147 | /*Codes_SRS_HTTPAPIEXSAS_06_011: [SASToken_Create shall be invoked.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 148 | /*Codes_SRS_HTTPAPIEXSAS_06_012: [If the return result of SASToken_Create is NULL then fallthrough.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 149 | size_t expiry = (size_t)(difftime(currentTime, 0) + 3600); |
AzureIoTClient | 38:ed9c888e5e12 | 150 | STRING_HANDLE newSASToken = SASToken_CreateString(state->key, state->uriResource, state->keyName, expiry); |
Azure.IoT Build | 0:fa2de1b79154 | 151 | if (newSASToken != NULL) |
Azure.IoT Build | 0:fa2de1b79154 | 152 | { |
Azure.IoT Build | 0:fa2de1b79154 | 153 | /*Codes_SRS_HTTPAPIEXSAS_06_013: [HTTPHeaders_ReplaceHeaderNameValuePair shall be invoked with "Authorization" as its second argument and STRING_c_str (newSASToken) as its third argument.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 154 | if (HTTPHeaders_ReplaceHeaderNameValuePair(requestHttpHeadersHandle, "Authorization", STRING_c_str(newSASToken)) != HTTP_HEADERS_OK) |
Azure.IoT Build | 0:fa2de1b79154 | 155 | { |
Azure.IoT Build | 0:fa2de1b79154 | 156 | /*Codes_SRS_HTTPAPIEXSAS_06_014: [If the result of the invocation of HTTPHeaders_ReplaceHeaderNameValuePair is NOT HTTP_HEADERS_OK then fallthrough.]*/ |
AzureIoTClient | 1:9190c0f4d23a | 157 | LogError("Unable to replace the old SAS Token."); |
Azure.IoT Build | 0:fa2de1b79154 | 158 | } |
Azure.IoT Build | 0:fa2de1b79154 | 159 | /*Codes_SRS_HTTPAPIEXSAS_06_015: [STRING_delete(newSASToken) will be invoked.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 160 | STRING_delete(newSASToken); |
Azure.IoT Build | 0:fa2de1b79154 | 161 | } |
Azure.IoT Build | 0:fa2de1b79154 | 162 | else |
Azure.IoT Build | 0:fa2de1b79154 | 163 | { |
AzureIoTClient | 1:9190c0f4d23a | 164 | LogError("Unable to create a new SAS token."); |
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 | } |
Azure.IoT Build | 0:fa2de1b79154 | 170 | /*Codes_SRS_HTTPAPIEXSAS_06_016: [HTTPAPIEX_ExecuteRequest with the remaining parameters (following sasHandle) as its arguments will be invoked and the result of that call is the result of HTTPAPIEX_SAS_ExecuteRequest.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 171 | return HTTPAPIEX_ExecuteRequest(handle,requestType,relativePath,requestHttpHeadersHandle,requestContent,statusCode,responseHeadersHandle,responseContent); |
Azure.IoT Build | 0:fa2de1b79154 | 172 | } |