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:
Azure.IoT Build
Date:
Fri Jul 01 10:42:36 2016 -0700
Revision:
45:54c11b1b1407
Parent:
43:038d8511e817
Child:
46:6a69294b6119
1.0.10

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