Azure IoT common library
Fork of azure_c_shared_utility by
httpapiexsas.c@7:1af47e3a19b6, 2016-07-29 (annotated)
- Committer:
- AzureIoTClient
- Date:
- Fri Jul 29 16:01:07 2016 -0700
- Revision:
- 7:1af47e3a19b6
- Parent:
- 6:c55b013dfc2a
- Child:
- 19:2e0811512ceb
1.0.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 | #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 <stddef.h> |
Azure.IoT Build | 0:fa2de1b79154 | 11 | #include <time.h> |
Azure.IoT Build | 0:fa2de1b79154 | 12 | |
Azure.IoT Build | 0:fa2de1b79154 | 13 | #include "azure_c_shared_utility/agenttime.h" |
Azure.IoT Build | 0:fa2de1b79154 | 14 | #include "azure_c_shared_utility/strings.h" |
Azure.IoT Build | 0:fa2de1b79154 | 15 | #include "azure_c_shared_utility/buffer_.h" |
Azure.IoT Build | 0:fa2de1b79154 | 16 | #include "azure_c_shared_utility/sastoken.h" |
Azure.IoT Build | 0:fa2de1b79154 | 17 | #include "azure_c_shared_utility/httpheaders.h" |
Azure.IoT Build | 0:fa2de1b79154 | 18 | #include "azure_c_shared_utility/httpapiex.h" |
Azure.IoT Build | 0:fa2de1b79154 | 19 | #include "azure_c_shared_utility/httpapiexsas.h" |
Azure.IoT Build | 6:c55b013dfc2a | 20 | #include "azure_c_shared_utility/xlogging.h" |
Azure.IoT Build | 0:fa2de1b79154 | 21 | |
Azure.IoT Build | 0:fa2de1b79154 | 22 | typedef struct HTTPAPIEX_SAS_STATE_TAG |
Azure.IoT Build | 0:fa2de1b79154 | 23 | { |
Azure.IoT Build | 0:fa2de1b79154 | 24 | STRING_HANDLE key; |
Azure.IoT Build | 0:fa2de1b79154 | 25 | STRING_HANDLE uriResource; |
Azure.IoT Build | 0:fa2de1b79154 | 26 | STRING_HANDLE keyName; |
Azure.IoT Build | 0:fa2de1b79154 | 27 | }HTTPAPIEX_SAS_STATE; |
Azure.IoT Build | 0:fa2de1b79154 | 28 | |
Azure.IoT Build | 0:fa2de1b79154 | 29 | |
Azure.IoT Build | 0:fa2de1b79154 | 30 | HTTPAPIEX_SAS_HANDLE HTTPAPIEX_SAS_Create(STRING_HANDLE key, STRING_HANDLE uriResource, STRING_HANDLE keyName) |
Azure.IoT Build | 0:fa2de1b79154 | 31 | { |
Azure.IoT Build | 0:fa2de1b79154 | 32 | HTTPAPIEX_SAS_HANDLE result = NULL; |
Azure.IoT Build | 0:fa2de1b79154 | 33 | if (key == NULL) |
Azure.IoT Build | 0:fa2de1b79154 | 34 | { |
Azure.IoT Build | 0:fa2de1b79154 | 35 | /*Codes_SRS_HTTPAPIEXSAS_06_001: [If the parameter key is NULL then HTTPAPIEX_SAS_Create shall return NULL.]*/ |
AzureIoTClient | 1:9190c0f4d23a | 36 | LogError("No key passed to HTTPAPIEX_SAS_Create."); |
Azure.IoT Build | 0:fa2de1b79154 | 37 | } |
Azure.IoT Build | 0:fa2de1b79154 | 38 | else if (uriResource == NULL) |
Azure.IoT Build | 0:fa2de1b79154 | 39 | { |
Azure.IoT Build | 0:fa2de1b79154 | 40 | /*Codes_SRS_HTTPAPIEXSAS_06_002: [If the parameter uriResource is NULL then HTTPAPIEX_SAS_Create shall return NULL.]*/ |
AzureIoTClient | 1:9190c0f4d23a | 41 | LogError("No uri resource passed to HTTPAPIEX_SAS_Create."); |
Azure.IoT Build | 0:fa2de1b79154 | 42 | } |
Azure.IoT Build | 0:fa2de1b79154 | 43 | else if (keyName == NULL) |
Azure.IoT Build | 0:fa2de1b79154 | 44 | { |
Azure.IoT Build | 0:fa2de1b79154 | 45 | /*Codes_SRS_HTTPAPIEXSAS_06_003: [If the parameter keyName is NULL then HTTPAPIEX_SAS_Create shall return NULL.]*/ |
AzureIoTClient | 1:9190c0f4d23a | 46 | LogError("No key name passed to HTTPAPIEX_SAS_Create."); |
Azure.IoT Build | 0:fa2de1b79154 | 47 | } |
Azure.IoT Build | 0:fa2de1b79154 | 48 | else |
Azure.IoT Build | 0:fa2de1b79154 | 49 | { |
AzureIoTClient | 7:1af47e3a19b6 | 50 | /*Codes_SRS_HTTPAPIEXSAS_01_001: [ HTTPAPIEX_SAS_Create shall create a new instance of HTTPAPIEX_SAS and return a non-NULL handle to it. ]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 51 | HTTPAPIEX_SAS_STATE* state = malloc(sizeof(HTTPAPIEX_SAS_STATE)); |
Azure.IoT Build | 0:fa2de1b79154 | 52 | /*Codes_SRS_HTTPAPIEXSAS_06_004: [If there are any other errors in the instantiation of this handle then HTTPAPIEX_SAS_Create shall return NULL.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 53 | if (state != NULL) |
Azure.IoT Build | 0:fa2de1b79154 | 54 | { |
Azure.IoT Build | 0:fa2de1b79154 | 55 | state->key = NULL; |
Azure.IoT Build | 0:fa2de1b79154 | 56 | state->uriResource = NULL; |
Azure.IoT Build | 0:fa2de1b79154 | 57 | state->keyName = NULL; |
Azure.IoT Build | 0:fa2de1b79154 | 58 | if (((state->key = STRING_clone(key)) == NULL) || |
Azure.IoT Build | 0:fa2de1b79154 | 59 | ((state->uriResource = STRING_clone(uriResource)) == NULL) || |
Azure.IoT Build | 0:fa2de1b79154 | 60 | ((state->keyName = STRING_clone(keyName)) == NULL)) |
Azure.IoT Build | 0:fa2de1b79154 | 61 | { |
Azure.IoT Build | 0:fa2de1b79154 | 62 | /*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 | 1:9190c0f4d23a | 63 | LogError("Unable to clone the arguments."); |
Azure.IoT Build | 0:fa2de1b79154 | 64 | HTTPAPIEX_SAS_Destroy(state); |
Azure.IoT Build | 0:fa2de1b79154 | 65 | } |
Azure.IoT Build | 0:fa2de1b79154 | 66 | else |
Azure.IoT Build | 0:fa2de1b79154 | 67 | { |
Azure.IoT Build | 0:fa2de1b79154 | 68 | result = state; |
Azure.IoT Build | 0:fa2de1b79154 | 69 | } |
Azure.IoT Build | 0:fa2de1b79154 | 70 | } |
Azure.IoT Build | 0:fa2de1b79154 | 71 | } |
Azure.IoT Build | 0:fa2de1b79154 | 72 | return result; |
Azure.IoT Build | 0:fa2de1b79154 | 73 | } |
Azure.IoT Build | 0:fa2de1b79154 | 74 | |
Azure.IoT Build | 0:fa2de1b79154 | 75 | void HTTPAPIEX_SAS_Destroy(HTTPAPIEX_SAS_HANDLE handle) |
Azure.IoT Build | 0:fa2de1b79154 | 76 | { |
Azure.IoT Build | 0:fa2de1b79154 | 77 | /*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 | 78 | if (handle) |
Azure.IoT Build | 0:fa2de1b79154 | 79 | { |
Azure.IoT Build | 0:fa2de1b79154 | 80 | HTTPAPIEX_SAS_STATE* state = (HTTPAPIEX_SAS_STATE*)handle; |
Azure.IoT Build | 0:fa2de1b79154 | 81 | /*Codes_SRS_HTTPAPIEXSAS_06_006: [HTTAPIEX_SAS_Destroy shall deallocate any structures denoted by the parameter handle.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 82 | if (state->key) |
Azure.IoT Build | 0:fa2de1b79154 | 83 | { |
Azure.IoT Build | 0:fa2de1b79154 | 84 | STRING_delete(state->key); |
Azure.IoT Build | 0:fa2de1b79154 | 85 | } |
Azure.IoT Build | 0:fa2de1b79154 | 86 | if (state->uriResource) |
Azure.IoT Build | 0:fa2de1b79154 | 87 | { |
Azure.IoT Build | 0:fa2de1b79154 | 88 | STRING_delete(state->uriResource); |
Azure.IoT Build | 0:fa2de1b79154 | 89 | } |
Azure.IoT Build | 0:fa2de1b79154 | 90 | if (state->keyName) |
Azure.IoT Build | 0:fa2de1b79154 | 91 | { |
Azure.IoT Build | 0:fa2de1b79154 | 92 | STRING_delete(state->keyName); |
Azure.IoT Build | 0:fa2de1b79154 | 93 | } |
Azure.IoT Build | 0:fa2de1b79154 | 94 | free(state); |
Azure.IoT Build | 0:fa2de1b79154 | 95 | } |
Azure.IoT Build | 0:fa2de1b79154 | 96 | } |
Azure.IoT Build | 0:fa2de1b79154 | 97 | |
Azure.IoT Build | 0:fa2de1b79154 | 98 | 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 | 99 | { |
Azure.IoT Build | 0:fa2de1b79154 | 100 | /*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 | 101 | if (sasHandle != NULL) |
Azure.IoT Build | 0:fa2de1b79154 | 102 | { |
Azure.IoT Build | 0:fa2de1b79154 | 103 | /*Codes_SRS_HTTPAPIEXSAS_06_008: [if the parameter requestHttpHeadersHandle is NULL then fallthrough.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 104 | if (requestHttpHeadersHandle != NULL) |
Azure.IoT Build | 0:fa2de1b79154 | 105 | { |
Azure.IoT Build | 0:fa2de1b79154 | 106 | /*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 | 107 | /*Codes_SRS_HTTPAPIEXSAS_06_010: [If the return result of the invocation of HTTPHeaders_FindHeaderValue is NULL then fallthrough.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 108 | if (HTTPHeaders_FindHeaderValue(requestHttpHeadersHandle, "Authorization") != NULL) |
Azure.IoT Build | 0:fa2de1b79154 | 109 | { |
Azure.IoT Build | 0:fa2de1b79154 | 110 | HTTPAPIEX_SAS_STATE* state = (HTTPAPIEX_SAS_STATE*)sasHandle; |
Azure.IoT Build | 0:fa2de1b79154 | 111 | /*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 | 112 | time_t currentTime = get_time(NULL); |
Azure.IoT Build | 0:fa2de1b79154 | 113 | /*Codes_SRS_HTTPAPIEXSAS_06_019: [If the value of currentTime is (time_t)-1 is then fallthrough.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 114 | if (currentTime == (time_t)-1) |
Azure.IoT Build | 0:fa2de1b79154 | 115 | { |
AzureIoTClient | 1:9190c0f4d23a | 116 | LogError("Time does not appear to be working."); |
Azure.IoT Build | 0:fa2de1b79154 | 117 | } |
Azure.IoT Build | 0:fa2de1b79154 | 118 | else |
Azure.IoT Build | 0:fa2de1b79154 | 119 | { |
Azure.IoT Build | 0:fa2de1b79154 | 120 | /*Codes_SRS_HTTPAPIEXSAS_06_011: [SASToken_Create shall be invoked.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 121 | /*Codes_SRS_HTTPAPIEXSAS_06_012: [If the return result of SASToken_Create is NULL then fallthrough.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 122 | size_t expiry = (size_t)(difftime(currentTime, 0) + 3600); |
Azure.IoT Build | 0:fa2de1b79154 | 123 | STRING_HANDLE newSASToken = SASToken_Create(state->key, state->uriResource, state->keyName, expiry); |
Azure.IoT Build | 0:fa2de1b79154 | 124 | if (newSASToken != NULL) |
Azure.IoT Build | 0:fa2de1b79154 | 125 | { |
Azure.IoT Build | 0:fa2de1b79154 | 126 | /*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 | 127 | if (HTTPHeaders_ReplaceHeaderNameValuePair(requestHttpHeadersHandle, "Authorization", STRING_c_str(newSASToken)) != HTTP_HEADERS_OK) |
Azure.IoT Build | 0:fa2de1b79154 | 128 | { |
Azure.IoT Build | 0:fa2de1b79154 | 129 | /*Codes_SRS_HTTPAPIEXSAS_06_014: [If the result of the invocation of HTTPHeaders_ReplaceHeaderNameValuePair is NOT HTTP_HEADERS_OK then fallthrough.]*/ |
AzureIoTClient | 1:9190c0f4d23a | 130 | LogError("Unable to replace the old SAS Token."); |
Azure.IoT Build | 0:fa2de1b79154 | 131 | } |
Azure.IoT Build | 0:fa2de1b79154 | 132 | /*Codes_SRS_HTTPAPIEXSAS_06_015: [STRING_delete(newSASToken) will be invoked.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 133 | STRING_delete(newSASToken); |
Azure.IoT Build | 0:fa2de1b79154 | 134 | } |
Azure.IoT Build | 0:fa2de1b79154 | 135 | else |
Azure.IoT Build | 0:fa2de1b79154 | 136 | { |
AzureIoTClient | 1:9190c0f4d23a | 137 | LogError("Unable to create a new SAS token."); |
Azure.IoT Build | 0:fa2de1b79154 | 138 | } |
Azure.IoT Build | 0:fa2de1b79154 | 139 | } |
Azure.IoT Build | 0:fa2de1b79154 | 140 | } |
Azure.IoT Build | 0:fa2de1b79154 | 141 | } |
Azure.IoT Build | 0:fa2de1b79154 | 142 | } |
Azure.IoT Build | 0:fa2de1b79154 | 143 | /*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 | 144 | return HTTPAPIEX_ExecuteRequest(handle,requestType,relativePath,requestHttpHeadersHandle,requestContent,statusCode,responseHeadersHandle,responseContent); |
Azure.IoT Build | 0:fa2de1b79154 | 145 | } |