Microsoft Azure IoTHub client libraries
Dependents: sht15_remote_monitoring RobotArmDemo iothub_client_sample_amqp f767zi_mqtt ... more
This library implements the Microsoft Azure IoTHub client library. The code is replicated from https://github.com/Azure/azure-iot-sdks
blob.c@42:448eecc3676e, 2016-06-07 (annotated)
- Committer:
- AzureIoTClient
- Date:
- Tue Jun 07 10:49:08 2016 -0700
- Revision:
- 42:448eecc3676e
- Child:
- 43:038d8511e817
1.0.8
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
AzureIoTClient | 42:448eecc3676e | 1 | // Copyright (c) Microsoft. All rights reserved. |
AzureIoTClient | 42:448eecc3676e | 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. |
AzureIoTClient | 42:448eecc3676e | 3 | |
AzureIoTClient | 42:448eecc3676e | 4 | #include <stdlib.h> |
AzureIoTClient | 42:448eecc3676e | 5 | #ifdef _CRTDBG_MAP_ALLOC |
AzureIoTClient | 42:448eecc3676e | 6 | #include <crtdbg.h> |
AzureIoTClient | 42:448eecc3676e | 7 | #endif |
AzureIoTClient | 42:448eecc3676e | 8 | #include "azure_c_shared_utility/gballoc.h" |
AzureIoTClient | 42:448eecc3676e | 9 | |
AzureIoTClient | 42:448eecc3676e | 10 | #include "blob.h" |
AzureIoTClient | 42:448eecc3676e | 11 | |
AzureIoTClient | 42:448eecc3676e | 12 | #include "azure_c_shared_utility/httpapiex.h" |
AzureIoTClient | 42:448eecc3676e | 13 | #include "azure_c_shared_utility/iot_logging.h" |
AzureIoTClient | 42:448eecc3676e | 14 | |
AzureIoTClient | 42:448eecc3676e | 15 | BLOB_RESULT Blob_UploadFromSasUri(const char* SASURI, const unsigned char* source, size_t size, unsigned int* httpStatus, BUFFER_HANDLE httpResponse) |
AzureIoTClient | 42:448eecc3676e | 16 | { |
AzureIoTClient | 42:448eecc3676e | 17 | BLOB_RESULT result; |
AzureIoTClient | 42:448eecc3676e | 18 | /*Codes_SRS_BLOB_02_001: [ If SASURI is NULL then Blob_UploadFromSasUri shall fail and return BLOB_INVALID_ARG. ]*/ |
AzureIoTClient | 42:448eecc3676e | 19 | if (SASURI == NULL) |
AzureIoTClient | 42:448eecc3676e | 20 | { |
AzureIoTClient | 42:448eecc3676e | 21 | LogError("parameter SASURI is NULL"); |
AzureIoTClient | 42:448eecc3676e | 22 | result = BLOB_INVALID_ARG; |
AzureIoTClient | 42:448eecc3676e | 23 | } |
AzureIoTClient | 42:448eecc3676e | 24 | else |
AzureIoTClient | 42:448eecc3676e | 25 | { |
AzureIoTClient | 42:448eecc3676e | 26 | /*Codes_SRS_BLOB_02_002: [ If source is NULL and size is not zero then Blob_UploadFromSasUri shall fail and return BLOB_INVALID_ARG. ]*/ |
AzureIoTClient | 42:448eecc3676e | 27 | if ( |
AzureIoTClient | 42:448eecc3676e | 28 | (size > 0) && |
AzureIoTClient | 42:448eecc3676e | 29 | (source == NULL) |
AzureIoTClient | 42:448eecc3676e | 30 | ) |
AzureIoTClient | 42:448eecc3676e | 31 | { |
AzureIoTClient | 42:448eecc3676e | 32 | LogError("combination of source = %p and size = %zd is invalid", source, size); |
AzureIoTClient | 42:448eecc3676e | 33 | result = BLOB_INVALID_ARG; |
AzureIoTClient | 42:448eecc3676e | 34 | } |
AzureIoTClient | 42:448eecc3676e | 35 | /*Codes_SRS_BLOB_02_003: [ If size is bigger or equal to 64M then Blob_UploadFromSasUri shall fail and return BLOB_NOT_IMPLEMENTED. ]*/ |
AzureIoTClient | 42:448eecc3676e | 36 | else if (size >= 64 * 1024 * 1024) |
AzureIoTClient | 42:448eecc3676e | 37 | { |
AzureIoTClient | 42:448eecc3676e | 38 | LogError("upload of files greater than 64M is not implemented"); |
AzureIoTClient | 42:448eecc3676e | 39 | result = BLOB_NOT_IMPLEMENTED; |
AzureIoTClient | 42:448eecc3676e | 40 | } |
AzureIoTClient | 42:448eecc3676e | 41 | else |
AzureIoTClient | 42:448eecc3676e | 42 | { |
AzureIoTClient | 42:448eecc3676e | 43 | /*Codes_SRS_BLOB_02_004: [ Blob_UploadFromSasUri shall copy from SASURI the hostname to a new const char*. ]*/ |
AzureIoTClient | 42:448eecc3676e | 44 | /*to find the hostname, the following logic is applied:*/ |
AzureIoTClient | 42:448eecc3676e | 45 | /*the hostname starts at the first character after "://"*/ |
AzureIoTClient | 42:448eecc3676e | 46 | /*the hostname ends at the first character before the next "/" after "://"*/ |
AzureIoTClient | 42:448eecc3676e | 47 | const char* hostnameBegin = strstr(SASURI, "://"); |
AzureIoTClient | 42:448eecc3676e | 48 | if (hostnameBegin == NULL) |
AzureIoTClient | 42:448eecc3676e | 49 | { |
AzureIoTClient | 42:448eecc3676e | 50 | /*Codes_SRS_BLOB_02_005: [ If the hostname cannot be determined, then Blob_UploadFromSasUri shall fail and return BLOB_INVALID_ARG. ]*/ |
AzureIoTClient | 42:448eecc3676e | 51 | LogError("hostname cannot be determined"); |
AzureIoTClient | 42:448eecc3676e | 52 | result = BLOB_INVALID_ARG; |
AzureIoTClient | 42:448eecc3676e | 53 | } |
AzureIoTClient | 42:448eecc3676e | 54 | else |
AzureIoTClient | 42:448eecc3676e | 55 | { |
AzureIoTClient | 42:448eecc3676e | 56 | hostnameBegin += 3; /*have to skip 3 characters which are "://"*/ |
AzureIoTClient | 42:448eecc3676e | 57 | const char* hostnameEnd = strchr(hostnameBegin, '/'); |
AzureIoTClient | 42:448eecc3676e | 58 | if (hostnameEnd == NULL) |
AzureIoTClient | 42:448eecc3676e | 59 | { |
AzureIoTClient | 42:448eecc3676e | 60 | /*Codes_SRS_BLOB_02_005: [ If the hostname cannot be determined, then Blob_UploadFromSasUri shall fail and return BLOB_INVALID_ARG. ]*/ |
AzureIoTClient | 42:448eecc3676e | 61 | LogError("hostname cannot be determined"); |
AzureIoTClient | 42:448eecc3676e | 62 | result = BLOB_INVALID_ARG; |
AzureIoTClient | 42:448eecc3676e | 63 | } |
AzureIoTClient | 42:448eecc3676e | 64 | else |
AzureIoTClient | 42:448eecc3676e | 65 | { |
AzureIoTClient | 42:448eecc3676e | 66 | size_t hostnameSize = hostnameEnd - hostnameBegin; |
AzureIoTClient | 42:448eecc3676e | 67 | char* hostname = (char*)malloc(hostnameSize + 1); /*+1 because of '\0' at the end*/ |
AzureIoTClient | 42:448eecc3676e | 68 | if (hostname == NULL) |
AzureIoTClient | 42:448eecc3676e | 69 | { |
AzureIoTClient | 42:448eecc3676e | 70 | /*Codes_SRS_BLOB_02_016: [ If the hostname copy cannot be made then then Blob_UploadFromSasUri shall fail and return BLOB_ERROR ]*/ |
AzureIoTClient | 42:448eecc3676e | 71 | LogError("oom - out of memory"); |
AzureIoTClient | 42:448eecc3676e | 72 | result = BLOB_ERROR; |
AzureIoTClient | 42:448eecc3676e | 73 | } |
AzureIoTClient | 42:448eecc3676e | 74 | else |
AzureIoTClient | 42:448eecc3676e | 75 | { |
AzureIoTClient | 42:448eecc3676e | 76 | HTTPAPIEX_HANDLE httpApiExHandle; |
AzureIoTClient | 42:448eecc3676e | 77 | memcpy(hostname, hostnameBegin, hostnameSize); |
AzureIoTClient | 42:448eecc3676e | 78 | hostname[hostnameSize] = '\0'; |
AzureIoTClient | 42:448eecc3676e | 79 | |
AzureIoTClient | 42:448eecc3676e | 80 | /*Codes_SRS_BLOB_02_006: [ Blob_UploadFromSasUri shall create a new HTTPAPI_EX_HANDLE by calling HTTPAPIEX_Create passing the hostname. ]*/ |
AzureIoTClient | 42:448eecc3676e | 81 | httpApiExHandle = HTTPAPIEX_Create(hostname); |
AzureIoTClient | 42:448eecc3676e | 82 | if (httpApiExHandle == NULL) |
AzureIoTClient | 42:448eecc3676e | 83 | { |
AzureIoTClient | 42:448eecc3676e | 84 | /*Codes_SRS_BLOB_02_007: [ If HTTPAPIEX_Create fails then Blob_UploadFromSasUri shall fail and return BLOB_ERROR. ]*/ |
AzureIoTClient | 42:448eecc3676e | 85 | LogError("unable to create a HTTPAPIEX_HANDLE"); |
AzureIoTClient | 42:448eecc3676e | 86 | result = BLOB_ERROR; |
AzureIoTClient | 42:448eecc3676e | 87 | } |
AzureIoTClient | 42:448eecc3676e | 88 | else |
AzureIoTClient | 42:448eecc3676e | 89 | { |
AzureIoTClient | 42:448eecc3676e | 90 | /*Codes_SRS_BLOB_02_008: [ Blob_UploadFromSasUri shall compute the relative path of the request from the SASURI parameter. ]*/ |
AzureIoTClient | 42:448eecc3676e | 91 | const char* relativePath = hostnameEnd; /*this is where the relative path begins in the SasUri*/ |
AzureIoTClient | 42:448eecc3676e | 92 | |
AzureIoTClient | 42:448eecc3676e | 93 | /*Codes_SRS_BLOB_02_010: [ Blob_UploadFromSasUri shall create a BUFFER_HANDLE from source and size parameters. ]*/ |
AzureIoTClient | 42:448eecc3676e | 94 | BUFFER_HANDLE requestBuffer = BUFFER_create(source, size); |
AzureIoTClient | 42:448eecc3676e | 95 | if (requestBuffer == NULL) |
AzureIoTClient | 42:448eecc3676e | 96 | { |
AzureIoTClient | 42:448eecc3676e | 97 | /*Codes_SRS_BLOB_02_011: [ If any of the previous steps related to building the HTTPAPI_EX_ExecuteRequest parameters fails, then Blob_UploadFromSasUri shall fail and return BLOB_ERROR. ]*/ |
AzureIoTClient | 42:448eecc3676e | 98 | LogError("unable to BUFFER_create"); |
AzureIoTClient | 42:448eecc3676e | 99 | result = BLOB_ERROR; |
AzureIoTClient | 42:448eecc3676e | 100 | } |
AzureIoTClient | 42:448eecc3676e | 101 | else |
AzureIoTClient | 42:448eecc3676e | 102 | { |
AzureIoTClient | 42:448eecc3676e | 103 | /*Codes_SRS_BLOB_02_009: [ Blob_UploadFromSasUri shall create an HTTP_HEADERS_HANDLE for the request HTTP headers carrying the following headers: ]*/ |
AzureIoTClient | 42:448eecc3676e | 104 | HTTP_HEADERS_HANDLE requestHttpHeaders = HTTPHeaders_Alloc(); |
AzureIoTClient | 42:448eecc3676e | 105 | if (requestHttpHeaders == NULL) |
AzureIoTClient | 42:448eecc3676e | 106 | { |
AzureIoTClient | 42:448eecc3676e | 107 | /*Codes_SRS_BLOB_02_011: [ If any of the previous steps related to building the HTTPAPI_EX_ExecuteRequest parameters fails, then Blob_UploadFromSasUri shall fail and return BLOB_ERROR. ]*/ |
AzureIoTClient | 42:448eecc3676e | 108 | LogError("unable to HTTPHeaders_Alloc"); |
AzureIoTClient | 42:448eecc3676e | 109 | result = BLOB_ERROR; |
AzureIoTClient | 42:448eecc3676e | 110 | } |
AzureIoTClient | 42:448eecc3676e | 111 | else |
AzureIoTClient | 42:448eecc3676e | 112 | { |
AzureIoTClient | 42:448eecc3676e | 113 | if (HTTPHeaders_AddHeaderNameValuePair(requestHttpHeaders, "x-ms-blob-type", "BlockBlob") != HTTP_HEADERS_OK) |
AzureIoTClient | 42:448eecc3676e | 114 | { |
AzureIoTClient | 42:448eecc3676e | 115 | /*Codes_SRS_BLOB_02_011: [ If any of the previous steps related to building the HTTPAPI_EX_ExecuteRequest parameters fails, then Blob_UploadFromSasUri shall fail and return BLOB_ERROR. ]*/ |
AzureIoTClient | 42:448eecc3676e | 116 | LogError("unable to HTTPHeaders_AddHeaderNameValuePair"); |
AzureIoTClient | 42:448eecc3676e | 117 | result = BLOB_ERROR; |
AzureIoTClient | 42:448eecc3676e | 118 | } |
AzureIoTClient | 42:448eecc3676e | 119 | else |
AzureIoTClient | 42:448eecc3676e | 120 | { |
AzureIoTClient | 42:448eecc3676e | 121 | /*Codes_SRS_BLOB_02_012: [ Blob_UploadFromSasUri shall call HTTPAPIEX_ExecuteRequest passing the parameters previously build, httpStatus and httpResponse ]*/ |
AzureIoTClient | 42:448eecc3676e | 122 | if (HTTPAPIEX_ExecuteRequest(httpApiExHandle, HTTPAPI_REQUEST_PUT, relativePath, requestHttpHeaders, requestBuffer, httpStatus, NULL, httpResponse) != HTTPAPIEX_OK) |
AzureIoTClient | 42:448eecc3676e | 123 | { |
AzureIoTClient | 42:448eecc3676e | 124 | /*Codes_SRS_BLOB_02_013: [ If HTTPAPIEX_ExecuteRequest fails, then Blob_UploadFromSasUri shall fail and return BLOB_HTTP_ERROR. ]*/ |
AzureIoTClient | 42:448eecc3676e | 125 | LogError("failed to HTTPAPIEX_ExecuteRequest"); |
AzureIoTClient | 42:448eecc3676e | 126 | result = BLOB_HTTP_ERROR; |
AzureIoTClient | 42:448eecc3676e | 127 | } |
AzureIoTClient | 42:448eecc3676e | 128 | else |
AzureIoTClient | 42:448eecc3676e | 129 | { |
AzureIoTClient | 42:448eecc3676e | 130 | /*Codes_SRS_BLOB_02_015: [ Otherwise, HTTPAPIEX_ExecuteRequest shall succeed and return BLOB_OK. ]*/ |
AzureIoTClient | 42:448eecc3676e | 131 | result = BLOB_OK; |
AzureIoTClient | 42:448eecc3676e | 132 | } |
AzureIoTClient | 42:448eecc3676e | 133 | } |
AzureIoTClient | 42:448eecc3676e | 134 | HTTPHeaders_Free(requestHttpHeaders); |
AzureIoTClient | 42:448eecc3676e | 135 | } |
AzureIoTClient | 42:448eecc3676e | 136 | BUFFER_delete(requestBuffer); |
AzureIoTClient | 42:448eecc3676e | 137 | } |
AzureIoTClient | 42:448eecc3676e | 138 | HTTPAPIEX_Destroy(httpApiExHandle); |
AzureIoTClient | 42:448eecc3676e | 139 | } |
AzureIoTClient | 42:448eecc3676e | 140 | free(hostname); |
AzureIoTClient | 42:448eecc3676e | 141 | } |
AzureIoTClient | 42:448eecc3676e | 142 | } |
AzureIoTClient | 42:448eecc3676e | 143 | } |
AzureIoTClient | 42:448eecc3676e | 144 | } |
AzureIoTClient | 42:448eecc3676e | 145 | } |
AzureIoTClient | 42:448eecc3676e | 146 | return result; |
AzureIoTClient | 42:448eecc3676e | 147 | } |