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

Committer:
AzureIoTClient
Date:
Fri Nov 17 13:57:39 2017 -0800
Revision:
79:bb88037c05e6
Parent:
62:5a4cdacf5090
Child:
80:db5f5237bc95
1.1.28

Who changed what in which revision?

UserRevisionLine numberNew 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 62:5a4cdacf5090 5 #include <stdint.h>
AzureIoTClient 42:448eecc3676e 6 #include "azure_c_shared_utility/gballoc.h"
AzureIoTClient 42:448eecc3676e 7 #include "blob.h"
AzureIoTClient 42:448eecc3676e 8
AzureIoTClient 42:448eecc3676e 9 #include "azure_c_shared_utility/httpapiex.h"
Azure.IoT Build 45:54c11b1b1407 10 #include "azure_c_shared_utility/xlogging.h"
AzureIoTClient 43:038d8511e817 11 #include "azure_c_shared_utility/base64.h"
AzureIoTClient 79:bb88037c05e6 12 #include "azure_c_shared_utility/shared_util_options.h"
AzureIoTClient 43:038d8511e817 13
AzureIoTClient 43:038d8511e817 14 /*a block has 4MB*/
AzureIoTClient 43:038d8511e817 15 #define BLOCK_SIZE (4*1024*1024)
AzureIoTClient 42:448eecc3676e 16
AzureIoTClient 79:bb88037c05e6 17 BLOB_RESULT Blob_UploadFromSasUri(const char* SASURI, const unsigned char* source, size_t size, unsigned int* httpStatus, BUFFER_HANDLE httpResponse, const char* certificates, HTTP_PROXY_OPTIONS *proxyOptions)
AzureIoTClient 42:448eecc3676e 18 {
AzureIoTClient 42:448eecc3676e 19 BLOB_RESULT result;
AzureIoTClient 42:448eecc3676e 20 /*Codes_SRS_BLOB_02_001: [ If SASURI is NULL then Blob_UploadFromSasUri shall fail and return BLOB_INVALID_ARG. ]*/
AzureIoTClient 42:448eecc3676e 21 if (SASURI == NULL)
AzureIoTClient 42:448eecc3676e 22 {
AzureIoTClient 42:448eecc3676e 23 LogError("parameter SASURI is NULL");
AzureIoTClient 42:448eecc3676e 24 result = BLOB_INVALID_ARG;
AzureIoTClient 42:448eecc3676e 25 }
AzureIoTClient 42:448eecc3676e 26 else
AzureIoTClient 42:448eecc3676e 27 {
AzureIoTClient 42:448eecc3676e 28 /*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 29 if (
AzureIoTClient 42:448eecc3676e 30 (size > 0) &&
AzureIoTClient 42:448eecc3676e 31 (source == NULL)
AzureIoTClient 43:038d8511e817 32 )
AzureIoTClient 42:448eecc3676e 33 {
AzureIoTClient 43:038d8511e817 34 LogError("combination of source = %p and size = %zu is invalid", source, size);
AzureIoTClient 42:448eecc3676e 35 result = BLOB_INVALID_ARG;
AzureIoTClient 42:448eecc3676e 36 }
AzureIoTClient 62:5a4cdacf5090 37 /*the below define avoid a "condition always false" on some compilers*/
AzureIoTClient 62:5a4cdacf5090 38 #if SIZE_MAX>UINT32_MAX
AzureIoTClient 43:038d8511e817 39 /*Codes_SRS_BLOB_02_034: [ If size is bigger than 50000*4*1024*1024 then Blob_UploadFromSasUri shall fail and return BLOB_INVALID_ARG. ]*/
AzureIoTClient 62:5a4cdacf5090 40 else if (size > 4 * 1024 * 1024 * 50000ULL) /*https://msdn.microsoft.com/en-us/library/azure/dd179467.aspx says "Each block can be a different size, up to a maximum of 4 MB, and a block blob can include a maximum of 50,000 blocks."*/
AzureIoTClient 42:448eecc3676e 41 {
AzureIoTClient 43:038d8511e817 42 LogError("size too big (%zu)", size);
AzureIoTClient 43:038d8511e817 43 result = BLOB_INVALID_ARG;
AzureIoTClient 42:448eecc3676e 44 }
AzureIoTClient 62:5a4cdacf5090 45 #endif
AzureIoTClient 42:448eecc3676e 46 else
AzureIoTClient 42:448eecc3676e 47 {
AzureIoTClient 43:038d8511e817 48 /*Codes_SRS_BLOB_02_017: [ Blob_UploadFromSasUri shall copy from SASURI the hostname to a new const char* ]*/
AzureIoTClient 42:448eecc3676e 49 /*Codes_SRS_BLOB_02_004: [ Blob_UploadFromSasUri shall copy from SASURI the hostname to a new const char*. ]*/
AzureIoTClient 42:448eecc3676e 50 /*to find the hostname, the following logic is applied:*/
AzureIoTClient 42:448eecc3676e 51 /*the hostname starts at the first character after "://"*/
AzureIoTClient 42:448eecc3676e 52 /*the hostname ends at the first character before the next "/" after "://"*/
AzureIoTClient 42:448eecc3676e 53 const char* hostnameBegin = strstr(SASURI, "://");
AzureIoTClient 42:448eecc3676e 54 if (hostnameBegin == NULL)
AzureIoTClient 42:448eecc3676e 55 {
AzureIoTClient 42:448eecc3676e 56 /*Codes_SRS_BLOB_02_005: [ If the hostname cannot be determined, then Blob_UploadFromSasUri shall fail and return BLOB_INVALID_ARG. ]*/
AzureIoTClient 42:448eecc3676e 57 LogError("hostname cannot be determined");
AzureIoTClient 42:448eecc3676e 58 result = BLOB_INVALID_ARG;
AzureIoTClient 42:448eecc3676e 59 }
AzureIoTClient 42:448eecc3676e 60 else
AzureIoTClient 42:448eecc3676e 61 {
AzureIoTClient 42:448eecc3676e 62 hostnameBegin += 3; /*have to skip 3 characters which are "://"*/
AzureIoTClient 42:448eecc3676e 63 const char* hostnameEnd = strchr(hostnameBegin, '/');
AzureIoTClient 42:448eecc3676e 64 if (hostnameEnd == NULL)
AzureIoTClient 42:448eecc3676e 65 {
AzureIoTClient 42:448eecc3676e 66 /*Codes_SRS_BLOB_02_005: [ If the hostname cannot be determined, then Blob_UploadFromSasUri shall fail and return BLOB_INVALID_ARG. ]*/
AzureIoTClient 42:448eecc3676e 67 LogError("hostname cannot be determined");
AzureIoTClient 42:448eecc3676e 68 result = BLOB_INVALID_ARG;
AzureIoTClient 42:448eecc3676e 69 }
AzureIoTClient 42:448eecc3676e 70 else
AzureIoTClient 42:448eecc3676e 71 {
AzureIoTClient 42:448eecc3676e 72 size_t hostnameSize = hostnameEnd - hostnameBegin;
AzureIoTClient 42:448eecc3676e 73 char* hostname = (char*)malloc(hostnameSize + 1); /*+1 because of '\0' at the end*/
AzureIoTClient 42:448eecc3676e 74 if (hostname == NULL)
AzureIoTClient 42:448eecc3676e 75 {
AzureIoTClient 42:448eecc3676e 76 /*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 77 LogError("oom - out of memory");
AzureIoTClient 42:448eecc3676e 78 result = BLOB_ERROR;
AzureIoTClient 42:448eecc3676e 79 }
AzureIoTClient 42:448eecc3676e 80 else
AzureIoTClient 42:448eecc3676e 81 {
AzureIoTClient 42:448eecc3676e 82 HTTPAPIEX_HANDLE httpApiExHandle;
AzureIoTClient 58:15b0d29b2667 83 (void)memcpy(hostname, hostnameBegin, hostnameSize);
AzureIoTClient 42:448eecc3676e 84 hostname[hostnameSize] = '\0';
AzureIoTClient 42:448eecc3676e 85
AzureIoTClient 42:448eecc3676e 86 /*Codes_SRS_BLOB_02_006: [ Blob_UploadFromSasUri shall create a new HTTPAPI_EX_HANDLE by calling HTTPAPIEX_Create passing the hostname. ]*/
AzureIoTClient 43:038d8511e817 87 /*Codes_SRS_BLOB_02_018: [ Blob_UploadFromSasUri shall create a new HTTPAPI_EX_HANDLE by calling HTTPAPIEX_Create passing the hostname. ]*/
AzureIoTClient 42:448eecc3676e 88 httpApiExHandle = HTTPAPIEX_Create(hostname);
AzureIoTClient 42:448eecc3676e 89 if (httpApiExHandle == NULL)
AzureIoTClient 42:448eecc3676e 90 {
AzureIoTClient 42:448eecc3676e 91 /*Codes_SRS_BLOB_02_007: [ If HTTPAPIEX_Create fails then Blob_UploadFromSasUri shall fail and return BLOB_ERROR. ]*/
AzureIoTClient 42:448eecc3676e 92 LogError("unable to create a HTTPAPIEX_HANDLE");
AzureIoTClient 42:448eecc3676e 93 result = BLOB_ERROR;
AzureIoTClient 42:448eecc3676e 94 }
AzureIoTClient 42:448eecc3676e 95 else
AzureIoTClient 42:448eecc3676e 96 {
AzureIoTClient 62:5a4cdacf5090 97 if ((certificates != NULL)&& (HTTPAPIEX_SetOption(httpApiExHandle, "TrustedCerts", certificates) == HTTPAPIEX_ERROR))
AzureIoTClient 62:5a4cdacf5090 98 {
AzureIoTClient 62:5a4cdacf5090 99 LogError("failure in setting trusted certificates");
AzureIoTClient 62:5a4cdacf5090 100 result = BLOB_ERROR;
AzureIoTClient 62:5a4cdacf5090 101 }
AzureIoTClient 62:5a4cdacf5090 102 else
AzureIoTClient 62:5a4cdacf5090 103 {
AzureIoTClient 79:bb88037c05e6 104 if ((proxyOptions != NULL && proxyOptions->host_address != NULL) && HTTPAPIEX_SetOption(httpApiExHandle, OPTION_HTTP_PROXY, proxyOptions) == HTTPAPIEX_ERROR)
AzureIoTClient 79:bb88037c05e6 105 {
AzureIoTClient 79:bb88037c05e6 106 LogError("failure in setting proxy options");
AzureIoTClient 79:bb88037c05e6 107 result = BLOB_ERROR;
AzureIoTClient 79:bb88037c05e6 108 }
AzureIoTClient 79:bb88037c05e6 109 else
AzureIoTClient 42:448eecc3676e 110 {
AzureIoTClient 79:bb88037c05e6 111 /*Codes_SRS_BLOB_02_008: [ Blob_UploadFromSasUri shall compute the relative path of the request from the SASURI parameter. ]*/
AzureIoTClient 79:bb88037c05e6 112 /*Codes_SRS_BLOB_02_019: [ Blob_UploadFromSasUri shall compute the base relative path of the request from the SASURI parameter. ]*/
AzureIoTClient 79:bb88037c05e6 113 const char* relativePath = hostnameEnd; /*this is where the relative path begins in the SasUri*/
AzureIoTClient 79:bb88037c05e6 114
AzureIoTClient 79:bb88037c05e6 115 if (size < 64 * 1024 * 1024) /*code path for sizes <64MB*/
AzureIoTClient 42:448eecc3676e 116 {
AzureIoTClient 79:bb88037c05e6 117 /*Codes_SRS_BLOB_02_010: [ Blob_UploadFromSasUri shall create a BUFFER_HANDLE from source and size parameters. ]*/
AzureIoTClient 79:bb88037c05e6 118 BUFFER_HANDLE requestBuffer = BUFFER_create(source, size);
AzureIoTClient 79:bb88037c05e6 119 if (requestBuffer == NULL)
AzureIoTClient 43:038d8511e817 120 {
AzureIoTClient 43:038d8511e817 121 /*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 79:bb88037c05e6 122 LogError("unable to BUFFER_create");
AzureIoTClient 43:038d8511e817 123 result = BLOB_ERROR;
AzureIoTClient 43:038d8511e817 124 }
AzureIoTClient 43:038d8511e817 125 else
AzureIoTClient 42:448eecc3676e 126 {
AzureIoTClient 79:bb88037c05e6 127 /*Codes_SRS_BLOB_02_009: [ Blob_UploadFromSasUri shall create an HTTP_HEADERS_HANDLE for the request HTTP headers carrying the following headers: ]*/
AzureIoTClient 79:bb88037c05e6 128 HTTP_HEADERS_HANDLE requestHttpHeaders = HTTPHeaders_Alloc();
AzureIoTClient 79:bb88037c05e6 129 if (requestHttpHeaders == NULL)
AzureIoTClient 43:038d8511e817 130 {
AzureIoTClient 62:5a4cdacf5090 131 /*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 79:bb88037c05e6 132 LogError("unable to HTTPHeaders_Alloc");
AzureIoTClient 62:5a4cdacf5090 133 result = BLOB_ERROR;
AzureIoTClient 43:038d8511e817 134 }
AzureIoTClient 43:038d8511e817 135 else
AzureIoTClient 43:038d8511e817 136 {
AzureIoTClient 79:bb88037c05e6 137 if (HTTPHeaders_AddHeaderNameValuePair(requestHttpHeaders, "x-ms-blob-type", "BlockBlob") != HTTP_HEADERS_OK)
AzureIoTClient 62:5a4cdacf5090 138 {
AzureIoTClient 79:bb88037c05e6 139 /*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 79:bb88037c05e6 140 LogError("unable to HTTPHeaders_AddHeaderNameValuePair");
AzureIoTClient 79:bb88037c05e6 141 result = BLOB_ERROR;
AzureIoTClient 62:5a4cdacf5090 142 }
AzureIoTClient 62:5a4cdacf5090 143 else
AzureIoTClient 62:5a4cdacf5090 144 {
AzureIoTClient 79:bb88037c05e6 145 /*Codes_SRS_BLOB_02_012: [ Blob_UploadFromSasUri shall call HTTPAPIEX_ExecuteRequest passing the parameters previously build, httpStatus and httpResponse ]*/
AzureIoTClient 79:bb88037c05e6 146 if (HTTPAPIEX_ExecuteRequest(httpApiExHandle, HTTPAPI_REQUEST_PUT, relativePath, requestHttpHeaders, requestBuffer, httpStatus, NULL, httpResponse) != HTTPAPIEX_OK)
AzureIoTClient 79:bb88037c05e6 147 {
AzureIoTClient 79:bb88037c05e6 148 /*Codes_SRS_BLOB_02_013: [ If HTTPAPIEX_ExecuteRequest fails, then Blob_UploadFromSasUri shall fail and return BLOB_HTTP_ERROR. ]*/
AzureIoTClient 79:bb88037c05e6 149 LogError("failed to HTTPAPIEX_ExecuteRequest");
AzureIoTClient 79:bb88037c05e6 150 result = BLOB_HTTP_ERROR;
AzureIoTClient 79:bb88037c05e6 151 }
AzureIoTClient 79:bb88037c05e6 152 else
AzureIoTClient 79:bb88037c05e6 153 {
AzureIoTClient 79:bb88037c05e6 154 /*Codes_SRS_BLOB_02_015: [ Otherwise, HTTPAPIEX_ExecuteRequest shall succeed and return BLOB_OK. ]*/
AzureIoTClient 79:bb88037c05e6 155 result = BLOB_OK;
AzureIoTClient 79:bb88037c05e6 156 }
AzureIoTClient 62:5a4cdacf5090 157 }
AzureIoTClient 79:bb88037c05e6 158 HTTPHeaders_Free(requestHttpHeaders);
AzureIoTClient 43:038d8511e817 159 }
AzureIoTClient 79:bb88037c05e6 160 BUFFER_delete(requestBuffer);
AzureIoTClient 43:038d8511e817 161 }
AzureIoTClient 43:038d8511e817 162 }
AzureIoTClient 79:bb88037c05e6 163 else /*code path for size >= 64MB*/
AzureIoTClient 43:038d8511e817 164 {
AzureIoTClient 79:bb88037c05e6 165 size_t toUpload = size;
AzureIoTClient 79:bb88037c05e6 166 /*Codes_SRS_BLOB_02_028: [ Blob_UploadFromSasUri shall construct an XML string with the following content: ]*/
AzureIoTClient 79:bb88037c05e6 167 STRING_HANDLE xml = STRING_construct("<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<BlockList>"); /*the XML "build as we go"*/
AzureIoTClient 79:bb88037c05e6 168 if (xml == NULL)
AzureIoTClient 79:bb88037c05e6 169 {
AzureIoTClient 79:bb88037c05e6 170 /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadFromSasUri shall fail and return BLOB_ERROR ]*/
AzureIoTClient 79:bb88037c05e6 171 LogError("failed to STRING_construct");
AzureIoTClient 79:bb88037c05e6 172 result = BLOB_HTTP_ERROR;
AzureIoTClient 79:bb88037c05e6 173 }
AzureIoTClient 79:bb88037c05e6 174 else
AzureIoTClient 43:038d8511e817 175 {
AzureIoTClient 79:bb88037c05e6 176 /*Codes_SRS_BLOB_02_021: [ For every block of 4MB the following operations shall happen: ]*/
AzureIoTClient 79:bb88037c05e6 177 unsigned int blockID = 0;
AzureIoTClient 79:bb88037c05e6 178 result = BLOB_ERROR;
AzureIoTClient 79:bb88037c05e6 179
AzureIoTClient 79:bb88037c05e6 180 int isError = 0; /*used to cleanly exit the loop*/
AzureIoTClient 79:bb88037c05e6 181 do
AzureIoTClient 43:038d8511e817 182 {
AzureIoTClient 79:bb88037c05e6 183 /*setting this block size*/
AzureIoTClient 79:bb88037c05e6 184 size_t thisBlockSize = (toUpload > BLOCK_SIZE) ? BLOCK_SIZE : toUpload;
AzureIoTClient 79:bb88037c05e6 185 /*Codes_SRS_BLOB_02_020: [ Blob_UploadFromSasUri shall construct a BASE64 encoded string from the block ID (000000... 0499999) ]*/
AzureIoTClient 79:bb88037c05e6 186 char temp[7]; /*this will contain 000000... 049999*/
AzureIoTClient 79:bb88037c05e6 187 if (sprintf(temp, "%6u", (unsigned int)blockID) != 6) /*produces 000000... 049999*/
AzureIoTClient 43:038d8511e817 188 {
AzureIoTClient 43:038d8511e817 189 /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadFromSasUri shall fail and return BLOB_ERROR ]*/
AzureIoTClient 79:bb88037c05e6 190 LogError("failed to sprintf");
AzureIoTClient 43:038d8511e817 191 result = BLOB_ERROR;
AzureIoTClient 43:038d8511e817 192 isError = 1;
AzureIoTClient 43:038d8511e817 193 }
AzureIoTClient 43:038d8511e817 194 else
AzureIoTClient 43:038d8511e817 195 {
AzureIoTClient 79:bb88037c05e6 196 STRING_HANDLE blockIdString = Base64_Encode_Bytes((const unsigned char*)temp, 6);
AzureIoTClient 79:bb88037c05e6 197 if (blockIdString == NULL)
AzureIoTClient 43:038d8511e817 198 {
AzureIoTClient 43:038d8511e817 199 /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadFromSasUri shall fail and return BLOB_ERROR ]*/
AzureIoTClient 79:bb88037c05e6 200 LogError("unable to Base64_Encode_Bytes");
AzureIoTClient 43:038d8511e817 201 result = BLOB_ERROR;
AzureIoTClient 43:038d8511e817 202 isError = 1;
AzureIoTClient 43:038d8511e817 203 }
AzureIoTClient 43:038d8511e817 204 else
AzureIoTClient 43:038d8511e817 205 {
AzureIoTClient 79:bb88037c05e6 206 /*add the blockId base64 encoded to the XML*/
AzureIoTClient 79:bb88037c05e6 207 if (!(
AzureIoTClient 79:bb88037c05e6 208 (STRING_concat(xml, "<Latest>") == 0) &&
AzureIoTClient 79:bb88037c05e6 209 (STRING_concat_with_STRING(xml, blockIdString) == 0) &&
AzureIoTClient 79:bb88037c05e6 210 (STRING_concat(xml, "</Latest>") == 0)
AzureIoTClient 79:bb88037c05e6 211 ))
AzureIoTClient 43:038d8511e817 212 {
AzureIoTClient 43:038d8511e817 213 /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadFromSasUri shall fail and return BLOB_ERROR ]*/
AzureIoTClient 79:bb88037c05e6 214 LogError("unable to STRING_concat");
AzureIoTClient 43:038d8511e817 215 result = BLOB_ERROR;
AzureIoTClient 43:038d8511e817 216 isError = 1;
AzureIoTClient 43:038d8511e817 217 }
AzureIoTClient 43:038d8511e817 218 else
AzureIoTClient 43:038d8511e817 219 {
AzureIoTClient 79:bb88037c05e6 220 /*Codes_SRS_BLOB_02_022: [ Blob_UploadFromSasUri shall construct a new relativePath from following string: base relativePath + "&comp=block&blockid=BASE64 encoded string of blockId" ]*/
AzureIoTClient 79:bb88037c05e6 221 STRING_HANDLE newRelativePath = STRING_construct(relativePath);
AzureIoTClient 79:bb88037c05e6 222 if (newRelativePath == NULL)
AzureIoTClient 43:038d8511e817 223 {
AzureIoTClient 43:038d8511e817 224 /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadFromSasUri shall fail and return BLOB_ERROR ]*/
AzureIoTClient 79:bb88037c05e6 225 LogError("unable to STRING_construct");
AzureIoTClient 43:038d8511e817 226 result = BLOB_ERROR;
AzureIoTClient 43:038d8511e817 227 isError = 1;
AzureIoTClient 43:038d8511e817 228 }
AzureIoTClient 43:038d8511e817 229 else
AzureIoTClient 43:038d8511e817 230 {
AzureIoTClient 79:bb88037c05e6 231 if (!(
AzureIoTClient 79:bb88037c05e6 232 (STRING_concat(newRelativePath, "&comp=block&blockid=") == 0) &&
AzureIoTClient 79:bb88037c05e6 233 (STRING_concat_with_STRING(newRelativePath, blockIdString) == 0)
AzureIoTClient 79:bb88037c05e6 234 ))
AzureIoTClient 43:038d8511e817 235 {
AzureIoTClient 62:5a4cdacf5090 236 /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadFromSasUri shall fail and return BLOB_ERROR ]*/
AzureIoTClient 79:bb88037c05e6 237 LogError("unable to STRING concatenate");
AzureIoTClient 62:5a4cdacf5090 238 result = BLOB_ERROR;
AzureIoTClient 43:038d8511e817 239 isError = 1;
AzureIoTClient 43:038d8511e817 240 }
AzureIoTClient 43:038d8511e817 241 else
AzureIoTClient 43:038d8511e817 242 {
AzureIoTClient 79:bb88037c05e6 243 /*Codes_SRS_BLOB_02_023: [ Blob_UploadFromSasUri shall create a BUFFER_HANDLE from source and size parameters. ]*/
AzureIoTClient 79:bb88037c05e6 244 BUFFER_HANDLE requestContent = BUFFER_create(source + (size - toUpload), thisBlockSize);
AzureIoTClient 79:bb88037c05e6 245 if (requestContent == NULL)
AzureIoTClient 62:5a4cdacf5090 246 {
AzureIoTClient 79:bb88037c05e6 247 /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadFromSasUri shall fail and return BLOB_ERROR ]*/
AzureIoTClient 79:bb88037c05e6 248 LogError("unable to BUFFER_create");
AzureIoTClient 79:bb88037c05e6 249 result = BLOB_ERROR;
AzureIoTClient 62:5a4cdacf5090 250 isError = 1;
AzureIoTClient 62:5a4cdacf5090 251 }
AzureIoTClient 62:5a4cdacf5090 252 else
AzureIoTClient 62:5a4cdacf5090 253 {
AzureIoTClient 79:bb88037c05e6 254 /*Codes_SRS_BLOB_02_024: [ Blob_UploadFromSasUri shall call HTTPAPIEX_ExecuteRequest with a PUT operation, passing httpStatus and httpResponse. ]*/
AzureIoTClient 79:bb88037c05e6 255 if (HTTPAPIEX_ExecuteRequest(
AzureIoTClient 79:bb88037c05e6 256 httpApiExHandle,
AzureIoTClient 79:bb88037c05e6 257 HTTPAPI_REQUEST_PUT,
AzureIoTClient 79:bb88037c05e6 258 STRING_c_str(newRelativePath),
AzureIoTClient 79:bb88037c05e6 259 NULL,
AzureIoTClient 79:bb88037c05e6 260 requestContent,
AzureIoTClient 79:bb88037c05e6 261 httpStatus,
AzureIoTClient 79:bb88037c05e6 262 NULL,
AzureIoTClient 79:bb88037c05e6 263 httpResponse) != HTTPAPIEX_OK
AzureIoTClient 79:bb88037c05e6 264 )
AzureIoTClient 79:bb88037c05e6 265 {
AzureIoTClient 79:bb88037c05e6 266 /*Codes_SRS_BLOB_02_025: [ If HTTPAPIEX_ExecuteRequest fails then Blob_UploadFromSasUri shall fail and return BLOB_HTTP_ERROR. ]*/
AzureIoTClient 79:bb88037c05e6 267 LogError("unable to HTTPAPIEX_ExecuteRequest");
AzureIoTClient 79:bb88037c05e6 268 result = BLOB_HTTP_ERROR;
AzureIoTClient 79:bb88037c05e6 269 isError = 1;
AzureIoTClient 79:bb88037c05e6 270 }
AzureIoTClient 79:bb88037c05e6 271 else if (*httpStatus >= 300)
AzureIoTClient 79:bb88037c05e6 272 {
AzureIoTClient 79:bb88037c05e6 273 /*Codes_SRS_BLOB_02_026: [ Otherwise, if HTTP response code is >=300 then Blob_UploadFromSasUri shall succeed and return BLOB_OK. ]*/
AzureIoTClient 79:bb88037c05e6 274 LogError("HTTP status from storage does not indicate success (%d)", (int)*httpStatus);
AzureIoTClient 79:bb88037c05e6 275 result = BLOB_OK;
AzureIoTClient 79:bb88037c05e6 276 isError = 1;
AzureIoTClient 79:bb88037c05e6 277 }
AzureIoTClient 79:bb88037c05e6 278 else
AzureIoTClient 79:bb88037c05e6 279 {
AzureIoTClient 79:bb88037c05e6 280 /*Codes_SRS_BLOB_02_027: [ Otherwise Blob_UploadFromSasUri shall continue execution. ]*/
AzureIoTClient 79:bb88037c05e6 281 }
AzureIoTClient 79:bb88037c05e6 282 BUFFER_delete(requestContent);
AzureIoTClient 62:5a4cdacf5090 283 }
AzureIoTClient 43:038d8511e817 284 }
AzureIoTClient 79:bb88037c05e6 285 STRING_delete(newRelativePath);
AzureIoTClient 43:038d8511e817 286 }
AzureIoTClient 43:038d8511e817 287 }
AzureIoTClient 79:bb88037c05e6 288 STRING_delete(blockIdString);
AzureIoTClient 43:038d8511e817 289 }
AzureIoTClient 43:038d8511e817 290 }
AzureIoTClient 43:038d8511e817 291
AzureIoTClient 79:bb88037c05e6 292 blockID++;
AzureIoTClient 79:bb88037c05e6 293 toUpload -= thisBlockSize;
AzureIoTClient 79:bb88037c05e6 294 } while ((toUpload > 0) && !isError);
AzureIoTClient 43:038d8511e817 295
AzureIoTClient 79:bb88037c05e6 296 if (isError)
AzureIoTClient 43:038d8511e817 297 {
AzureIoTClient 79:bb88037c05e6 298 /*do nothing, it will be reported "as is"*/
AzureIoTClient 43:038d8511e817 299 }
AzureIoTClient 43:038d8511e817 300 else
AzureIoTClient 43:038d8511e817 301 {
AzureIoTClient 79:bb88037c05e6 302 /*complete the XML*/
AzureIoTClient 79:bb88037c05e6 303 if (STRING_concat(xml, "</BlockList>") != 0)
AzureIoTClient 43:038d8511e817 304 {
AzureIoTClient 43:038d8511e817 305 /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadFromSasUri shall fail and return BLOB_ERROR ]*/
AzureIoTClient 79:bb88037c05e6 306 LogError("failed to STRING_concat");
AzureIoTClient 43:038d8511e817 307 result = BLOB_ERROR;
AzureIoTClient 43:038d8511e817 308 }
AzureIoTClient 43:038d8511e817 309 else
AzureIoTClient 43:038d8511e817 310 {
AzureIoTClient 79:bb88037c05e6 311 /*Codes_SRS_BLOB_02_029: [Blob_UploadFromSasUri shall construct a new relativePath from following string : base relativePath + "&comp=blocklist"]*/
AzureIoTClient 79:bb88037c05e6 312 STRING_HANDLE newRelativePath = STRING_construct(relativePath);
AzureIoTClient 79:bb88037c05e6 313 if (newRelativePath == NULL)
AzureIoTClient 43:038d8511e817 314 {
AzureIoTClient 43:038d8511e817 315 /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadFromSasUri shall fail and return BLOB_ERROR ]*/
AzureIoTClient 79:bb88037c05e6 316 LogError("failed to STRING_construct");
AzureIoTClient 43:038d8511e817 317 result = BLOB_ERROR;
AzureIoTClient 43:038d8511e817 318 }
AzureIoTClient 43:038d8511e817 319 else
AzureIoTClient 43:038d8511e817 320 {
AzureIoTClient 79:bb88037c05e6 321 if (STRING_concat(newRelativePath, "&comp=blocklist") != 0)
AzureIoTClient 43:038d8511e817 322 {
AzureIoTClient 62:5a4cdacf5090 323 /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadFromSasUri shall fail and return BLOB_ERROR ]*/
AzureIoTClient 79:bb88037c05e6 324 LogError("failed to STRING_concat");
AzureIoTClient 62:5a4cdacf5090 325 result = BLOB_ERROR;
AzureIoTClient 43:038d8511e817 326 }
AzureIoTClient 43:038d8511e817 327 else
AzureIoTClient 43:038d8511e817 328 {
AzureIoTClient 79:bb88037c05e6 329 /*Codes_SRS_BLOB_02_030: [ Blob_UploadFromSasUri shall call HTTPAPIEX_ExecuteRequest with a PUT operation, passing the new relativePath, httpStatus and httpResponse and the XML string as content. ]*/
AzureIoTClient 79:bb88037c05e6 330 const char* s = STRING_c_str(xml);
AzureIoTClient 79:bb88037c05e6 331 BUFFER_HANDLE xmlAsBuffer = BUFFER_create((const unsigned char*)s, strlen(s));
AzureIoTClient 79:bb88037c05e6 332 if (xmlAsBuffer == NULL)
AzureIoTClient 62:5a4cdacf5090 333 {
AzureIoTClient 79:bb88037c05e6 334 /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadFromSasUri shall fail and return BLOB_ERROR ]*/
AzureIoTClient 79:bb88037c05e6 335 LogError("failed to BUFFER_create");
AzureIoTClient 79:bb88037c05e6 336 result = BLOB_ERROR;
AzureIoTClient 62:5a4cdacf5090 337 }
AzureIoTClient 62:5a4cdacf5090 338 else
AzureIoTClient 62:5a4cdacf5090 339 {
AzureIoTClient 79:bb88037c05e6 340 if (HTTPAPIEX_ExecuteRequest(
AzureIoTClient 79:bb88037c05e6 341 httpApiExHandle,
AzureIoTClient 79:bb88037c05e6 342 HTTPAPI_REQUEST_PUT,
AzureIoTClient 79:bb88037c05e6 343 STRING_c_str(newRelativePath),
AzureIoTClient 79:bb88037c05e6 344 NULL,
AzureIoTClient 79:bb88037c05e6 345 xmlAsBuffer,
AzureIoTClient 79:bb88037c05e6 346 httpStatus,
AzureIoTClient 79:bb88037c05e6 347 NULL,
AzureIoTClient 79:bb88037c05e6 348 httpResponse
AzureIoTClient 79:bb88037c05e6 349 ) != HTTPAPIEX_OK)
AzureIoTClient 79:bb88037c05e6 350 {
AzureIoTClient 79:bb88037c05e6 351 /*Codes_SRS_BLOB_02_031: [ If HTTPAPIEX_ExecuteRequest fails then Blob_UploadFromSasUri shall fail and return BLOB_HTTP_ERROR. ]*/
AzureIoTClient 79:bb88037c05e6 352 LogError("unable to HTTPAPIEX_ExecuteRequest");
AzureIoTClient 79:bb88037c05e6 353 result = BLOB_HTTP_ERROR;
AzureIoTClient 79:bb88037c05e6 354 }
AzureIoTClient 79:bb88037c05e6 355 else
AzureIoTClient 79:bb88037c05e6 356 {
AzureIoTClient 79:bb88037c05e6 357 /*Codes_SRS_BLOB_02_032: [ Otherwise, Blob_UploadFromSasUri shall succeed and return BLOB_OK. ]*/
AzureIoTClient 79:bb88037c05e6 358 result = BLOB_OK;
AzureIoTClient 79:bb88037c05e6 359 }
AzureIoTClient 79:bb88037c05e6 360 BUFFER_delete(xmlAsBuffer);
AzureIoTClient 62:5a4cdacf5090 361 }
AzureIoTClient 43:038d8511e817 362 }
AzureIoTClient 79:bb88037c05e6 363 STRING_delete(newRelativePath);
AzureIoTClient 43:038d8511e817 364 }
AzureIoTClient 43:038d8511e817 365 }
AzureIoTClient 43:038d8511e817 366 }
AzureIoTClient 79:bb88037c05e6 367 STRING_delete(xml);
AzureIoTClient 42:448eecc3676e 368 }
AzureIoTClient 42:448eecc3676e 369 }
AzureIoTClient 42:448eecc3676e 370 }
AzureIoTClient 42:448eecc3676e 371 }
AzureIoTClient 42:448eecc3676e 372 HTTPAPIEX_Destroy(httpApiExHandle);
AzureIoTClient 42:448eecc3676e 373 }
AzureIoTClient 42:448eecc3676e 374 free(hostname);
AzureIoTClient 42:448eecc3676e 375 }
AzureIoTClient 42:448eecc3676e 376 }
AzureIoTClient 42:448eecc3676e 377 }
AzureIoTClient 42:448eecc3676e 378 }
AzureIoTClient 42:448eecc3676e 379 }
AzureIoTClient 42:448eecc3676e 380 return result;
AzureIoTClient 42:448eecc3676e 381 }