Xin Zhang / azure-iot-c-sdk-f767zi

Dependents:   samplemqtt

Committer:
XinZhangMS
Date:
Thu Aug 23 06:52:14 2018 +0000
Revision:
0:f7f1f0d76dd6
azure-c-sdk for mbed os supporting NUCLEO_F767ZI

Who changed what in which revision?

UserRevisionLine numberNew contents of line
XinZhangMS 0:f7f1f0d76dd6 1 // Copyright (c) Microsoft. All rights reserved.
XinZhangMS 0:f7f1f0d76dd6 2 // Licensed under the MIT license. See LICENSE file in the project root for full license information.
XinZhangMS 0:f7f1f0d76dd6 3
XinZhangMS 0:f7f1f0d76dd6 4 #ifdef DONT_USE_UPLOADTOBLOB
XinZhangMS 0:f7f1f0d76dd6 5 #error "trying to compile iothub_client_ll_uploadtoblob.c while the symbol DONT_USE_UPLOADTOBLOB is #define'd"
XinZhangMS 0:f7f1f0d76dd6 6 #else
XinZhangMS 0:f7f1f0d76dd6 7
XinZhangMS 0:f7f1f0d76dd6 8 #include <stdlib.h>
XinZhangMS 0:f7f1f0d76dd6 9 #include <string.h>
XinZhangMS 0:f7f1f0d76dd6 10 #include "azure_c_shared_utility/optimize_size.h"
XinZhangMS 0:f7f1f0d76dd6 11 #include "azure_c_shared_utility/gballoc.h"
XinZhangMS 0:f7f1f0d76dd6 12 #include "azure_c_shared_utility/string_tokenizer.h"
XinZhangMS 0:f7f1f0d76dd6 13 #include "azure_c_shared_utility/doublylinkedlist.h"
XinZhangMS 0:f7f1f0d76dd6 14 #include "azure_c_shared_utility/xlogging.h"
XinZhangMS 0:f7f1f0d76dd6 15 #include "azure_c_shared_utility/tickcounter.h"
XinZhangMS 0:f7f1f0d76dd6 16 #include "azure_c_shared_utility/httpapiexsas.h"
XinZhangMS 0:f7f1f0d76dd6 17 #include "azure_c_shared_utility/shared_util_options.h"
XinZhangMS 0:f7f1f0d76dd6 18 #include "azure_c_shared_utility/urlencode.h"
XinZhangMS 0:f7f1f0d76dd6 19
XinZhangMS 0:f7f1f0d76dd6 20 #include "iothub_client_core_ll.h"
XinZhangMS 0:f7f1f0d76dd6 21 #include "iothub_client_options.h"
XinZhangMS 0:f7f1f0d76dd6 22 #include "internal/iothub_client_private.h"
XinZhangMS 0:f7f1f0d76dd6 23 #include "iothub_client_version.h"
XinZhangMS 0:f7f1f0d76dd6 24 #include "iothub_transport_ll.h"
XinZhangMS 0:f7f1f0d76dd6 25 #include "parson.h"
XinZhangMS 0:f7f1f0d76dd6 26 #include "internal/iothub_client_ll_uploadtoblob.h"
XinZhangMS 0:f7f1f0d76dd6 27 #include "internal/blob.h"
XinZhangMS 0:f7f1f0d76dd6 28
XinZhangMS 0:f7f1f0d76dd6 29 #ifdef WINCE
XinZhangMS 0:f7f1f0d76dd6 30 #include <stdarg.h>
XinZhangMS 0:f7f1f0d76dd6 31 // Returns number of characters copied.
XinZhangMS 0:f7f1f0d76dd6 32 int snprintf(char * s, size_t n, const char * format, ...)
XinZhangMS 0:f7f1f0d76dd6 33 {
XinZhangMS 0:f7f1f0d76dd6 34 int result;
XinZhangMS 0:f7f1f0d76dd6 35 va_list args;
XinZhangMS 0:f7f1f0d76dd6 36 va_start(args, format);
XinZhangMS 0:f7f1f0d76dd6 37 result = vsnprintf(s, n, format, args);
XinZhangMS 0:f7f1f0d76dd6 38 va_end(args);
XinZhangMS 0:f7f1f0d76dd6 39 return result;
XinZhangMS 0:f7f1f0d76dd6 40 }
XinZhangMS 0:f7f1f0d76dd6 41 #endif
XinZhangMS 0:f7f1f0d76dd6 42
XinZhangMS 0:f7f1f0d76dd6 43
XinZhangMS 0:f7f1f0d76dd6 44 /*Codes_SRS_IOTHUBCLIENT_LL_02_085: [ IoTHubClient_LL_UploadToBlob shall use the same authorization as step 1. to prepare and perform a HTTP request with the following parameters: ]*/
XinZhangMS 0:f7f1f0d76dd6 45 #define FILE_UPLOAD_FAILED_BODY "{ \"isSuccess\":false, \"statusCode\":-1,\"statusDescription\" : \"client not able to connect with the server\" }"
XinZhangMS 0:f7f1f0d76dd6 46 #define FILE_UPLOAD_ABORTED_BODY "{ \"isSuccess\":false, \"statusCode\":-1,\"statusDescription\" : \"file upload aborted\" }"
XinZhangMS 0:f7f1f0d76dd6 47
XinZhangMS 0:f7f1f0d76dd6 48 #define AUTHORIZATION_SCHEME_VALUES \
XinZhangMS 0:f7f1f0d76dd6 49 DEVICE_KEY, \
XinZhangMS 0:f7f1f0d76dd6 50 X509, \
XinZhangMS 0:f7f1f0d76dd6 51 SAS_TOKEN
XinZhangMS 0:f7f1f0d76dd6 52 DEFINE_ENUM(AUTHORIZATION_SCHEME, AUTHORIZATION_SCHEME_VALUES);
XinZhangMS 0:f7f1f0d76dd6 53
XinZhangMS 0:f7f1f0d76dd6 54 typedef struct UPLOADTOBLOB_X509_CREDENTIALS_TAG
XinZhangMS 0:f7f1f0d76dd6 55 {
XinZhangMS 0:f7f1f0d76dd6 56 const char* x509certificate;
XinZhangMS 0:f7f1f0d76dd6 57 const char* x509privatekey;
XinZhangMS 0:f7f1f0d76dd6 58 }UPLOADTOBLOB_X509_CREDENTIALS;
XinZhangMS 0:f7f1f0d76dd6 59
XinZhangMS 0:f7f1f0d76dd6 60 typedef struct IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE_DATA_TAG
XinZhangMS 0:f7f1f0d76dd6 61 {
XinZhangMS 0:f7f1f0d76dd6 62 STRING_HANDLE deviceId; /*needed for file upload*/
XinZhangMS 0:f7f1f0d76dd6 63 const char* hostname; /*needed for file upload*/
XinZhangMS 0:f7f1f0d76dd6 64 AUTHORIZATION_SCHEME authorizationScheme; /*needed for file upload*/
XinZhangMS 0:f7f1f0d76dd6 65 union {
XinZhangMS 0:f7f1f0d76dd6 66 STRING_HANDLE deviceKey; /*used when authorizationScheme is DEVICE_KEY*/
XinZhangMS 0:f7f1f0d76dd6 67 STRING_HANDLE sas; /*used when authorizationScheme is SAS_TOKEN*/
XinZhangMS 0:f7f1f0d76dd6 68 UPLOADTOBLOB_X509_CREDENTIALS x509credentials; /*assumed to be used when both deviceKey and deviceSasToken are NULL*/
XinZhangMS 0:f7f1f0d76dd6 69 } credentials; /*needed for file upload*/
XinZhangMS 0:f7f1f0d76dd6 70 char* certificates; /*if there are any certificates used*/
XinZhangMS 0:f7f1f0d76dd6 71 HTTP_PROXY_OPTIONS http_proxy_options;
XinZhangMS 0:f7f1f0d76dd6 72 size_t curl_verbose;
XinZhangMS 0:f7f1f0d76dd6 73 size_t blob_upload_timeout_secs;
XinZhangMS 0:f7f1f0d76dd6 74 }IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE_DATA;
XinZhangMS 0:f7f1f0d76dd6 75
XinZhangMS 0:f7f1f0d76dd6 76 typedef struct BLOB_UPLOAD_CONTEXT_TAG
XinZhangMS 0:f7f1f0d76dd6 77 {
XinZhangMS 0:f7f1f0d76dd6 78 const unsigned char* blobSource; /* source to upload */
XinZhangMS 0:f7f1f0d76dd6 79 size_t blobSourceSize; /* size of the source */
XinZhangMS 0:f7f1f0d76dd6 80 size_t remainingSizeToUpload; /* size not yet uploaded */
XinZhangMS 0:f7f1f0d76dd6 81 }BLOB_UPLOAD_CONTEXT;
XinZhangMS 0:f7f1f0d76dd6 82
XinZhangMS 0:f7f1f0d76dd6 83 IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE IoTHubClient_LL_UploadToBlob_Create(const IOTHUB_CLIENT_CONFIG* config)
XinZhangMS 0:f7f1f0d76dd6 84 {
XinZhangMS 0:f7f1f0d76dd6 85 IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE_DATA* handleData = malloc(sizeof(IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE_DATA));
XinZhangMS 0:f7f1f0d76dd6 86 if (handleData == NULL)
XinZhangMS 0:f7f1f0d76dd6 87 {
XinZhangMS 0:f7f1f0d76dd6 88 LogError("oom - malloc");
XinZhangMS 0:f7f1f0d76dd6 89 /*return as is*/
XinZhangMS 0:f7f1f0d76dd6 90 }
XinZhangMS 0:f7f1f0d76dd6 91 else
XinZhangMS 0:f7f1f0d76dd6 92 {
XinZhangMS 0:f7f1f0d76dd6 93 size_t iotHubNameLength = strlen(config->iotHubName);
XinZhangMS 0:f7f1f0d76dd6 94 size_t iotHubSuffixLength = strlen(config->iotHubSuffix);
XinZhangMS 0:f7f1f0d76dd6 95 handleData->deviceId = STRING_construct(config->deviceId);
XinZhangMS 0:f7f1f0d76dd6 96 if (handleData->deviceId == NULL)
XinZhangMS 0:f7f1f0d76dd6 97 {
XinZhangMS 0:f7f1f0d76dd6 98 LogError("unable to STRING_construct");
XinZhangMS 0:f7f1f0d76dd6 99 free(handleData);
XinZhangMS 0:f7f1f0d76dd6 100 handleData = NULL;
XinZhangMS 0:f7f1f0d76dd6 101 }
XinZhangMS 0:f7f1f0d76dd6 102 else
XinZhangMS 0:f7f1f0d76dd6 103 {
XinZhangMS 0:f7f1f0d76dd6 104 handleData->hostname = malloc(iotHubNameLength + 1 + iotHubSuffixLength + 1); /*first +1 is because "." the second +1 is because \0*/
XinZhangMS 0:f7f1f0d76dd6 105 if (handleData->hostname == NULL)
XinZhangMS 0:f7f1f0d76dd6 106 {
XinZhangMS 0:f7f1f0d76dd6 107 LogError("malloc failed");
XinZhangMS 0:f7f1f0d76dd6 108 STRING_delete(handleData->deviceId);
XinZhangMS 0:f7f1f0d76dd6 109 free(handleData);
XinZhangMS 0:f7f1f0d76dd6 110 handleData = NULL;
XinZhangMS 0:f7f1f0d76dd6 111 }
XinZhangMS 0:f7f1f0d76dd6 112 else
XinZhangMS 0:f7f1f0d76dd6 113 {
XinZhangMS 0:f7f1f0d76dd6 114 char* insert_pos = (char*)handleData->hostname;
XinZhangMS 0:f7f1f0d76dd6 115 (void)memcpy((char*)insert_pos, config->iotHubName, iotHubNameLength);
XinZhangMS 0:f7f1f0d76dd6 116 insert_pos += iotHubNameLength;
XinZhangMS 0:f7f1f0d76dd6 117 *insert_pos = '.';
XinZhangMS 0:f7f1f0d76dd6 118 insert_pos += 1;
XinZhangMS 0:f7f1f0d76dd6 119 (void)memcpy(insert_pos, config->iotHubSuffix, iotHubSuffixLength); /*+1 will copy the \0 too*/
XinZhangMS 0:f7f1f0d76dd6 120 insert_pos += iotHubSuffixLength;
XinZhangMS 0:f7f1f0d76dd6 121 *insert_pos = '\0';
XinZhangMS 0:f7f1f0d76dd6 122
XinZhangMS 0:f7f1f0d76dd6 123 handleData->certificates = NULL;
XinZhangMS 0:f7f1f0d76dd6 124 memset(&(handleData->http_proxy_options), 0, sizeof(HTTP_PROXY_OPTIONS));
XinZhangMS 0:f7f1f0d76dd6 125 handleData->curl_verbose = 0;
XinZhangMS 0:f7f1f0d76dd6 126 handleData->blob_upload_timeout_secs = 0;
XinZhangMS 0:f7f1f0d76dd6 127
XinZhangMS 0:f7f1f0d76dd6 128 if ((config->deviceSasToken != NULL) && (config->deviceKey == NULL))
XinZhangMS 0:f7f1f0d76dd6 129 {
XinZhangMS 0:f7f1f0d76dd6 130 handleData->authorizationScheme = SAS_TOKEN;
XinZhangMS 0:f7f1f0d76dd6 131 handleData->credentials.sas = STRING_construct(config->deviceSasToken);
XinZhangMS 0:f7f1f0d76dd6 132 if (handleData->credentials.sas == NULL)
XinZhangMS 0:f7f1f0d76dd6 133 {
XinZhangMS 0:f7f1f0d76dd6 134 LogError("unable to STRING_construct");
XinZhangMS 0:f7f1f0d76dd6 135 free((void*)handleData->hostname);
XinZhangMS 0:f7f1f0d76dd6 136 STRING_delete(handleData->deviceId);
XinZhangMS 0:f7f1f0d76dd6 137 free(handleData);
XinZhangMS 0:f7f1f0d76dd6 138 handleData = NULL;
XinZhangMS 0:f7f1f0d76dd6 139 }
XinZhangMS 0:f7f1f0d76dd6 140 else
XinZhangMS 0:f7f1f0d76dd6 141 {
XinZhangMS 0:f7f1f0d76dd6 142 /*return as is*/
XinZhangMS 0:f7f1f0d76dd6 143 }
XinZhangMS 0:f7f1f0d76dd6 144 }
XinZhangMS 0:f7f1f0d76dd6 145 else if ((config->deviceSasToken == NULL) && (config->deviceKey != NULL))
XinZhangMS 0:f7f1f0d76dd6 146 {
XinZhangMS 0:f7f1f0d76dd6 147 handleData->authorizationScheme = DEVICE_KEY;
XinZhangMS 0:f7f1f0d76dd6 148 handleData->credentials.deviceKey = STRING_construct(config->deviceKey);
XinZhangMS 0:f7f1f0d76dd6 149 if (handleData->credentials.deviceKey == NULL)
XinZhangMS 0:f7f1f0d76dd6 150 {
XinZhangMS 0:f7f1f0d76dd6 151 LogError("unable to STRING_construct");
XinZhangMS 0:f7f1f0d76dd6 152 free((void*)handleData->hostname);
XinZhangMS 0:f7f1f0d76dd6 153 STRING_delete(handleData->deviceId);
XinZhangMS 0:f7f1f0d76dd6 154 free(handleData);
XinZhangMS 0:f7f1f0d76dd6 155 handleData = NULL;
XinZhangMS 0:f7f1f0d76dd6 156 }
XinZhangMS 0:f7f1f0d76dd6 157 else
XinZhangMS 0:f7f1f0d76dd6 158 {
XinZhangMS 0:f7f1f0d76dd6 159 /*return as is*/
XinZhangMS 0:f7f1f0d76dd6 160 }
XinZhangMS 0:f7f1f0d76dd6 161 }
XinZhangMS 0:f7f1f0d76dd6 162 else if ((config->deviceSasToken == NULL) && (config->deviceKey == NULL))
XinZhangMS 0:f7f1f0d76dd6 163 {
XinZhangMS 0:f7f1f0d76dd6 164 handleData->authorizationScheme = X509;
XinZhangMS 0:f7f1f0d76dd6 165 handleData->credentials.x509credentials.x509certificate = NULL;
XinZhangMS 0:f7f1f0d76dd6 166 handleData->credentials.x509credentials.x509privatekey = NULL;
XinZhangMS 0:f7f1f0d76dd6 167 /*return as is*/
XinZhangMS 0:f7f1f0d76dd6 168 }
XinZhangMS 0:f7f1f0d76dd6 169 }
XinZhangMS 0:f7f1f0d76dd6 170 }
XinZhangMS 0:f7f1f0d76dd6 171 }
XinZhangMS 0:f7f1f0d76dd6 172 return (IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE)handleData;
XinZhangMS 0:f7f1f0d76dd6 173
XinZhangMS 0:f7f1f0d76dd6 174 }
XinZhangMS 0:f7f1f0d76dd6 175
XinZhangMS 0:f7f1f0d76dd6 176 /*returns 0 when correlationId, sasUri contain data*/
XinZhangMS 0:f7f1f0d76dd6 177 static int IoTHubClient_LL_UploadToBlob_step1and2(IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE_DATA* handleData, HTTPAPIEX_HANDLE iotHubHttpApiExHandle, HTTP_HEADERS_HANDLE requestHttpHeaders, const char* destinationFileName,
XinZhangMS 0:f7f1f0d76dd6 178 STRING_HANDLE correlationId, STRING_HANDLE sasUri)
XinZhangMS 0:f7f1f0d76dd6 179 {
XinZhangMS 0:f7f1f0d76dd6 180 int result;
XinZhangMS 0:f7f1f0d76dd6 181
XinZhangMS 0:f7f1f0d76dd6 182 /*Codes_SRS_IOTHUBCLIENT_LL_02_066: [ IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall create an HTTP relative path formed from "/devices/" + deviceId + "/files/" + "?api-version=API_VERSION". ]*/
XinZhangMS 0:f7f1f0d76dd6 183 STRING_HANDLE relativePath = STRING_construct("/devices/");
XinZhangMS 0:f7f1f0d76dd6 184 if (relativePath == NULL)
XinZhangMS 0:f7f1f0d76dd6 185 {
XinZhangMS 0:f7f1f0d76dd6 186 /*Codes_SRS_IOTHUBCLIENT_LL_02_067: [ If creating the relativePath fails then IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall fail and return IOTHUB_CLIENT_ERROR. ]*/
XinZhangMS 0:f7f1f0d76dd6 187 LogError("unable to STRING_construct");
XinZhangMS 0:f7f1f0d76dd6 188 result = __FAILURE__;
XinZhangMS 0:f7f1f0d76dd6 189 }
XinZhangMS 0:f7f1f0d76dd6 190 else
XinZhangMS 0:f7f1f0d76dd6 191 {
XinZhangMS 0:f7f1f0d76dd6 192 if (!(
XinZhangMS 0:f7f1f0d76dd6 193 (STRING_concat_with_STRING(relativePath, handleData->deviceId) == 0) &&
XinZhangMS 0:f7f1f0d76dd6 194 (STRING_concat(relativePath, "/files") == 0) &&
XinZhangMS 0:f7f1f0d76dd6 195 (STRING_concat(relativePath, API_VERSION) == 0)
XinZhangMS 0:f7f1f0d76dd6 196 ))
XinZhangMS 0:f7f1f0d76dd6 197 {
XinZhangMS 0:f7f1f0d76dd6 198 /*Codes_SRS_IOTHUBCLIENT_LL_02_067: [ If creating the relativePath fails then IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall fail and return IOTHUB_CLIENT_ERROR. ]*/
XinZhangMS 0:f7f1f0d76dd6 199 LogError("unable to concatenate STRING");
XinZhangMS 0:f7f1f0d76dd6 200 result = __FAILURE__;
XinZhangMS 0:f7f1f0d76dd6 201 }
XinZhangMS 0:f7f1f0d76dd6 202 else
XinZhangMS 0:f7f1f0d76dd6 203 {
XinZhangMS 0:f7f1f0d76dd6 204 /*Codes_SRS_IOTHUBCLIENT_LL_32_001: [ IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall create a JSON string formed from "{ \"blobName\": \" + destinationFileName + "\" }" */
XinZhangMS 0:f7f1f0d76dd6 205 STRING_HANDLE blobName = STRING_construct("{ \"blobName\": \"");
XinZhangMS 0:f7f1f0d76dd6 206 if (blobName == NULL)
XinZhangMS 0:f7f1f0d76dd6 207 {
XinZhangMS 0:f7f1f0d76dd6 208 /*Codes_SRS_IOTHUBCLIENT_LL_32_002: [ If creating the JSON string fails then IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall fail and return IOTHUB_CLIENT_ERROR. ]*/
XinZhangMS 0:f7f1f0d76dd6 209 LogError("unable to STRING_construct");
XinZhangMS 0:f7f1f0d76dd6 210 result = __FAILURE__;
XinZhangMS 0:f7f1f0d76dd6 211 }
XinZhangMS 0:f7f1f0d76dd6 212 else
XinZhangMS 0:f7f1f0d76dd6 213 {
XinZhangMS 0:f7f1f0d76dd6 214 if (!(
XinZhangMS 0:f7f1f0d76dd6 215 (STRING_concat(blobName, destinationFileName) == 0) &&
XinZhangMS 0:f7f1f0d76dd6 216 (STRING_concat(blobName, "\" }") == 0)
XinZhangMS 0:f7f1f0d76dd6 217 ))
XinZhangMS 0:f7f1f0d76dd6 218 {
XinZhangMS 0:f7f1f0d76dd6 219 /*Codes_SRS_IOTHUBCLIENT_LL_32_002: [ If creating the JSON string fails then IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall fail and return IOTHUB_CLIENT_ERROR. ]*/
XinZhangMS 0:f7f1f0d76dd6 220 LogError("unable to concatenate STRING");
XinZhangMS 0:f7f1f0d76dd6 221 result = __FAILURE__;
XinZhangMS 0:f7f1f0d76dd6 222 }
XinZhangMS 0:f7f1f0d76dd6 223 else
XinZhangMS 0:f7f1f0d76dd6 224 {
XinZhangMS 0:f7f1f0d76dd6 225 size_t len = STRING_length(blobName);
XinZhangMS 0:f7f1f0d76dd6 226 BUFFER_HANDLE blobBuffer = BUFFER_create((const unsigned char *)STRING_c_str(blobName), len);
XinZhangMS 0:f7f1f0d76dd6 227
XinZhangMS 0:f7f1f0d76dd6 228 if (blobBuffer == NULL)
XinZhangMS 0:f7f1f0d76dd6 229 {
XinZhangMS 0:f7f1f0d76dd6 230 /*Codes_SRS_IOTHUBCLIENT_LL_32_002: [ If creating the JSON string fails then IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall fail and return IOTHUB_CLIENT_ERROR. ]*/
XinZhangMS 0:f7f1f0d76dd6 231 LogError("unable to create BUFFER");
XinZhangMS 0:f7f1f0d76dd6 232 result = __FAILURE__;
XinZhangMS 0:f7f1f0d76dd6 233 }
XinZhangMS 0:f7f1f0d76dd6 234 else
XinZhangMS 0:f7f1f0d76dd6 235 {
XinZhangMS 0:f7f1f0d76dd6 236 /*Codes_SRS_IOTHUBCLIENT_LL_02_068: [ IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall create an HTTP responseContent BUFFER_HANDLE. ]*/
XinZhangMS 0:f7f1f0d76dd6 237 BUFFER_HANDLE responseContent = BUFFER_new();
XinZhangMS 0:f7f1f0d76dd6 238 if (responseContent == NULL)
XinZhangMS 0:f7f1f0d76dd6 239 {
XinZhangMS 0:f7f1f0d76dd6 240 /*Codes_SRS_IOTHUBCLIENT_LL_02_069: [ If creating the HTTP response buffer handle fails then IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall fail and return IOTHUB_CLIENT_ERROR. ]*/
XinZhangMS 0:f7f1f0d76dd6 241 result = __FAILURE__;
XinZhangMS 0:f7f1f0d76dd6 242 LogError("unable to BUFFER_new");
XinZhangMS 0:f7f1f0d76dd6 243 }
XinZhangMS 0:f7f1f0d76dd6 244 else
XinZhangMS 0:f7f1f0d76dd6 245 {
XinZhangMS 0:f7f1f0d76dd6 246 /*Codes_SRS_IOTHUBCLIENT_LL_02_072: [ IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall add the following name:value to request HTTP headers: ] "Content-Type": "application/json" "Accept": "application/json" "User-Agent": "iothubclient/" IOTHUB_SDK_VERSION*/
XinZhangMS 0:f7f1f0d76dd6 247 /*Codes_SRS_IOTHUBCLIENT_LL_02_107: [ - "Authorization" header shall not be build. ]*/
XinZhangMS 0:f7f1f0d76dd6 248 if (!(
XinZhangMS 0:f7f1f0d76dd6 249 (HTTPHeaders_AddHeaderNameValuePair(requestHttpHeaders, "Content-Type", "application/json") == HTTP_HEADERS_OK) &&
XinZhangMS 0:f7f1f0d76dd6 250 (HTTPHeaders_AddHeaderNameValuePair(requestHttpHeaders, "Accept", "application/json") == HTTP_HEADERS_OK) &&
XinZhangMS 0:f7f1f0d76dd6 251 (HTTPHeaders_AddHeaderNameValuePair(requestHttpHeaders, "User-Agent", "iothubclient/" IOTHUB_SDK_VERSION) == HTTP_HEADERS_OK) &&
XinZhangMS 0:f7f1f0d76dd6 252 (handleData->authorizationScheme == X509 || (HTTPHeaders_AddHeaderNameValuePair(requestHttpHeaders, "Authorization", "") == HTTP_HEADERS_OK))
XinZhangMS 0:f7f1f0d76dd6 253 ))
XinZhangMS 0:f7f1f0d76dd6 254 {
XinZhangMS 0:f7f1f0d76dd6 255 /*Codes_SRS_IOTHUBCLIENT_LL_02_071: [ If creating the HTTP headers fails then IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall fail and return IOTHUB_CLIENT_ERROR. ]*/
XinZhangMS 0:f7f1f0d76dd6 256 LogError("unable to HTTPHeaders_AddHeaderNameValuePair");
XinZhangMS 0:f7f1f0d76dd6 257 result = __FAILURE__;
XinZhangMS 0:f7f1f0d76dd6 258 }
XinZhangMS 0:f7f1f0d76dd6 259 else
XinZhangMS 0:f7f1f0d76dd6 260 {
XinZhangMS 0:f7f1f0d76dd6 261 int wasIoTHubRequestSuccess = 0; /*!=0 means responseContent has a buffer that should be parsed by parson after executing the below switch*/
XinZhangMS 0:f7f1f0d76dd6 262 /* set the result to error by default */
XinZhangMS 0:f7f1f0d76dd6 263 result = __FAILURE__;
XinZhangMS 0:f7f1f0d76dd6 264 switch (handleData->authorizationScheme)
XinZhangMS 0:f7f1f0d76dd6 265 {
XinZhangMS 0:f7f1f0d76dd6 266 default:
XinZhangMS 0:f7f1f0d76dd6 267 {
XinZhangMS 0:f7f1f0d76dd6 268 /*wasIoTHubRequestSuccess takes care of the return value*/
XinZhangMS 0:f7f1f0d76dd6 269 LogError("Internal Error: unexpected value in handleData->authorizationScheme = %d", handleData->authorizationScheme);
XinZhangMS 0:f7f1f0d76dd6 270 result = __FAILURE__;
XinZhangMS 0:f7f1f0d76dd6 271 break;
XinZhangMS 0:f7f1f0d76dd6 272 }
XinZhangMS 0:f7f1f0d76dd6 273 case(X509):
XinZhangMS 0:f7f1f0d76dd6 274 {
XinZhangMS 0:f7f1f0d76dd6 275 unsigned int statusCode;
XinZhangMS 0:f7f1f0d76dd6 276 /*Codes_SRS_IOTHUBCLIENT_LL_32_003: [ IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall execute HTTPAPIEX_ExecuteRequest passing the following information for arguments: ]*/
XinZhangMS 0:f7f1f0d76dd6 277 if (HTTPAPIEX_ExecuteRequest(
XinZhangMS 0:f7f1f0d76dd6 278 iotHubHttpApiExHandle, /*HTTPAPIEX_HANDLE handle - the handle created at the beginning of `IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex)`*/
XinZhangMS 0:f7f1f0d76dd6 279 HTTPAPI_REQUEST_POST, /*HTTPAPI_REQUEST_TYPE requestType - HTTPAPI_REQUEST_POST*/
XinZhangMS 0:f7f1f0d76dd6 280 STRING_c_str(relativePath), /*const char* relativePath - the HTTP relative path*/
XinZhangMS 0:f7f1f0d76dd6 281 requestHttpHeaders, /*HTTP_HEADERS_HANDLE requestHttpHeadersHandle - request HTTP headers*/
XinZhangMS 0:f7f1f0d76dd6 282 blobBuffer, /*BUFFER_HANDLE requestContent - address of JSON with optional/directory/tree/filename*/
XinZhangMS 0:f7f1f0d76dd6 283 &statusCode, /*unsigned int* statusCode - the address of an unsigned int that will contain the HTTP status code*/
XinZhangMS 0:f7f1f0d76dd6 284 NULL, /*HTTP_HEADERS_HANDLE responseHttpHeadersHandle - NULL*/
XinZhangMS 0:f7f1f0d76dd6 285 responseContent /*BUFFER_HANDLE responseContent - the HTTP response BUFFER_HANDLE - responseContent*/
XinZhangMS 0:f7f1f0d76dd6 286 ) != HTTPAPIEX_OK)
XinZhangMS 0:f7f1f0d76dd6 287 {
XinZhangMS 0:f7f1f0d76dd6 288 /*Codes_SRS_IOTHUBCLIENT_LL_02_076: [ If HTTPAPIEX_ExecuteRequest call fails then IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall fail and return IOTHUB_CLIENT_ERROR. ]*/
XinZhangMS 0:f7f1f0d76dd6 289 result = __FAILURE__;
XinZhangMS 0:f7f1f0d76dd6 290 LogError("unable to HTTPAPIEX_ExecuteRequest");
XinZhangMS 0:f7f1f0d76dd6 291 }
XinZhangMS 0:f7f1f0d76dd6 292 else
XinZhangMS 0:f7f1f0d76dd6 293 {
XinZhangMS 0:f7f1f0d76dd6 294 /*Codes_SRS_IOTHUBCLIENT_LL_02_077: [ If HTTP statusCode is greater than or equal to 300 then IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall fail and return IOTHUB_CLIENT_ERROR. ]*/
XinZhangMS 0:f7f1f0d76dd6 295 if (statusCode >= 300)
XinZhangMS 0:f7f1f0d76dd6 296 {
XinZhangMS 0:f7f1f0d76dd6 297 result = __FAILURE__;
XinZhangMS 0:f7f1f0d76dd6 298 LogError("HTTP code was %u", statusCode);
XinZhangMS 0:f7f1f0d76dd6 299 }
XinZhangMS 0:f7f1f0d76dd6 300 else
XinZhangMS 0:f7f1f0d76dd6 301 {
XinZhangMS 0:f7f1f0d76dd6 302 wasIoTHubRequestSuccess = 1;
XinZhangMS 0:f7f1f0d76dd6 303 }
XinZhangMS 0:f7f1f0d76dd6 304 }
XinZhangMS 0:f7f1f0d76dd6 305 break;
XinZhangMS 0:f7f1f0d76dd6 306 }
XinZhangMS 0:f7f1f0d76dd6 307 case (SAS_TOKEN):
XinZhangMS 0:f7f1f0d76dd6 308 {
XinZhangMS 0:f7f1f0d76dd6 309 const char* sasToken = STRING_c_str(handleData->credentials.sas);
XinZhangMS 0:f7f1f0d76dd6 310 /*Codes_SRS_IOTHUBCLIENT_LL_02_073: [ If the credentials used to create handle have "sasToken" then IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall add the following HTTP request headers: ]*/
XinZhangMS 0:f7f1f0d76dd6 311 if (HTTPHeaders_ReplaceHeaderNameValuePair(requestHttpHeaders, "Authorization", sasToken) != HTTP_HEADERS_OK)
XinZhangMS 0:f7f1f0d76dd6 312 {
XinZhangMS 0:f7f1f0d76dd6 313 /*Codes_SRS_IOTHUBCLIENT_LL_02_074: [ If adding "Authorization" fails then IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall fail and return IOTHUB_CLIENT_ERROR ]*/
XinZhangMS 0:f7f1f0d76dd6 314 result = __FAILURE__;
XinZhangMS 0:f7f1f0d76dd6 315 LogError("unable to HTTPHeaders_AddHeaderNameValuePair");
XinZhangMS 0:f7f1f0d76dd6 316 }
XinZhangMS 0:f7f1f0d76dd6 317 else
XinZhangMS 0:f7f1f0d76dd6 318 {
XinZhangMS 0:f7f1f0d76dd6 319 unsigned int statusCode;
XinZhangMS 0:f7f1f0d76dd6 320 /*Codes_SRS_IOTHUBCLIENT_LL_32_004: [ IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall execute HTTPAPIEX_ExecuteRequest passing the following information for arguments: ]*/
XinZhangMS 0:f7f1f0d76dd6 321 if (HTTPAPIEX_ExecuteRequest(
XinZhangMS 0:f7f1f0d76dd6 322 iotHubHttpApiExHandle, /*HTTPAPIEX_HANDLE handle - the handle created at the beginning of `IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex)`*/
XinZhangMS 0:f7f1f0d76dd6 323 HTTPAPI_REQUEST_POST, /*HTTPAPI_REQUEST_TYPE requestType - HTTPAPI_REQUEST_POST*/
XinZhangMS 0:f7f1f0d76dd6 324 STRING_c_str(relativePath), /*const char* relativePath - the HTTP relative path*/
XinZhangMS 0:f7f1f0d76dd6 325 requestHttpHeaders, /*HTTP_HEADERS_HANDLE requestHttpHeadersHandle - request HTTP headers*/
XinZhangMS 0:f7f1f0d76dd6 326 blobBuffer, /*BUFFER_HANDLE requestContent - address of JSON with optional/directory/tree/filename*/
XinZhangMS 0:f7f1f0d76dd6 327 &statusCode, /*unsigned int* statusCode - the address of an unsigned int that will contain the HTTP status code*/
XinZhangMS 0:f7f1f0d76dd6 328 NULL, /*HTTP_HEADERS_HANDLE responseHttpHeadersHandle - NULL*/
XinZhangMS 0:f7f1f0d76dd6 329 responseContent /*BUFFER_HANDLE responseContent - the HTTP response BUFFER_HANDLE - responseContent*/
XinZhangMS 0:f7f1f0d76dd6 330 ) != HTTPAPIEX_OK)
XinZhangMS 0:f7f1f0d76dd6 331 {
XinZhangMS 0:f7f1f0d76dd6 332 /*Codes_SRS_IOTHUBCLIENT_LL_02_076: [ If HTTPAPIEX_ExecuteRequest call fails then IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall fail and return IOTHUB_CLIENT_ERROR. ]*/
XinZhangMS 0:f7f1f0d76dd6 333 result = __FAILURE__;
XinZhangMS 0:f7f1f0d76dd6 334 LogError("unable to HTTPAPIEX_ExecuteRequest");
XinZhangMS 0:f7f1f0d76dd6 335 }
XinZhangMS 0:f7f1f0d76dd6 336 else
XinZhangMS 0:f7f1f0d76dd6 337 {
XinZhangMS 0:f7f1f0d76dd6 338 /*Codes_SRS_IOTHUBCLIENT_LL_02_077: [ If HTTP statusCode is greater than or equal to 300 then IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall fail and return IOTHUB_CLIENT_ERROR. ]*/
XinZhangMS 0:f7f1f0d76dd6 339 if (statusCode >= 300)
XinZhangMS 0:f7f1f0d76dd6 340 {
XinZhangMS 0:f7f1f0d76dd6 341 result = __FAILURE__;
XinZhangMS 0:f7f1f0d76dd6 342 LogError("HTTP code was %u", statusCode);
XinZhangMS 0:f7f1f0d76dd6 343 }
XinZhangMS 0:f7f1f0d76dd6 344 else
XinZhangMS 0:f7f1f0d76dd6 345 {
XinZhangMS 0:f7f1f0d76dd6 346 wasIoTHubRequestSuccess = 1;
XinZhangMS 0:f7f1f0d76dd6 347 }
XinZhangMS 0:f7f1f0d76dd6 348 }
XinZhangMS 0:f7f1f0d76dd6 349 }
XinZhangMS 0:f7f1f0d76dd6 350 break;
XinZhangMS 0:f7f1f0d76dd6 351 }
XinZhangMS 0:f7f1f0d76dd6 352 case(DEVICE_KEY):
XinZhangMS 0:f7f1f0d76dd6 353 {
XinZhangMS 0:f7f1f0d76dd6 354 /*Codes_SRS_IOTHUBCLIENT_LL_02_078: [ If the credentials used to create handle have "deviceKey" then IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall create an HTTPAPIEX_SAS_HANDLE passing as arguments: ]*/
XinZhangMS 0:f7f1f0d76dd6 355 STRING_HANDLE uriResource = STRING_construct(handleData->hostname);
XinZhangMS 0:f7f1f0d76dd6 356 if (uriResource == NULL)
XinZhangMS 0:f7f1f0d76dd6 357 {
XinZhangMS 0:f7f1f0d76dd6 358 /*Codes_SRS_IOTHUBCLIENT_LL_02_089: [ If creating the HTTPAPIEX_SAS_HANDLE fails then IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall fail and return IOTHUB_CLIENT_ERROR. ]*/
XinZhangMS 0:f7f1f0d76dd6 359 result = __FAILURE__;
XinZhangMS 0:f7f1f0d76dd6 360 LogError("unable to STRING_construct");
XinZhangMS 0:f7f1f0d76dd6 361 }
XinZhangMS 0:f7f1f0d76dd6 362 else
XinZhangMS 0:f7f1f0d76dd6 363 {
XinZhangMS 0:f7f1f0d76dd6 364 if (!(
XinZhangMS 0:f7f1f0d76dd6 365 (STRING_concat(uriResource, "/devices/") == 0) &&
XinZhangMS 0:f7f1f0d76dd6 366 (STRING_concat_with_STRING(uriResource, handleData->deviceId) == 0)
XinZhangMS 0:f7f1f0d76dd6 367 ))
XinZhangMS 0:f7f1f0d76dd6 368 {
XinZhangMS 0:f7f1f0d76dd6 369 /*Codes_SRS_IOTHUBCLIENT_LL_02_089: [ If creating the HTTPAPIEX_SAS_HANDLE fails then IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall fail and return IOTHUB_CLIENT_ERROR. ]*/
XinZhangMS 0:f7f1f0d76dd6 370 LogError("unable to STRING_concat_with_STRING");
XinZhangMS 0:f7f1f0d76dd6 371 result = __FAILURE__;
XinZhangMS 0:f7f1f0d76dd6 372 }
XinZhangMS 0:f7f1f0d76dd6 373 else
XinZhangMS 0:f7f1f0d76dd6 374 {
XinZhangMS 0:f7f1f0d76dd6 375 STRING_HANDLE empty = STRING_new();
XinZhangMS 0:f7f1f0d76dd6 376 if (empty == NULL)
XinZhangMS 0:f7f1f0d76dd6 377 {
XinZhangMS 0:f7f1f0d76dd6 378 LogError("unable to STRING_new");
XinZhangMS 0:f7f1f0d76dd6 379 result = __FAILURE__;
XinZhangMS 0:f7f1f0d76dd6 380 }
XinZhangMS 0:f7f1f0d76dd6 381 else
XinZhangMS 0:f7f1f0d76dd6 382 {
XinZhangMS 0:f7f1f0d76dd6 383 /*Codes_SRS_IOTHUBCLIENT_LL_02_089: [ If creating the HTTPAPIEX_SAS_HANDLE fails then IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall fail and return IOTHUB_CLIENT_ERROR. ]*/
XinZhangMS 0:f7f1f0d76dd6 384 HTTPAPIEX_SAS_HANDLE sasHandle = HTTPAPIEX_SAS_Create(handleData->credentials.deviceKey, uriResource, empty);
XinZhangMS 0:f7f1f0d76dd6 385 if (sasHandle == NULL)
XinZhangMS 0:f7f1f0d76dd6 386 {
XinZhangMS 0:f7f1f0d76dd6 387 LogError("unable to HTTPAPIEX_SAS_Create");
XinZhangMS 0:f7f1f0d76dd6 388 result = __FAILURE__;
XinZhangMS 0:f7f1f0d76dd6 389 }
XinZhangMS 0:f7f1f0d76dd6 390 else
XinZhangMS 0:f7f1f0d76dd6 391 {
XinZhangMS 0:f7f1f0d76dd6 392 unsigned int statusCode;
XinZhangMS 0:f7f1f0d76dd6 393 /*Codes_SRS_IOTHUBCLIENT_LL_32_005: [ IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall call HTTPAPIEX_SAS_ExecuteRequest passing as arguments: ]*/
XinZhangMS 0:f7f1f0d76dd6 394 if (HTTPAPIEX_SAS_ExecuteRequest(
XinZhangMS 0:f7f1f0d76dd6 395 sasHandle, /*HTTPAPIEX_SAS_HANDLE sasHandle - the created HTTPAPIEX_SAS_HANDLE*/
XinZhangMS 0:f7f1f0d76dd6 396 iotHubHttpApiExHandle, /*HTTPAPIEX_HANDLE handle - the created HTTPAPIEX_HANDLE*/
XinZhangMS 0:f7f1f0d76dd6 397 HTTPAPI_REQUEST_POST, /*HTTPAPI_REQUEST_TYPE requestType - HTTPAPI_REQUEST_POST*/
XinZhangMS 0:f7f1f0d76dd6 398 STRING_c_str(relativePath), /*const char* relativePath - the HTTP relative path*/
XinZhangMS 0:f7f1f0d76dd6 399 requestHttpHeaders, /*HTTP_HEADERS_HANDLE requestHttpHeadersHandle - request HTTP headers*/
XinZhangMS 0:f7f1f0d76dd6 400 blobBuffer, /*BUFFER_HANDLE requestContent - address of JSON with optional/directory/tree/filename*/
XinZhangMS 0:f7f1f0d76dd6 401 &statusCode, /*unsigned int* statusCode - the address of an unsigned int that will contain the HTTP status code*/
XinZhangMS 0:f7f1f0d76dd6 402 NULL, /*HTTP_HEADERS_HANDLE responseHeadersHandle - NULL*/
XinZhangMS 0:f7f1f0d76dd6 403 responseContent
XinZhangMS 0:f7f1f0d76dd6 404 ) != HTTPAPIEX_OK)
XinZhangMS 0:f7f1f0d76dd6 405 {
XinZhangMS 0:f7f1f0d76dd6 406 /*Codes_SRS_IOTHUBCLIENT_LL_02_079: [ If HTTPAPIEX_SAS_ExecuteRequest fails then IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall fail and return IOTHUB_CLIENT_ERROR. ]*/
XinZhangMS 0:f7f1f0d76dd6 407 LogError("unable to HTTPAPIEX_SAS_ExecuteRequest");
XinZhangMS 0:f7f1f0d76dd6 408 result = __FAILURE__;
XinZhangMS 0:f7f1f0d76dd6 409 }
XinZhangMS 0:f7f1f0d76dd6 410 else
XinZhangMS 0:f7f1f0d76dd6 411 {
XinZhangMS 0:f7f1f0d76dd6 412 if (statusCode >= 300)
XinZhangMS 0:f7f1f0d76dd6 413 {
XinZhangMS 0:f7f1f0d76dd6 414 /*Codes_SRS_IOTHUBCLIENT_LL_02_080: [ If status code is greater than or equal to 300 then IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall fail and return IOTHUB_CLIENT_ERROR. ]*/
XinZhangMS 0:f7f1f0d76dd6 415 result = __FAILURE__;
XinZhangMS 0:f7f1f0d76dd6 416 LogError("HTTP code was %u", statusCode);
XinZhangMS 0:f7f1f0d76dd6 417 }
XinZhangMS 0:f7f1f0d76dd6 418 else
XinZhangMS 0:f7f1f0d76dd6 419 {
XinZhangMS 0:f7f1f0d76dd6 420 wasIoTHubRequestSuccess = 1;
XinZhangMS 0:f7f1f0d76dd6 421 }
XinZhangMS 0:f7f1f0d76dd6 422 }
XinZhangMS 0:f7f1f0d76dd6 423 HTTPAPIEX_SAS_Destroy(sasHandle);
XinZhangMS 0:f7f1f0d76dd6 424 }
XinZhangMS 0:f7f1f0d76dd6 425 STRING_delete(empty);
XinZhangMS 0:f7f1f0d76dd6 426 }
XinZhangMS 0:f7f1f0d76dd6 427 }
XinZhangMS 0:f7f1f0d76dd6 428 STRING_delete(uriResource);
XinZhangMS 0:f7f1f0d76dd6 429 }
XinZhangMS 0:f7f1f0d76dd6 430 }
XinZhangMS 0:f7f1f0d76dd6 431 } /*switch*/
XinZhangMS 0:f7f1f0d76dd6 432
XinZhangMS 0:f7f1f0d76dd6 433 if (wasIoTHubRequestSuccess == 0)
XinZhangMS 0:f7f1f0d76dd6 434 {
XinZhangMS 0:f7f1f0d76dd6 435 /*do nothing, shall be reported as an error*/
XinZhangMS 0:f7f1f0d76dd6 436 }
XinZhangMS 0:f7f1f0d76dd6 437 else
XinZhangMS 0:f7f1f0d76dd6 438 {
XinZhangMS 0:f7f1f0d76dd6 439 const unsigned char*responseContent_u_char = BUFFER_u_char(responseContent);
XinZhangMS 0:f7f1f0d76dd6 440 size_t responseContent_length = BUFFER_length(responseContent);
XinZhangMS 0:f7f1f0d76dd6 441 STRING_HANDLE responseAsString = STRING_from_byte_array(responseContent_u_char, responseContent_length);
XinZhangMS 0:f7f1f0d76dd6 442 if (responseAsString == NULL)
XinZhangMS 0:f7f1f0d76dd6 443 {
XinZhangMS 0:f7f1f0d76dd6 444 result = __FAILURE__;
XinZhangMS 0:f7f1f0d76dd6 445 LogError("unable to get the response as string");
XinZhangMS 0:f7f1f0d76dd6 446 }
XinZhangMS 0:f7f1f0d76dd6 447 else
XinZhangMS 0:f7f1f0d76dd6 448 {
XinZhangMS 0:f7f1f0d76dd6 449 /*Codes_SRS_IOTHUBCLIENT_LL_02_081: [ Otherwise, IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall use parson to extract and save the following information from the response buffer: correlationID and SasUri. ]*/
XinZhangMS 0:f7f1f0d76dd6 450 JSON_Value* allJson = json_parse_string(STRING_c_str(responseAsString));
XinZhangMS 0:f7f1f0d76dd6 451 if (allJson == NULL)
XinZhangMS 0:f7f1f0d76dd6 452 {
XinZhangMS 0:f7f1f0d76dd6 453 /*Codes_SRS_IOTHUBCLIENT_LL_02_082: [ If extracting and saving the correlationId or SasUri fails then IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall fail and return IOTHUB_CLIENT_ERROR. ]*/
XinZhangMS 0:f7f1f0d76dd6 454 LogError("unable to json_parse_string");
XinZhangMS 0:f7f1f0d76dd6 455 result = __FAILURE__;
XinZhangMS 0:f7f1f0d76dd6 456 }
XinZhangMS 0:f7f1f0d76dd6 457 else
XinZhangMS 0:f7f1f0d76dd6 458 {
XinZhangMS 0:f7f1f0d76dd6 459 JSON_Object* jsonObject = json_value_get_object(allJson);
XinZhangMS 0:f7f1f0d76dd6 460 if (jsonObject == NULL)
XinZhangMS 0:f7f1f0d76dd6 461 {
XinZhangMS 0:f7f1f0d76dd6 462 /*Codes_SRS_IOTHUBCLIENT_LL_02_082: [ If extracting and saving the correlationId or SasUri fails then IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall fail and return IOTHUB_CLIENT_ERROR. ]*/
XinZhangMS 0:f7f1f0d76dd6 463 LogError("unable to json_value_get_object");
XinZhangMS 0:f7f1f0d76dd6 464 result = __FAILURE__;
XinZhangMS 0:f7f1f0d76dd6 465 }
XinZhangMS 0:f7f1f0d76dd6 466 else
XinZhangMS 0:f7f1f0d76dd6 467 {
XinZhangMS 0:f7f1f0d76dd6 468 const char* json_correlationId;
XinZhangMS 0:f7f1f0d76dd6 469 json_correlationId = json_object_get_string(jsonObject, "correlationId");
XinZhangMS 0:f7f1f0d76dd6 470 if (json_correlationId == NULL)
XinZhangMS 0:f7f1f0d76dd6 471 {
XinZhangMS 0:f7f1f0d76dd6 472 /*Codes_SRS_IOTHUBCLIENT_LL_02_082: [ If extracting and saving the correlationId or SasUri fails then IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall fail and return IOTHUB_CLIENT_ERROR. ]*/
XinZhangMS 0:f7f1f0d76dd6 473 LogError("unable to json_object_get_string(jsonObject, \"correlationId\")");
XinZhangMS 0:f7f1f0d76dd6 474 result = __FAILURE__;
XinZhangMS 0:f7f1f0d76dd6 475 }
XinZhangMS 0:f7f1f0d76dd6 476 else
XinZhangMS 0:f7f1f0d76dd6 477 {
XinZhangMS 0:f7f1f0d76dd6 478 if (STRING_copy(correlationId, json_correlationId) != 0)
XinZhangMS 0:f7f1f0d76dd6 479 {
XinZhangMS 0:f7f1f0d76dd6 480 /*Codes_SRS_IOTHUBCLIENT_LL_02_082: [ If extracting and saving the correlationId or SasUri fails then IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall fail and return IOTHUB_CLIENT_ERROR. ]*/
XinZhangMS 0:f7f1f0d76dd6 481 LogError("unable to copy json_correlationId");
XinZhangMS 0:f7f1f0d76dd6 482 result = __FAILURE__;
XinZhangMS 0:f7f1f0d76dd6 483 }
XinZhangMS 0:f7f1f0d76dd6 484 else
XinZhangMS 0:f7f1f0d76dd6 485 {
XinZhangMS 0:f7f1f0d76dd6 486 const char* json_hostName = json_object_get_string(jsonObject, "hostName");
XinZhangMS 0:f7f1f0d76dd6 487 if (json_hostName == NULL)
XinZhangMS 0:f7f1f0d76dd6 488 {
XinZhangMS 0:f7f1f0d76dd6 489 /*Codes_SRS_IOTHUBCLIENT_LL_02_082: [ If extracting and saving the correlationId or SasUri fails then IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall fail and return IOTHUB_CLIENT_ERROR. ]*/
XinZhangMS 0:f7f1f0d76dd6 490 LogError("unable to json_object_get_string(jsonObject, \"hostName\")");
XinZhangMS 0:f7f1f0d76dd6 491 result = __FAILURE__;
XinZhangMS 0:f7f1f0d76dd6 492 }
XinZhangMS 0:f7f1f0d76dd6 493 else
XinZhangMS 0:f7f1f0d76dd6 494 {
XinZhangMS 0:f7f1f0d76dd6 495 const char* json_containerName = json_object_get_string(jsonObject, "containerName");
XinZhangMS 0:f7f1f0d76dd6 496 if (json_containerName == NULL)
XinZhangMS 0:f7f1f0d76dd6 497 {
XinZhangMS 0:f7f1f0d76dd6 498 /*Codes_SRS_IOTHUBCLIENT_LL_02_082: [ If extracting and saving the correlationId or SasUri fails then IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall fail and return IOTHUB_CLIENT_ERROR. ]*/
XinZhangMS 0:f7f1f0d76dd6 499 LogError("unable to json_object_get_string(jsonObject, \"containerName\")");
XinZhangMS 0:f7f1f0d76dd6 500 result = __FAILURE__;
XinZhangMS 0:f7f1f0d76dd6 501 }
XinZhangMS 0:f7f1f0d76dd6 502 else
XinZhangMS 0:f7f1f0d76dd6 503 {
XinZhangMS 0:f7f1f0d76dd6 504 const char* json_blobName = json_object_get_string(jsonObject, "blobName");
XinZhangMS 0:f7f1f0d76dd6 505 if (json_blobName == NULL)
XinZhangMS 0:f7f1f0d76dd6 506 {
XinZhangMS 0:f7f1f0d76dd6 507 /*Codes_SRS_IOTHUBCLIENT_LL_02_082: [ If extracting and saving the correlationId or SasUri fails then IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall fail and return IOTHUB_CLIENT_ERROR. ]*/
XinZhangMS 0:f7f1f0d76dd6 508 LogError("unable to json_object_get_string(jsonObject, \"blobName\")");
XinZhangMS 0:f7f1f0d76dd6 509 result = __FAILURE__;
XinZhangMS 0:f7f1f0d76dd6 510 }
XinZhangMS 0:f7f1f0d76dd6 511 else
XinZhangMS 0:f7f1f0d76dd6 512 {
XinZhangMS 0:f7f1f0d76dd6 513 const char* json_sasToken = json_object_get_string(jsonObject, "sasToken");
XinZhangMS 0:f7f1f0d76dd6 514 if (json_sasToken == NULL)
XinZhangMS 0:f7f1f0d76dd6 515 {
XinZhangMS 0:f7f1f0d76dd6 516 /*Codes_SRS_IOTHUBCLIENT_LL_02_082: [ If extracting and saving the correlationId or SasUri fails then IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall fail and return IOTHUB_CLIENT_ERROR. ]*/
XinZhangMS 0:f7f1f0d76dd6 517 LogError("unable to json_object_get_string(jsonObject, \"sasToken\")");
XinZhangMS 0:f7f1f0d76dd6 518 result = __FAILURE__;
XinZhangMS 0:f7f1f0d76dd6 519 }
XinZhangMS 0:f7f1f0d76dd6 520 else
XinZhangMS 0:f7f1f0d76dd6 521 {
XinZhangMS 0:f7f1f0d76dd6 522 /*good JSON received from the service*/
XinZhangMS 0:f7f1f0d76dd6 523
XinZhangMS 0:f7f1f0d76dd6 524 if (STRING_copy(sasUri, "https://") != 0)
XinZhangMS 0:f7f1f0d76dd6 525 {
XinZhangMS 0:f7f1f0d76dd6 526 /*Codes_SRS_IOTHUBCLIENT_LL_02_082: [ If extracting and saving the correlationId or SasUri fails then IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall fail and return IOTHUB_CLIENT_ERROR. ]*/
XinZhangMS 0:f7f1f0d76dd6 527 LogError("unable to STRING_copy");
XinZhangMS 0:f7f1f0d76dd6 528 result = __FAILURE__;
XinZhangMS 0:f7f1f0d76dd6 529 }
XinZhangMS 0:f7f1f0d76dd6 530 else
XinZhangMS 0:f7f1f0d76dd6 531 {
XinZhangMS 0:f7f1f0d76dd6 532 /*Codes_SRS_IOTHUBCLIENT_LL_32_008: [ The returned file name shall be URL encoded before passing back to the cloud. ]*/
XinZhangMS 0:f7f1f0d76dd6 533 STRING_HANDLE fileName = URL_EncodeString(json_blobName);
XinZhangMS 0:f7f1f0d76dd6 534
XinZhangMS 0:f7f1f0d76dd6 535 if (fileName == NULL)
XinZhangMS 0:f7f1f0d76dd6 536 {
XinZhangMS 0:f7f1f0d76dd6 537 /*Codes_SRS_IOTHUBCLIENT_LL_32_009: [ If URL_EncodeString fails then IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall fail and return IOTHUB_CLIENT_ERROR. ]*/
XinZhangMS 0:f7f1f0d76dd6 538 LogError("unable to URL_EncodeString of filename");
XinZhangMS 0:f7f1f0d76dd6 539 result = __FAILURE__;
XinZhangMS 0:f7f1f0d76dd6 540 }
XinZhangMS 0:f7f1f0d76dd6 541
XinZhangMS 0:f7f1f0d76dd6 542 else
XinZhangMS 0:f7f1f0d76dd6 543 {
XinZhangMS 0:f7f1f0d76dd6 544 if (!(
XinZhangMS 0:f7f1f0d76dd6 545 (STRING_concat(sasUri, json_hostName) == 0) &&
XinZhangMS 0:f7f1f0d76dd6 546 (STRING_concat(sasUri, "/") == 0) &&
XinZhangMS 0:f7f1f0d76dd6 547 (STRING_concat(sasUri, json_containerName) == 0) &&
XinZhangMS 0:f7f1f0d76dd6 548 (STRING_concat(sasUri, "/") == 0) &&
XinZhangMS 0:f7f1f0d76dd6 549 (STRING_concat(sasUri, STRING_c_str(fileName)) == 0) &&
XinZhangMS 0:f7f1f0d76dd6 550 (STRING_concat(sasUri, json_sasToken) == 0)
XinZhangMS 0:f7f1f0d76dd6 551 ))
XinZhangMS 0:f7f1f0d76dd6 552 {
XinZhangMS 0:f7f1f0d76dd6 553 /*Codes_SRS_IOTHUBCLIENT_LL_02_082: [ If extracting and saving the correlationId or SasUri fails then IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall fail and return IOTHUB_CLIENT_ERROR. ]*/
XinZhangMS 0:f7f1f0d76dd6 554 LogError("unable to STRING_concat");
XinZhangMS 0:f7f1f0d76dd6 555 result = __FAILURE__;
XinZhangMS 0:f7f1f0d76dd6 556 }
XinZhangMS 0:f7f1f0d76dd6 557 else
XinZhangMS 0:f7f1f0d76dd6 558 {
XinZhangMS 0:f7f1f0d76dd6 559 result = 0; /*success in step 1*/
XinZhangMS 0:f7f1f0d76dd6 560 }
XinZhangMS 0:f7f1f0d76dd6 561
XinZhangMS 0:f7f1f0d76dd6 562 STRING_delete(fileName);
XinZhangMS 0:f7f1f0d76dd6 563 }
XinZhangMS 0:f7f1f0d76dd6 564 }
XinZhangMS 0:f7f1f0d76dd6 565 }
XinZhangMS 0:f7f1f0d76dd6 566 }
XinZhangMS 0:f7f1f0d76dd6 567 }
XinZhangMS 0:f7f1f0d76dd6 568 }
XinZhangMS 0:f7f1f0d76dd6 569 }
XinZhangMS 0:f7f1f0d76dd6 570 }
XinZhangMS 0:f7f1f0d76dd6 571 }
XinZhangMS 0:f7f1f0d76dd6 572 json_value_free(allJson);
XinZhangMS 0:f7f1f0d76dd6 573 }
XinZhangMS 0:f7f1f0d76dd6 574 STRING_delete(responseAsString);
XinZhangMS 0:f7f1f0d76dd6 575 }
XinZhangMS 0:f7f1f0d76dd6 576 }
XinZhangMS 0:f7f1f0d76dd6 577 }
XinZhangMS 0:f7f1f0d76dd6 578 BUFFER_delete(responseContent);
XinZhangMS 0:f7f1f0d76dd6 579 }
XinZhangMS 0:f7f1f0d76dd6 580 BUFFER_delete(blobBuffer);
XinZhangMS 0:f7f1f0d76dd6 581 }
XinZhangMS 0:f7f1f0d76dd6 582 }
XinZhangMS 0:f7f1f0d76dd6 583 STRING_delete(blobName);
XinZhangMS 0:f7f1f0d76dd6 584 }
XinZhangMS 0:f7f1f0d76dd6 585 }
XinZhangMS 0:f7f1f0d76dd6 586 STRING_delete(relativePath);
XinZhangMS 0:f7f1f0d76dd6 587 }
XinZhangMS 0:f7f1f0d76dd6 588 return result;
XinZhangMS 0:f7f1f0d76dd6 589 }
XinZhangMS 0:f7f1f0d76dd6 590
XinZhangMS 0:f7f1f0d76dd6 591 /*returns 0 when the IoTHub has been informed about the file upload status*/
XinZhangMS 0:f7f1f0d76dd6 592 static int IoTHubClient_LL_UploadToBlob_step3(IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE_DATA* handleData, STRING_HANDLE correlationId, HTTPAPIEX_HANDLE iotHubHttpApiExHandle, HTTP_HEADERS_HANDLE requestHttpHeaders, BUFFER_HANDLE messageBody)
XinZhangMS 0:f7f1f0d76dd6 593 {
XinZhangMS 0:f7f1f0d76dd6 594 int result;
XinZhangMS 0:f7f1f0d76dd6 595 /*here is step 3. depending on the outcome of step 2 it needs to inform IoTHub about the file upload status*/
XinZhangMS 0:f7f1f0d76dd6 596 /*if step 1 failed, there's nothing that step 3 needs to report.*/
XinZhangMS 0:f7f1f0d76dd6 597 /*this POST "tries" to happen*/
XinZhangMS 0:f7f1f0d76dd6 598
XinZhangMS 0:f7f1f0d76dd6 599 /*Codes_SRS_IOTHUBCLIENT_LL_02_085: [ IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall use the same authorization as step 1. to prepare and perform a HTTP request with the following parameters: ]*/
XinZhangMS 0:f7f1f0d76dd6 600 STRING_HANDLE uriResource = STRING_construct(handleData->hostname);
XinZhangMS 0:f7f1f0d76dd6 601 if (uriResource == NULL)
XinZhangMS 0:f7f1f0d76dd6 602 {
XinZhangMS 0:f7f1f0d76dd6 603 LogError("unable to construct URI");
XinZhangMS 0:f7f1f0d76dd6 604 result = __FAILURE__;
XinZhangMS 0:f7f1f0d76dd6 605 }
XinZhangMS 0:f7f1f0d76dd6 606 else
XinZhangMS 0:f7f1f0d76dd6 607 {
XinZhangMS 0:f7f1f0d76dd6 608 if (!(
XinZhangMS 0:f7f1f0d76dd6 609 (STRING_concat(uriResource, "/devices/") == 0) &&
XinZhangMS 0:f7f1f0d76dd6 610 (STRING_concat_with_STRING(uriResource, handleData->deviceId) == 0) &&
XinZhangMS 0:f7f1f0d76dd6 611 (STRING_concat(uriResource, "/files/notifications") == 0)
XinZhangMS 0:f7f1f0d76dd6 612 ))
XinZhangMS 0:f7f1f0d76dd6 613 {
XinZhangMS 0:f7f1f0d76dd6 614 LogError("unable to STRING_concat");
XinZhangMS 0:f7f1f0d76dd6 615 result = __FAILURE__;
XinZhangMS 0:f7f1f0d76dd6 616 }
XinZhangMS 0:f7f1f0d76dd6 617 else
XinZhangMS 0:f7f1f0d76dd6 618 {
XinZhangMS 0:f7f1f0d76dd6 619 STRING_HANDLE relativePathNotification = STRING_construct("/devices/");
XinZhangMS 0:f7f1f0d76dd6 620 if (relativePathNotification == NULL)
XinZhangMS 0:f7f1f0d76dd6 621 {
XinZhangMS 0:f7f1f0d76dd6 622 result = __FAILURE__;
XinZhangMS 0:f7f1f0d76dd6 623 LogError("unable to STRING_construct");
XinZhangMS 0:f7f1f0d76dd6 624 }
XinZhangMS 0:f7f1f0d76dd6 625 else
XinZhangMS 0:f7f1f0d76dd6 626 {
XinZhangMS 0:f7f1f0d76dd6 627 if (!(
XinZhangMS 0:f7f1f0d76dd6 628 (STRING_concat_with_STRING(relativePathNotification, handleData->deviceId) == 0) &&
XinZhangMS 0:f7f1f0d76dd6 629 (STRING_concat(relativePathNotification, "/files/notifications/") == 0) &&
XinZhangMS 0:f7f1f0d76dd6 630 (STRING_concat(relativePathNotification, STRING_c_str(correlationId)) == 0) &&
XinZhangMS 0:f7f1f0d76dd6 631 (STRING_concat(relativePathNotification, API_VERSION) == 0)
XinZhangMS 0:f7f1f0d76dd6 632 ))
XinZhangMS 0:f7f1f0d76dd6 633 {
XinZhangMS 0:f7f1f0d76dd6 634 LogError("unable to STRING_concat_with_STRING");
XinZhangMS 0:f7f1f0d76dd6 635 result = __FAILURE__;
XinZhangMS 0:f7f1f0d76dd6 636 }
XinZhangMS 0:f7f1f0d76dd6 637 else
XinZhangMS 0:f7f1f0d76dd6 638 {
XinZhangMS 0:f7f1f0d76dd6 639 /*Codes_SRS_IOTHUBCLIENT_LL_02_086: [ If performing the HTTP request fails then IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall fail and return IOTHUB_CLIENT_ERROR. ]*/
XinZhangMS 0:f7f1f0d76dd6 640 switch (handleData->authorizationScheme)
XinZhangMS 0:f7f1f0d76dd6 641 {
XinZhangMS 0:f7f1f0d76dd6 642 default:
XinZhangMS 0:f7f1f0d76dd6 643 {
XinZhangMS 0:f7f1f0d76dd6 644 LogError("internal error: unknown authorization Scheme");
XinZhangMS 0:f7f1f0d76dd6 645 result = __FAILURE__;
XinZhangMS 0:f7f1f0d76dd6 646 break;
XinZhangMS 0:f7f1f0d76dd6 647 }
XinZhangMS 0:f7f1f0d76dd6 648 case (X509):
XinZhangMS 0:f7f1f0d76dd6 649 {
XinZhangMS 0:f7f1f0d76dd6 650 unsigned int notificationStatusCode;
XinZhangMS 0:f7f1f0d76dd6 651 if (HTTPAPIEX_ExecuteRequest(
XinZhangMS 0:f7f1f0d76dd6 652 iotHubHttpApiExHandle,
XinZhangMS 0:f7f1f0d76dd6 653 HTTPAPI_REQUEST_POST,
XinZhangMS 0:f7f1f0d76dd6 654 STRING_c_str(relativePathNotification),
XinZhangMS 0:f7f1f0d76dd6 655 requestHttpHeaders,
XinZhangMS 0:f7f1f0d76dd6 656 messageBody,
XinZhangMS 0:f7f1f0d76dd6 657 &notificationStatusCode,
XinZhangMS 0:f7f1f0d76dd6 658 NULL,
XinZhangMS 0:f7f1f0d76dd6 659 NULL) != HTTPAPIEX_OK)
XinZhangMS 0:f7f1f0d76dd6 660 {
XinZhangMS 0:f7f1f0d76dd6 661 LogError("unable to do HTTPAPIEX_ExecuteRequest");
XinZhangMS 0:f7f1f0d76dd6 662 result = __FAILURE__;
XinZhangMS 0:f7f1f0d76dd6 663 }
XinZhangMS 0:f7f1f0d76dd6 664 else
XinZhangMS 0:f7f1f0d76dd6 665 {
XinZhangMS 0:f7f1f0d76dd6 666 if (notificationStatusCode >= 300)
XinZhangMS 0:f7f1f0d76dd6 667 {
XinZhangMS 0:f7f1f0d76dd6 668 /*Codes_SRS_IOTHUBCLIENT_LL_02_087: [If the statusCode of the HTTP request is greater than or equal to 300 then IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall fail and return IOTHUB_CLIENT_ERROR]*/
XinZhangMS 0:f7f1f0d76dd6 669 LogError("server didn't like the notification request");
XinZhangMS 0:f7f1f0d76dd6 670 result = __FAILURE__;
XinZhangMS 0:f7f1f0d76dd6 671 }
XinZhangMS 0:f7f1f0d76dd6 672 else
XinZhangMS 0:f7f1f0d76dd6 673 {
XinZhangMS 0:f7f1f0d76dd6 674 result = 0;
XinZhangMS 0:f7f1f0d76dd6 675 }
XinZhangMS 0:f7f1f0d76dd6 676 }
XinZhangMS 0:f7f1f0d76dd6 677 break;
XinZhangMS 0:f7f1f0d76dd6 678 }
XinZhangMS 0:f7f1f0d76dd6 679 case (DEVICE_KEY):
XinZhangMS 0:f7f1f0d76dd6 680 {
XinZhangMS 0:f7f1f0d76dd6 681 STRING_HANDLE empty = STRING_new();
XinZhangMS 0:f7f1f0d76dd6 682 if (empty == NULL)
XinZhangMS 0:f7f1f0d76dd6 683 {
XinZhangMS 0:f7f1f0d76dd6 684 LogError("unable to STRING_new");
XinZhangMS 0:f7f1f0d76dd6 685 result = __FAILURE__;
XinZhangMS 0:f7f1f0d76dd6 686 }
XinZhangMS 0:f7f1f0d76dd6 687 else
XinZhangMS 0:f7f1f0d76dd6 688 {
XinZhangMS 0:f7f1f0d76dd6 689 HTTPAPIEX_SAS_HANDLE sasHandle = HTTPAPIEX_SAS_Create(handleData->credentials.deviceKey, uriResource, empty);
XinZhangMS 0:f7f1f0d76dd6 690 if (sasHandle == NULL)
XinZhangMS 0:f7f1f0d76dd6 691 {
XinZhangMS 0:f7f1f0d76dd6 692 LogError("unable to HTTPAPIEX_SAS_Create");
XinZhangMS 0:f7f1f0d76dd6 693 result = __FAILURE__;
XinZhangMS 0:f7f1f0d76dd6 694 }
XinZhangMS 0:f7f1f0d76dd6 695 else
XinZhangMS 0:f7f1f0d76dd6 696 {
XinZhangMS 0:f7f1f0d76dd6 697 unsigned int statusCode;
XinZhangMS 0:f7f1f0d76dd6 698 if (HTTPAPIEX_SAS_ExecuteRequest(
XinZhangMS 0:f7f1f0d76dd6 699 sasHandle, /*HTTPAPIEX_SAS_HANDLE sasHandle - the created HTTPAPIEX_SAS_HANDLE*/
XinZhangMS 0:f7f1f0d76dd6 700 iotHubHttpApiExHandle, /*HTTPAPIEX_HANDLE handle - the created HTTPAPIEX_HANDLE*/
XinZhangMS 0:f7f1f0d76dd6 701 HTTPAPI_REQUEST_POST, /*HTTPAPI_REQUEST_TYPE requestType - HTTPAPI_REQUEST_GET*/
XinZhangMS 0:f7f1f0d76dd6 702 STRING_c_str(relativePathNotification), /*const char* relativePath - the HTTP relative path*/
XinZhangMS 0:f7f1f0d76dd6 703 requestHttpHeaders, /*HTTP_HEADERS_HANDLE requestHttpHeadersHandle - request HTTP headers*/
XinZhangMS 0:f7f1f0d76dd6 704 messageBody, /*BUFFER_HANDLE requestContent*/
XinZhangMS 0:f7f1f0d76dd6 705 &statusCode, /*unsigned int* statusCode - the address of an unsigned int that will contain the HTTP status code*/
XinZhangMS 0:f7f1f0d76dd6 706 NULL, /*HTTP_HEADERS_HANDLE responseHeadersHandle - NULL*/
XinZhangMS 0:f7f1f0d76dd6 707 NULL
XinZhangMS 0:f7f1f0d76dd6 708 ) != HTTPAPIEX_OK)
XinZhangMS 0:f7f1f0d76dd6 709 {
XinZhangMS 0:f7f1f0d76dd6 710 /*Codes_SRS_IOTHUBCLIENT_LL_02_079: [ If HTTPAPIEX_SAS_ExecuteRequest fails then IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall fail and return IOTHUB_CLIENT_ERROR. ]*/
XinZhangMS 0:f7f1f0d76dd6 711 LogError("unable to HTTPAPIEX_SAS_ExecuteRequest");
XinZhangMS 0:f7f1f0d76dd6 712 result = __FAILURE__;
XinZhangMS 0:f7f1f0d76dd6 713 ;
XinZhangMS 0:f7f1f0d76dd6 714 }
XinZhangMS 0:f7f1f0d76dd6 715 else
XinZhangMS 0:f7f1f0d76dd6 716 {
XinZhangMS 0:f7f1f0d76dd6 717 if (statusCode >= 300)
XinZhangMS 0:f7f1f0d76dd6 718 {
XinZhangMS 0:f7f1f0d76dd6 719 /*Codes_SRS_IOTHUBCLIENT_LL_02_087: [If the statusCode of the HTTP request is greater than or equal to 300 then IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall fail and return IOTHUB_CLIENT_ERROR]*/
XinZhangMS 0:f7f1f0d76dd6 720 result = __FAILURE__;
XinZhangMS 0:f7f1f0d76dd6 721 LogError("HTTP code was %u", statusCode);
XinZhangMS 0:f7f1f0d76dd6 722 }
XinZhangMS 0:f7f1f0d76dd6 723 else
XinZhangMS 0:f7f1f0d76dd6 724 {
XinZhangMS 0:f7f1f0d76dd6 725 result = 0;
XinZhangMS 0:f7f1f0d76dd6 726 }
XinZhangMS 0:f7f1f0d76dd6 727 }
XinZhangMS 0:f7f1f0d76dd6 728 HTTPAPIEX_SAS_Destroy(sasHandle);
XinZhangMS 0:f7f1f0d76dd6 729 }
XinZhangMS 0:f7f1f0d76dd6 730 STRING_delete(empty);
XinZhangMS 0:f7f1f0d76dd6 731 }
XinZhangMS 0:f7f1f0d76dd6 732 break;
XinZhangMS 0:f7f1f0d76dd6 733 }
XinZhangMS 0:f7f1f0d76dd6 734 case(SAS_TOKEN):
XinZhangMS 0:f7f1f0d76dd6 735 {
XinZhangMS 0:f7f1f0d76dd6 736 unsigned int notificationStatusCode;
XinZhangMS 0:f7f1f0d76dd6 737 if (HTTPAPIEX_ExecuteRequest(
XinZhangMS 0:f7f1f0d76dd6 738 iotHubHttpApiExHandle,
XinZhangMS 0:f7f1f0d76dd6 739 HTTPAPI_REQUEST_POST,
XinZhangMS 0:f7f1f0d76dd6 740 STRING_c_str(relativePathNotification),
XinZhangMS 0:f7f1f0d76dd6 741 requestHttpHeaders,
XinZhangMS 0:f7f1f0d76dd6 742 messageBody,
XinZhangMS 0:f7f1f0d76dd6 743 &notificationStatusCode,
XinZhangMS 0:f7f1f0d76dd6 744 NULL,
XinZhangMS 0:f7f1f0d76dd6 745 NULL) != HTTPAPIEX_OK)
XinZhangMS 0:f7f1f0d76dd6 746 {
XinZhangMS 0:f7f1f0d76dd6 747 LogError("unable to do HTTPAPIEX_ExecuteRequest");
XinZhangMS 0:f7f1f0d76dd6 748 result = __FAILURE__;
XinZhangMS 0:f7f1f0d76dd6 749 }
XinZhangMS 0:f7f1f0d76dd6 750 else
XinZhangMS 0:f7f1f0d76dd6 751 {
XinZhangMS 0:f7f1f0d76dd6 752 if (notificationStatusCode >= 300)
XinZhangMS 0:f7f1f0d76dd6 753 {
XinZhangMS 0:f7f1f0d76dd6 754 /*Codes_SRS_IOTHUBCLIENT_LL_02_087: [If the statusCode of the HTTP request is greater than or equal to 300 then IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall fail and return IOTHUB_CLIENT_ERROR]*/
XinZhangMS 0:f7f1f0d76dd6 755 LogError("server didn't like the notification request");
XinZhangMS 0:f7f1f0d76dd6 756 result = __FAILURE__;
XinZhangMS 0:f7f1f0d76dd6 757 }
XinZhangMS 0:f7f1f0d76dd6 758 else
XinZhangMS 0:f7f1f0d76dd6 759 {
XinZhangMS 0:f7f1f0d76dd6 760 result = 0;
XinZhangMS 0:f7f1f0d76dd6 761 }
XinZhangMS 0:f7f1f0d76dd6 762 }
XinZhangMS 0:f7f1f0d76dd6 763 break;
XinZhangMS 0:f7f1f0d76dd6 764 }
XinZhangMS 0:f7f1f0d76dd6 765 } /*switch authorizationScheme*/
XinZhangMS 0:f7f1f0d76dd6 766 }
XinZhangMS 0:f7f1f0d76dd6 767 STRING_delete(relativePathNotification);
XinZhangMS 0:f7f1f0d76dd6 768 }
XinZhangMS 0:f7f1f0d76dd6 769 }
XinZhangMS 0:f7f1f0d76dd6 770 STRING_delete(uriResource);
XinZhangMS 0:f7f1f0d76dd6 771 }
XinZhangMS 0:f7f1f0d76dd6 772 return result;
XinZhangMS 0:f7f1f0d76dd6 773 }
XinZhangMS 0:f7f1f0d76dd6 774
XinZhangMS 0:f7f1f0d76dd6 775 // this callback splits the source data into blocks to be fed to IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex)_Impl
XinZhangMS 0:f7f1f0d76dd6 776 static IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_RESULT FileUpload_GetData_Callback(IOTHUB_CLIENT_FILE_UPLOAD_RESULT result, unsigned char const ** data, size_t* size, void* context)
XinZhangMS 0:f7f1f0d76dd6 777 {
XinZhangMS 0:f7f1f0d76dd6 778 BLOB_UPLOAD_CONTEXT* uploadContext = (BLOB_UPLOAD_CONTEXT*) context;
XinZhangMS 0:f7f1f0d76dd6 779
XinZhangMS 0:f7f1f0d76dd6 780 if (data == NULL || size == NULL)
XinZhangMS 0:f7f1f0d76dd6 781 {
XinZhangMS 0:f7f1f0d76dd6 782 // This is the last call, nothing to do
XinZhangMS 0:f7f1f0d76dd6 783 }
XinZhangMS 0:f7f1f0d76dd6 784 else if (result != FILE_UPLOAD_OK)
XinZhangMS 0:f7f1f0d76dd6 785 {
XinZhangMS 0:f7f1f0d76dd6 786 // Last call failed
XinZhangMS 0:f7f1f0d76dd6 787 *data = NULL;
XinZhangMS 0:f7f1f0d76dd6 788 *size = 0;
XinZhangMS 0:f7f1f0d76dd6 789 }
XinZhangMS 0:f7f1f0d76dd6 790 else if (uploadContext->remainingSizeToUpload == 0)
XinZhangMS 0:f7f1f0d76dd6 791 {
XinZhangMS 0:f7f1f0d76dd6 792 // Everything has been uploaded
XinZhangMS 0:f7f1f0d76dd6 793 *data = NULL;
XinZhangMS 0:f7f1f0d76dd6 794 *size = 0;
XinZhangMS 0:f7f1f0d76dd6 795 }
XinZhangMS 0:f7f1f0d76dd6 796 else
XinZhangMS 0:f7f1f0d76dd6 797 {
XinZhangMS 0:f7f1f0d76dd6 798 // Upload next block
XinZhangMS 0:f7f1f0d76dd6 799 size_t thisBlockSize = (uploadContext->remainingSizeToUpload > BLOCK_SIZE) ? BLOCK_SIZE : uploadContext->remainingSizeToUpload;
XinZhangMS 0:f7f1f0d76dd6 800 *data = (unsigned char*)uploadContext->blobSource + (uploadContext->blobSourceSize - uploadContext->remainingSizeToUpload);
XinZhangMS 0:f7f1f0d76dd6 801 *size = thisBlockSize;
XinZhangMS 0:f7f1f0d76dd6 802 uploadContext->remainingSizeToUpload -= thisBlockSize;
XinZhangMS 0:f7f1f0d76dd6 803 }
XinZhangMS 0:f7f1f0d76dd6 804
XinZhangMS 0:f7f1f0d76dd6 805 return IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_OK;
XinZhangMS 0:f7f1f0d76dd6 806 }
XinZhangMS 0:f7f1f0d76dd6 807
XinZhangMS 0:f7f1f0d76dd6 808 static HTTPAPIEX_RESULT set_transfer_timeout(IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE_DATA* handleData, HTTPAPIEX_HANDLE iotHubHttpApiExHandle)
XinZhangMS 0:f7f1f0d76dd6 809 {
XinZhangMS 0:f7f1f0d76dd6 810 HTTPAPIEX_RESULT result;
XinZhangMS 0:f7f1f0d76dd6 811 if (handleData->blob_upload_timeout_secs != 0)
XinZhangMS 0:f7f1f0d76dd6 812 {
XinZhangMS 0:f7f1f0d76dd6 813 // Convert the timeout to milliseconds for curl
XinZhangMS 0:f7f1f0d76dd6 814 long http_timeout = (long)handleData->blob_upload_timeout_secs * 1000;
XinZhangMS 0:f7f1f0d76dd6 815 result = HTTPAPIEX_SetOption(iotHubHttpApiExHandle, OPTION_HTTP_TIMEOUT, &http_timeout);
XinZhangMS 0:f7f1f0d76dd6 816 }
XinZhangMS 0:f7f1f0d76dd6 817 else
XinZhangMS 0:f7f1f0d76dd6 818 {
XinZhangMS 0:f7f1f0d76dd6 819 result = HTTPAPIEX_OK;
XinZhangMS 0:f7f1f0d76dd6 820 }
XinZhangMS 0:f7f1f0d76dd6 821 return result;
XinZhangMS 0:f7f1f0d76dd6 822 }
XinZhangMS 0:f7f1f0d76dd6 823
XinZhangMS 0:f7f1f0d76dd6 824 IOTHUB_CLIENT_RESULT IoTHubClient_LL_UploadMultipleBlocksToBlob_Impl(IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE handle, const char* destinationFileName, IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_CALLBACK_EX getDataCallbackEx, void* context)
XinZhangMS 0:f7f1f0d76dd6 825 {
XinZhangMS 0:f7f1f0d76dd6 826 IOTHUB_CLIENT_RESULT result;
XinZhangMS 0:f7f1f0d76dd6 827
XinZhangMS 0:f7f1f0d76dd6 828 /*Codes_SRS_IOTHUBCLIENT_LL_02_061: [ If handle is NULL then IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall fail and return IOTHUB_CLIENT_INVALID_ARG. ]*/
XinZhangMS 0:f7f1f0d76dd6 829 /*Codes_SRS_IOTHUBCLIENT_LL_02_062: [ If destinationFileName is NULL then IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall fail and return IOTHUB_CLIENT_INVALID_ARG. ]*/
XinZhangMS 0:f7f1f0d76dd6 830
XinZhangMS 0:f7f1f0d76dd6 831 if (
XinZhangMS 0:f7f1f0d76dd6 832 (handle == NULL) ||
XinZhangMS 0:f7f1f0d76dd6 833 (destinationFileName == NULL) ||
XinZhangMS 0:f7f1f0d76dd6 834 (getDataCallbackEx == NULL)
XinZhangMS 0:f7f1f0d76dd6 835 )
XinZhangMS 0:f7f1f0d76dd6 836 {
XinZhangMS 0:f7f1f0d76dd6 837 LogError("invalid argument detected handle=%p destinationFileName=%p getDataCallbackEx=%p", handle, destinationFileName, getDataCallbackEx);
XinZhangMS 0:f7f1f0d76dd6 838 result = IOTHUB_CLIENT_INVALID_ARG;
XinZhangMS 0:f7f1f0d76dd6 839 }
XinZhangMS 0:f7f1f0d76dd6 840 else
XinZhangMS 0:f7f1f0d76dd6 841 {
XinZhangMS 0:f7f1f0d76dd6 842 IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE_DATA* handleData = (IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE_DATA*)handle;
XinZhangMS 0:f7f1f0d76dd6 843
XinZhangMS 0:f7f1f0d76dd6 844 /*Codes_SRS_IOTHUBCLIENT_LL_02_064: [ IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall create an HTTPAPIEX_HANDLE to the IoTHub hostname. ]*/
XinZhangMS 0:f7f1f0d76dd6 845 HTTPAPIEX_HANDLE iotHubHttpApiExHandle = HTTPAPIEX_Create(handleData->hostname);
XinZhangMS 0:f7f1f0d76dd6 846
XinZhangMS 0:f7f1f0d76dd6 847 /*Codes_SRS_IOTHUBCLIENT_LL_02_065: [ If creating the HTTPAPIEX_HANDLE fails then IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall fail and return IOTHUB_CLIENT_ERROR. ]*/
XinZhangMS 0:f7f1f0d76dd6 848 if (iotHubHttpApiExHandle == NULL)
XinZhangMS 0:f7f1f0d76dd6 849 {
XinZhangMS 0:f7f1f0d76dd6 850 LogError("unable to HTTPAPIEX_Create");
XinZhangMS 0:f7f1f0d76dd6 851 result = IOTHUB_CLIENT_ERROR;
XinZhangMS 0:f7f1f0d76dd6 852 }
XinZhangMS 0:f7f1f0d76dd6 853 /*Codes_SRS_IOTHUBCLIENT_LL_30_020: [ If the blob_upload_timeout_secs option has been set to non-zero, IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall set the timeout on the underlying transport accordingly. ]*/
XinZhangMS 0:f7f1f0d76dd6 854 else if (set_transfer_timeout(handleData, iotHubHttpApiExHandle) != HTTPAPIEX_OK)
XinZhangMS 0:f7f1f0d76dd6 855 {
XinZhangMS 0:f7f1f0d76dd6 856 LogError("unable to set blob transfer timeout");
XinZhangMS 0:f7f1f0d76dd6 857 result = IOTHUB_CLIENT_ERROR;
XinZhangMS 0:f7f1f0d76dd6 858
XinZhangMS 0:f7f1f0d76dd6 859 }
XinZhangMS 0:f7f1f0d76dd6 860 else
XinZhangMS 0:f7f1f0d76dd6 861 {
XinZhangMS 0:f7f1f0d76dd6 862 (void)HTTPAPIEX_SetOption(iotHubHttpApiExHandle, OPTION_CURL_VERBOSE, &handleData->curl_verbose);
XinZhangMS 0:f7f1f0d76dd6 863
XinZhangMS 0:f7f1f0d76dd6 864 if (
XinZhangMS 0:f7f1f0d76dd6 865 (handleData->authorizationScheme == X509) &&
XinZhangMS 0:f7f1f0d76dd6 866
XinZhangMS 0:f7f1f0d76dd6 867 /*transmit the x509certificate and x509privatekey*/
XinZhangMS 0:f7f1f0d76dd6 868 /*Codes_SRS_IOTHUBCLIENT_LL_02_106: [ - x509certificate and x509privatekey saved options shall be passed on the HTTPAPIEX_SetOption ]*/
XinZhangMS 0:f7f1f0d76dd6 869 (!(
XinZhangMS 0:f7f1f0d76dd6 870 (HTTPAPIEX_SetOption(iotHubHttpApiExHandle, OPTION_X509_CERT, handleData->credentials.x509credentials.x509certificate) == HTTPAPIEX_OK) &&
XinZhangMS 0:f7f1f0d76dd6 871 (HTTPAPIEX_SetOption(iotHubHttpApiExHandle, OPTION_X509_PRIVATE_KEY, handleData->credentials.x509credentials.x509privatekey) == HTTPAPIEX_OK)
XinZhangMS 0:f7f1f0d76dd6 872 ))
XinZhangMS 0:f7f1f0d76dd6 873 )
XinZhangMS 0:f7f1f0d76dd6 874 {
XinZhangMS 0:f7f1f0d76dd6 875 LogError("unable to HTTPAPIEX_SetOption for x509");
XinZhangMS 0:f7f1f0d76dd6 876 result = IOTHUB_CLIENT_ERROR;
XinZhangMS 0:f7f1f0d76dd6 877 }
XinZhangMS 0:f7f1f0d76dd6 878 else
XinZhangMS 0:f7f1f0d76dd6 879 {
XinZhangMS 0:f7f1f0d76dd6 880 /*Codes_SRS_IOTHUBCLIENT_LL_02_111: [ If certificates is non-NULL then certificates shall be passed to HTTPAPIEX_SetOption with optionName TrustedCerts. ]*/
XinZhangMS 0:f7f1f0d76dd6 881 if ((handleData->certificates != NULL) && (HTTPAPIEX_SetOption(iotHubHttpApiExHandle, "TrustedCerts", handleData->certificates) != HTTPAPIEX_OK))
XinZhangMS 0:f7f1f0d76dd6 882 {
XinZhangMS 0:f7f1f0d76dd6 883 LogError("unable to set TrustedCerts!");
XinZhangMS 0:f7f1f0d76dd6 884 result = IOTHUB_CLIENT_ERROR;
XinZhangMS 0:f7f1f0d76dd6 885 }
XinZhangMS 0:f7f1f0d76dd6 886 else
XinZhangMS 0:f7f1f0d76dd6 887 {
XinZhangMS 0:f7f1f0d76dd6 888
XinZhangMS 0:f7f1f0d76dd6 889 if (handleData->http_proxy_options.host_address != NULL)
XinZhangMS 0:f7f1f0d76dd6 890 {
XinZhangMS 0:f7f1f0d76dd6 891 HTTP_PROXY_OPTIONS proxy_options;
XinZhangMS 0:f7f1f0d76dd6 892 proxy_options = handleData->http_proxy_options;
XinZhangMS 0:f7f1f0d76dd6 893
XinZhangMS 0:f7f1f0d76dd6 894 if (HTTPAPIEX_SetOption(iotHubHttpApiExHandle, OPTION_HTTP_PROXY, &proxy_options) != HTTPAPIEX_OK)
XinZhangMS 0:f7f1f0d76dd6 895 {
XinZhangMS 0:f7f1f0d76dd6 896 LogError("unable to set http proxy!");
XinZhangMS 0:f7f1f0d76dd6 897 result = IOTHUB_CLIENT_ERROR;
XinZhangMS 0:f7f1f0d76dd6 898 }
XinZhangMS 0:f7f1f0d76dd6 899 else
XinZhangMS 0:f7f1f0d76dd6 900 {
XinZhangMS 0:f7f1f0d76dd6 901 result = IOTHUB_CLIENT_OK;
XinZhangMS 0:f7f1f0d76dd6 902 }
XinZhangMS 0:f7f1f0d76dd6 903 }
XinZhangMS 0:f7f1f0d76dd6 904 else
XinZhangMS 0:f7f1f0d76dd6 905 {
XinZhangMS 0:f7f1f0d76dd6 906 result = IOTHUB_CLIENT_OK;
XinZhangMS 0:f7f1f0d76dd6 907 }
XinZhangMS 0:f7f1f0d76dd6 908
XinZhangMS 0:f7f1f0d76dd6 909 if (result != IOTHUB_CLIENT_ERROR)
XinZhangMS 0:f7f1f0d76dd6 910 {
XinZhangMS 0:f7f1f0d76dd6 911 STRING_HANDLE correlationId = STRING_new();
XinZhangMS 0:f7f1f0d76dd6 912 if (correlationId == NULL)
XinZhangMS 0:f7f1f0d76dd6 913 {
XinZhangMS 0:f7f1f0d76dd6 914 LogError("unable to STRING_new");
XinZhangMS 0:f7f1f0d76dd6 915 result = IOTHUB_CLIENT_ERROR;
XinZhangMS 0:f7f1f0d76dd6 916 }
XinZhangMS 0:f7f1f0d76dd6 917 else
XinZhangMS 0:f7f1f0d76dd6 918 {
XinZhangMS 0:f7f1f0d76dd6 919 STRING_HANDLE sasUri = STRING_new();
XinZhangMS 0:f7f1f0d76dd6 920 if (sasUri == NULL)
XinZhangMS 0:f7f1f0d76dd6 921 {
XinZhangMS 0:f7f1f0d76dd6 922 LogError("unable to STRING_new");
XinZhangMS 0:f7f1f0d76dd6 923 result = IOTHUB_CLIENT_ERROR;
XinZhangMS 0:f7f1f0d76dd6 924 }
XinZhangMS 0:f7f1f0d76dd6 925 else
XinZhangMS 0:f7f1f0d76dd6 926 {
XinZhangMS 0:f7f1f0d76dd6 927 /*Codes_SRS_IOTHUBCLIENT_LL_02_070: [ IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall create request HTTP headers. ]*/
XinZhangMS 0:f7f1f0d76dd6 928 HTTP_HEADERS_HANDLE requestHttpHeaders = HTTPHeaders_Alloc(); /*these are build by step 1 and used by step 3 too*/
XinZhangMS 0:f7f1f0d76dd6 929 if (requestHttpHeaders == NULL)
XinZhangMS 0:f7f1f0d76dd6 930 {
XinZhangMS 0:f7f1f0d76dd6 931 LogError("unable to HTTPHeaders_Alloc");
XinZhangMS 0:f7f1f0d76dd6 932 result = IOTHUB_CLIENT_ERROR;
XinZhangMS 0:f7f1f0d76dd6 933 }
XinZhangMS 0:f7f1f0d76dd6 934 else
XinZhangMS 0:f7f1f0d76dd6 935 {
XinZhangMS 0:f7f1f0d76dd6 936 /*do step 1*/
XinZhangMS 0:f7f1f0d76dd6 937 if (IoTHubClient_LL_UploadToBlob_step1and2(handleData, iotHubHttpApiExHandle, requestHttpHeaders, destinationFileName, correlationId, sasUri) != 0)
XinZhangMS 0:f7f1f0d76dd6 938 {
XinZhangMS 0:f7f1f0d76dd6 939 LogError("error in IoTHubClient_LL_UploadToBlob_step1");
XinZhangMS 0:f7f1f0d76dd6 940 result = IOTHUB_CLIENT_ERROR;
XinZhangMS 0:f7f1f0d76dd6 941 }
XinZhangMS 0:f7f1f0d76dd6 942 else
XinZhangMS 0:f7f1f0d76dd6 943 {
XinZhangMS 0:f7f1f0d76dd6 944 /*do step 2.*/
XinZhangMS 0:f7f1f0d76dd6 945
XinZhangMS 0:f7f1f0d76dd6 946 unsigned int httpResponse;
XinZhangMS 0:f7f1f0d76dd6 947 BUFFER_HANDLE responseToIoTHub = BUFFER_new();
XinZhangMS 0:f7f1f0d76dd6 948 if (responseToIoTHub == NULL)
XinZhangMS 0:f7f1f0d76dd6 949 {
XinZhangMS 0:f7f1f0d76dd6 950 result = IOTHUB_CLIENT_ERROR;
XinZhangMS 0:f7f1f0d76dd6 951 LogError("unable to BUFFER_new");
XinZhangMS 0:f7f1f0d76dd6 952 }
XinZhangMS 0:f7f1f0d76dd6 953 else
XinZhangMS 0:f7f1f0d76dd6 954 {
XinZhangMS 0:f7f1f0d76dd6 955 /*Codes_SRS_IOTHUBCLIENT_LL_02_083: [ IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall call Blob_UploadFromSasUri and capture the HTTP return code and HTTP body. ]*/
XinZhangMS 0:f7f1f0d76dd6 956 BLOB_RESULT uploadMultipleBlocksResult = Blob_UploadMultipleBlocksFromSasUri(STRING_c_str(sasUri), getDataCallbackEx, context, &httpResponse, responseToIoTHub, handleData->certificates, &(handleData->http_proxy_options));
XinZhangMS 0:f7f1f0d76dd6 957 if (uploadMultipleBlocksResult == BLOB_ABORTED)
XinZhangMS 0:f7f1f0d76dd6 958 {
XinZhangMS 0:f7f1f0d76dd6 959 /*Codes_SRS_IOTHUBCLIENT_LL_99_008: [ If step 2 is aborted by the client, then the HTTP message body shall look like: ]*/
XinZhangMS 0:f7f1f0d76dd6 960 LogInfo("Blob_UploadFromSasUri aborted file upload");
XinZhangMS 0:f7f1f0d76dd6 961
XinZhangMS 0:f7f1f0d76dd6 962 if (BUFFER_build(responseToIoTHub, (const unsigned char*)FILE_UPLOAD_ABORTED_BODY, sizeof(FILE_UPLOAD_ABORTED_BODY) / sizeof(FILE_UPLOAD_ABORTED_BODY[0])) == 0)
XinZhangMS 0:f7f1f0d76dd6 963 {
XinZhangMS 0:f7f1f0d76dd6 964 if (IoTHubClient_LL_UploadToBlob_step3(handleData, correlationId, iotHubHttpApiExHandle, requestHttpHeaders, responseToIoTHub) != 0)
XinZhangMS 0:f7f1f0d76dd6 965 {
XinZhangMS 0:f7f1f0d76dd6 966 LogError("IoTHubClient_LL_UploadToBlob_step3 failed");
XinZhangMS 0:f7f1f0d76dd6 967 result = IOTHUB_CLIENT_ERROR;
XinZhangMS 0:f7f1f0d76dd6 968 }
XinZhangMS 0:f7f1f0d76dd6 969 else
XinZhangMS 0:f7f1f0d76dd6 970 {
XinZhangMS 0:f7f1f0d76dd6 971 /*Codes_SRS_IOTHUBCLIENT_LL_99_009: [ If step 2 is aborted by the client and if step 3 succeeds, then `IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex)` shall return `IOTHUB_CLIENT_OK`. ] */
XinZhangMS 0:f7f1f0d76dd6 972 result = IOTHUB_CLIENT_OK;
XinZhangMS 0:f7f1f0d76dd6 973 }
XinZhangMS 0:f7f1f0d76dd6 974 }
XinZhangMS 0:f7f1f0d76dd6 975 else
XinZhangMS 0:f7f1f0d76dd6 976 {
XinZhangMS 0:f7f1f0d76dd6 977 LogError("Unable to BUFFER_build, can't perform IoTHubClient_LL_UploadToBlob_step3");
XinZhangMS 0:f7f1f0d76dd6 978 result = IOTHUB_CLIENT_ERROR;
XinZhangMS 0:f7f1f0d76dd6 979 }
XinZhangMS 0:f7f1f0d76dd6 980 }
XinZhangMS 0:f7f1f0d76dd6 981 else if (uploadMultipleBlocksResult != BLOB_OK)
XinZhangMS 0:f7f1f0d76dd6 982 {
XinZhangMS 0:f7f1f0d76dd6 983 /*Codes_SRS_IOTHUBCLIENT_LL_02_084: [ If Blob_UploadFromSasUri fails then IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex) shall fail and return IOTHUB_CLIENT_ERROR. ]*/
XinZhangMS 0:f7f1f0d76dd6 984 LogError("unable to Blob_UploadFromSasUri");
XinZhangMS 0:f7f1f0d76dd6 985
XinZhangMS 0:f7f1f0d76dd6 986 /*do step 3*/ /*try*/
XinZhangMS 0:f7f1f0d76dd6 987 /*Codes_SRS_IOTHUBCLIENT_LL_02_091: [ If step 2 fails without establishing an HTTP dialogue, then the HTTP message body shall look like: ]*/
XinZhangMS 0:f7f1f0d76dd6 988 if (BUFFER_build(responseToIoTHub, (const unsigned char*)FILE_UPLOAD_FAILED_BODY, sizeof(FILE_UPLOAD_FAILED_BODY) / sizeof(FILE_UPLOAD_FAILED_BODY[0])) == 0)
XinZhangMS 0:f7f1f0d76dd6 989 {
XinZhangMS 0:f7f1f0d76dd6 990 if (IoTHubClient_LL_UploadToBlob_step3(handleData, correlationId, iotHubHttpApiExHandle, requestHttpHeaders, responseToIoTHub) != 0)
XinZhangMS 0:f7f1f0d76dd6 991 {
XinZhangMS 0:f7f1f0d76dd6 992 LogError("IoTHubClient_LL_UploadToBlob_step3 failed");
XinZhangMS 0:f7f1f0d76dd6 993 }
XinZhangMS 0:f7f1f0d76dd6 994 }
XinZhangMS 0:f7f1f0d76dd6 995 result = IOTHUB_CLIENT_ERROR;
XinZhangMS 0:f7f1f0d76dd6 996 }
XinZhangMS 0:f7f1f0d76dd6 997 else
XinZhangMS 0:f7f1f0d76dd6 998 {
XinZhangMS 0:f7f1f0d76dd6 999 /*must make a json*/
XinZhangMS 0:f7f1f0d76dd6 1000
XinZhangMS 0:f7f1f0d76dd6 1001 int requiredStringLength = snprintf(NULL, 0, "{\"isSuccess\":%s, \"statusCode\":%d, \"statusDescription\":\"%s\"}", ((httpResponse < 300) ? "true" : "false"), httpResponse, BUFFER_u_char(responseToIoTHub));
XinZhangMS 0:f7f1f0d76dd6 1002
XinZhangMS 0:f7f1f0d76dd6 1003 char * requiredString = malloc(requiredStringLength + 1);
XinZhangMS 0:f7f1f0d76dd6 1004 if (requiredString == 0)
XinZhangMS 0:f7f1f0d76dd6 1005 {
XinZhangMS 0:f7f1f0d76dd6 1006 LogError("unable to malloc");
XinZhangMS 0:f7f1f0d76dd6 1007 result = IOTHUB_CLIENT_ERROR;
XinZhangMS 0:f7f1f0d76dd6 1008 }
XinZhangMS 0:f7f1f0d76dd6 1009 else
XinZhangMS 0:f7f1f0d76dd6 1010 {
XinZhangMS 0:f7f1f0d76dd6 1011 /*do again snprintf*/
XinZhangMS 0:f7f1f0d76dd6 1012 BUFFER_HANDLE toBeTransmitted = NULL;
XinZhangMS 0:f7f1f0d76dd6 1013 (void)snprintf(requiredString, requiredStringLength + 1, "{\"isSuccess\":%s, \"statusCode\":%d, \"statusDescription\":\"%s\"}", ((httpResponse < 300) ? "true" : "false"), httpResponse, BUFFER_u_char(responseToIoTHub));
XinZhangMS 0:f7f1f0d76dd6 1014 toBeTransmitted = BUFFER_create((const unsigned char*)requiredString, requiredStringLength);
XinZhangMS 0:f7f1f0d76dd6 1015 if (toBeTransmitted == NULL)
XinZhangMS 0:f7f1f0d76dd6 1016 {
XinZhangMS 0:f7f1f0d76dd6 1017 LogError("unable to BUFFER_create");
XinZhangMS 0:f7f1f0d76dd6 1018 result = IOTHUB_CLIENT_ERROR;
XinZhangMS 0:f7f1f0d76dd6 1019 }
XinZhangMS 0:f7f1f0d76dd6 1020 else
XinZhangMS 0:f7f1f0d76dd6 1021 {
XinZhangMS 0:f7f1f0d76dd6 1022 if (IoTHubClient_LL_UploadToBlob_step3(handleData, correlationId, iotHubHttpApiExHandle, requestHttpHeaders, toBeTransmitted) != 0)
XinZhangMS 0:f7f1f0d76dd6 1023 {
XinZhangMS 0:f7f1f0d76dd6 1024 LogError("IoTHubClient_LL_UploadToBlob_step3 failed");
XinZhangMS 0:f7f1f0d76dd6 1025 result = IOTHUB_CLIENT_ERROR;
XinZhangMS 0:f7f1f0d76dd6 1026 }
XinZhangMS 0:f7f1f0d76dd6 1027 else
XinZhangMS 0:f7f1f0d76dd6 1028 {
XinZhangMS 0:f7f1f0d76dd6 1029 result = (httpResponse < 300) ? IOTHUB_CLIENT_OK : IOTHUB_CLIENT_ERROR;
XinZhangMS 0:f7f1f0d76dd6 1030 }
XinZhangMS 0:f7f1f0d76dd6 1031 BUFFER_delete(toBeTransmitted);
XinZhangMS 0:f7f1f0d76dd6 1032 }
XinZhangMS 0:f7f1f0d76dd6 1033 free(requiredString);
XinZhangMS 0:f7f1f0d76dd6 1034 }
XinZhangMS 0:f7f1f0d76dd6 1035 }
XinZhangMS 0:f7f1f0d76dd6 1036 BUFFER_delete(responseToIoTHub);
XinZhangMS 0:f7f1f0d76dd6 1037 }
XinZhangMS 0:f7f1f0d76dd6 1038 }
XinZhangMS 0:f7f1f0d76dd6 1039 HTTPHeaders_Free(requestHttpHeaders);
XinZhangMS 0:f7f1f0d76dd6 1040 }
XinZhangMS 0:f7f1f0d76dd6 1041 STRING_delete(sasUri);
XinZhangMS 0:f7f1f0d76dd6 1042 }
XinZhangMS 0:f7f1f0d76dd6 1043 STRING_delete(correlationId);
XinZhangMS 0:f7f1f0d76dd6 1044 }
XinZhangMS 0:f7f1f0d76dd6 1045 }
XinZhangMS 0:f7f1f0d76dd6 1046 }
XinZhangMS 0:f7f1f0d76dd6 1047 }
XinZhangMS 0:f7f1f0d76dd6 1048 HTTPAPIEX_Destroy(iotHubHttpApiExHandle);
XinZhangMS 0:f7f1f0d76dd6 1049 }
XinZhangMS 0:f7f1f0d76dd6 1050 }
XinZhangMS 0:f7f1f0d76dd6 1051
XinZhangMS 0:f7f1f0d76dd6 1052 /*Codes_SRS_IOTHUBCLIENT_LL_99_003: [ If `IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex)` return `IOTHUB_CLIENT_OK`, it shall call `getDataCallbackEx` with `result` set to `FILE_UPLOAD_OK`, and `data` and `size` set to NULL. ]*/
XinZhangMS 0:f7f1f0d76dd6 1053 /*Codes_SRS_IOTHUBCLIENT_LL_99_004: [ If `IoTHubClient_LL_UploadMultipleBlocksToBlob(Ex)` does not return `IOTHUB_CLIENT_OK`, it shall call `getDataCallbackEx` with `result` set to `FILE_UPLOAD_ERROR`, and `data` and `size` set to NULL. ]*/
XinZhangMS 0:f7f1f0d76dd6 1054 (void)getDataCallbackEx(result == IOTHUB_CLIENT_OK ? FILE_UPLOAD_OK : FILE_UPLOAD_ERROR, NULL, NULL, context);
XinZhangMS 0:f7f1f0d76dd6 1055
XinZhangMS 0:f7f1f0d76dd6 1056 return result;
XinZhangMS 0:f7f1f0d76dd6 1057 }
XinZhangMS 0:f7f1f0d76dd6 1058
XinZhangMS 0:f7f1f0d76dd6 1059 IOTHUB_CLIENT_RESULT IoTHubClient_LL_UploadToBlob_Impl(IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE handle, const char* destinationFileName, const unsigned char* source, size_t size)
XinZhangMS 0:f7f1f0d76dd6 1060 {
XinZhangMS 0:f7f1f0d76dd6 1061 IOTHUB_CLIENT_RESULT result;
XinZhangMS 0:f7f1f0d76dd6 1062
XinZhangMS 0:f7f1f0d76dd6 1063 /*Codes_SRS_IOTHUBCLIENT_LL_02_063: [ If source is NULL and size is greater than 0 then IoTHubClient_LL_UploadToBlob shall fail and return IOTHUB_CLIENT_INVALID_ARG. ]*/
XinZhangMS 0:f7f1f0d76dd6 1064 if (source == NULL && size > 0)
XinZhangMS 0:f7f1f0d76dd6 1065 {
XinZhangMS 0:f7f1f0d76dd6 1066 LogError("invalid source and size combination: source=%p size=%lu", source, size);
XinZhangMS 0:f7f1f0d76dd6 1067 result = IOTHUB_CLIENT_INVALID_ARG;
XinZhangMS 0:f7f1f0d76dd6 1068 }
XinZhangMS 0:f7f1f0d76dd6 1069 else
XinZhangMS 0:f7f1f0d76dd6 1070 {
XinZhangMS 0:f7f1f0d76dd6 1071 /*Codes_SRS_IOTHUBCLIENT_LL_99_001: [ `IoTHubClient_LL_UploadToBlob` shall create a struct containing the `source`, the `size`, and the remaining size to upload.]*/
XinZhangMS 0:f7f1f0d76dd6 1072 BLOB_UPLOAD_CONTEXT context;
XinZhangMS 0:f7f1f0d76dd6 1073 context.blobSource = source;
XinZhangMS 0:f7f1f0d76dd6 1074 context.blobSourceSize = size;
XinZhangMS 0:f7f1f0d76dd6 1075 context.remainingSizeToUpload = size;
XinZhangMS 0:f7f1f0d76dd6 1076
XinZhangMS 0:f7f1f0d76dd6 1077 /*Codes_SRS_IOTHUBCLIENT_LL_99_002: [ `IoTHubClient_LL_UploadToBlob` shall call `IoTHubClient_LL_UploadMultipleBlocksToBlob_Impl` with `FileUpload_GetData_Callback` as `getDataCallbackEx` and pass the struct created at step SRS_IOTHUBCLIENT_LL_99_001 as `context` ]*/
XinZhangMS 0:f7f1f0d76dd6 1078 result = IoTHubClient_LL_UploadMultipleBlocksToBlob_Impl(handle, destinationFileName, FileUpload_GetData_Callback, &context);
XinZhangMS 0:f7f1f0d76dd6 1079 }
XinZhangMS 0:f7f1f0d76dd6 1080 return result;
XinZhangMS 0:f7f1f0d76dd6 1081 }
XinZhangMS 0:f7f1f0d76dd6 1082
XinZhangMS 0:f7f1f0d76dd6 1083 void IoTHubClient_LL_UploadToBlob_Destroy(IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE handle)
XinZhangMS 0:f7f1f0d76dd6 1084 {
XinZhangMS 0:f7f1f0d76dd6 1085 if (handle == NULL)
XinZhangMS 0:f7f1f0d76dd6 1086 {
XinZhangMS 0:f7f1f0d76dd6 1087 LogError("unexpected NULL argument");
XinZhangMS 0:f7f1f0d76dd6 1088 }
XinZhangMS 0:f7f1f0d76dd6 1089 else
XinZhangMS 0:f7f1f0d76dd6 1090 {
XinZhangMS 0:f7f1f0d76dd6 1091 IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE_DATA* handleData = (IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE_DATA*)handle;
XinZhangMS 0:f7f1f0d76dd6 1092 switch (handleData->authorizationScheme)
XinZhangMS 0:f7f1f0d76dd6 1093 {
XinZhangMS 0:f7f1f0d76dd6 1094 case(SAS_TOKEN):
XinZhangMS 0:f7f1f0d76dd6 1095 {
XinZhangMS 0:f7f1f0d76dd6 1096 STRING_delete(handleData->credentials.sas);
XinZhangMS 0:f7f1f0d76dd6 1097 break;
XinZhangMS 0:f7f1f0d76dd6 1098 }
XinZhangMS 0:f7f1f0d76dd6 1099 case(DEVICE_KEY):
XinZhangMS 0:f7f1f0d76dd6 1100 {
XinZhangMS 0:f7f1f0d76dd6 1101 STRING_delete(handleData->credentials.deviceKey);
XinZhangMS 0:f7f1f0d76dd6 1102 break;
XinZhangMS 0:f7f1f0d76dd6 1103 }
XinZhangMS 0:f7f1f0d76dd6 1104 case(X509):
XinZhangMS 0:f7f1f0d76dd6 1105 {
XinZhangMS 0:f7f1f0d76dd6 1106 if (handleData->credentials.x509credentials.x509certificate != NULL)
XinZhangMS 0:f7f1f0d76dd6 1107 {
XinZhangMS 0:f7f1f0d76dd6 1108 free((void*)handleData->credentials.x509credentials.x509certificate);
XinZhangMS 0:f7f1f0d76dd6 1109 }
XinZhangMS 0:f7f1f0d76dd6 1110 if (handleData->credentials.x509credentials.x509privatekey != NULL)
XinZhangMS 0:f7f1f0d76dd6 1111 {
XinZhangMS 0:f7f1f0d76dd6 1112 free((void*)handleData->credentials.x509credentials.x509privatekey);
XinZhangMS 0:f7f1f0d76dd6 1113 }
XinZhangMS 0:f7f1f0d76dd6 1114 break;
XinZhangMS 0:f7f1f0d76dd6 1115 }
XinZhangMS 0:f7f1f0d76dd6 1116 default:
XinZhangMS 0:f7f1f0d76dd6 1117 {
XinZhangMS 0:f7f1f0d76dd6 1118 LogError("INTERNAL ERROR");
XinZhangMS 0:f7f1f0d76dd6 1119 break;
XinZhangMS 0:f7f1f0d76dd6 1120 }
XinZhangMS 0:f7f1f0d76dd6 1121 }
XinZhangMS 0:f7f1f0d76dd6 1122 free((void*)handleData->hostname);
XinZhangMS 0:f7f1f0d76dd6 1123 STRING_delete(handleData->deviceId);
XinZhangMS 0:f7f1f0d76dd6 1124 if (handleData->certificates != NULL)
XinZhangMS 0:f7f1f0d76dd6 1125 {
XinZhangMS 0:f7f1f0d76dd6 1126 free(handleData->certificates);
XinZhangMS 0:f7f1f0d76dd6 1127 }
XinZhangMS 0:f7f1f0d76dd6 1128 if (handleData->http_proxy_options.host_address != NULL)
XinZhangMS 0:f7f1f0d76dd6 1129 {
XinZhangMS 0:f7f1f0d76dd6 1130 free((char *)handleData->http_proxy_options.host_address);
XinZhangMS 0:f7f1f0d76dd6 1131 }
XinZhangMS 0:f7f1f0d76dd6 1132 if (handleData->http_proxy_options.username != NULL)
XinZhangMS 0:f7f1f0d76dd6 1133 {
XinZhangMS 0:f7f1f0d76dd6 1134 free((char *)handleData->http_proxy_options.username);
XinZhangMS 0:f7f1f0d76dd6 1135 }
XinZhangMS 0:f7f1f0d76dd6 1136 if (handleData->http_proxy_options.password != NULL)
XinZhangMS 0:f7f1f0d76dd6 1137 {
XinZhangMS 0:f7f1f0d76dd6 1138 free((char *)handleData->http_proxy_options.password);
XinZhangMS 0:f7f1f0d76dd6 1139 }
XinZhangMS 0:f7f1f0d76dd6 1140 free(handleData);
XinZhangMS 0:f7f1f0d76dd6 1141 }
XinZhangMS 0:f7f1f0d76dd6 1142 }
XinZhangMS 0:f7f1f0d76dd6 1143
XinZhangMS 0:f7f1f0d76dd6 1144 IOTHUB_CLIENT_RESULT IoTHubClient_LL_UploadToBlob_SetOption(IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE handle, const char* optionName, const void* value)
XinZhangMS 0:f7f1f0d76dd6 1145 {
XinZhangMS 0:f7f1f0d76dd6 1146 IOTHUB_CLIENT_RESULT result;
XinZhangMS 0:f7f1f0d76dd6 1147 /*Codes_SRS_IOTHUBCLIENT_LL_02_110: [ If parameter handle is NULL then IoTHubClient_LL_UploadToBlob_SetOption shall fail and return IOTHUB_CLIENT_ERROR. ]*/
XinZhangMS 0:f7f1f0d76dd6 1148 if (handle == NULL)
XinZhangMS 0:f7f1f0d76dd6 1149 {
XinZhangMS 0:f7f1f0d76dd6 1150 LogError("invalid argument detected: IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE handle=%p, const char* optionName=%s, const void* value=%p", handle, optionName, value);
XinZhangMS 0:f7f1f0d76dd6 1151 result = IOTHUB_CLIENT_ERROR;
XinZhangMS 0:f7f1f0d76dd6 1152 }
XinZhangMS 0:f7f1f0d76dd6 1153 else
XinZhangMS 0:f7f1f0d76dd6 1154 {
XinZhangMS 0:f7f1f0d76dd6 1155 IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE_DATA* handleData = (IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE_DATA*)handle;
XinZhangMS 0:f7f1f0d76dd6 1156
XinZhangMS 0:f7f1f0d76dd6 1157 /*Codes_SRS_IOTHUBCLIENT_LL_02_100: [ x509certificate - then value then is a null terminated string that contains the x509 certificate. ]*/
XinZhangMS 0:f7f1f0d76dd6 1158 if (strcmp(optionName, OPTION_X509_CERT) == 0)
XinZhangMS 0:f7f1f0d76dd6 1159 {
XinZhangMS 0:f7f1f0d76dd6 1160 /*Codes_SRS_IOTHUBCLIENT_LL_02_109: [ If the authentication scheme is NOT x509 then IoTHubClient_LL_UploadToBlob_SetOption shall return IOTHUB_CLIENT_INVALID_ARG. ]*/
XinZhangMS 0:f7f1f0d76dd6 1161 if (handleData->authorizationScheme != X509)
XinZhangMS 0:f7f1f0d76dd6 1162 {
XinZhangMS 0:f7f1f0d76dd6 1163 LogError("trying to set a x509 certificate while the authentication scheme is not x509");
XinZhangMS 0:f7f1f0d76dd6 1164 result = IOTHUB_CLIENT_INVALID_ARG;
XinZhangMS 0:f7f1f0d76dd6 1165 }
XinZhangMS 0:f7f1f0d76dd6 1166 else
XinZhangMS 0:f7f1f0d76dd6 1167 {
XinZhangMS 0:f7f1f0d76dd6 1168 /*Codes_SRS_IOTHUBCLIENT_LL_02_103: [ The options shall be saved. ]*/
XinZhangMS 0:f7f1f0d76dd6 1169 /*try to make a copy of the certificate*/
XinZhangMS 0:f7f1f0d76dd6 1170 char* temp;
XinZhangMS 0:f7f1f0d76dd6 1171 if (mallocAndStrcpy_s(&temp, value) != 0)
XinZhangMS 0:f7f1f0d76dd6 1172 {
XinZhangMS 0:f7f1f0d76dd6 1173 /*Codes_SRS_IOTHUBCLIENT_LL_02_104: [ If saving fails, then IoTHubClient_LL_UploadToBlob_SetOption shall fail and return IOTHUB_CLIENT_ERROR. ]*/
XinZhangMS 0:f7f1f0d76dd6 1174 LogError("unable to mallocAndStrcpy_s");
XinZhangMS 0:f7f1f0d76dd6 1175 result = IOTHUB_CLIENT_ERROR;
XinZhangMS 0:f7f1f0d76dd6 1176 }
XinZhangMS 0:f7f1f0d76dd6 1177 else
XinZhangMS 0:f7f1f0d76dd6 1178 {
XinZhangMS 0:f7f1f0d76dd6 1179 /*Codes_SRS_IOTHUBCLIENT_LL_02_105: [ Otherwise IoTHubClient_LL_UploadToBlob_SetOption shall succeed and return IOTHUB_CLIENT_OK. ]*/
XinZhangMS 0:f7f1f0d76dd6 1180 if (handleData->credentials.x509credentials.x509certificate != NULL) /*free any previous values, if any*/
XinZhangMS 0:f7f1f0d76dd6 1181 {
XinZhangMS 0:f7f1f0d76dd6 1182 free((void*)handleData->credentials.x509credentials.x509certificate);
XinZhangMS 0:f7f1f0d76dd6 1183 }
XinZhangMS 0:f7f1f0d76dd6 1184 handleData->credentials.x509credentials.x509certificate = temp;
XinZhangMS 0:f7f1f0d76dd6 1185 result = IOTHUB_CLIENT_OK;
XinZhangMS 0:f7f1f0d76dd6 1186 }
XinZhangMS 0:f7f1f0d76dd6 1187 }
XinZhangMS 0:f7f1f0d76dd6 1188 }
XinZhangMS 0:f7f1f0d76dd6 1189 /*Codes_SRS_IOTHUBCLIENT_LL_02_101: [ x509privatekey - then value is a null terminated string that contains the x509 privatekey. ]*/
XinZhangMS 0:f7f1f0d76dd6 1190 else if (strcmp(optionName, OPTION_X509_PRIVATE_KEY) == 0)
XinZhangMS 0:f7f1f0d76dd6 1191 {
XinZhangMS 0:f7f1f0d76dd6 1192 /*Codes_SRS_IOTHUBCLIENT_LL_02_109: [ If the authentication scheme is NOT x509 then IoTHubClient_LL_UploadToBlob_SetOption shall return IOTHUB_CLIENT_INVALID_ARG. ]*/
XinZhangMS 0:f7f1f0d76dd6 1193 if (handleData->authorizationScheme != X509)
XinZhangMS 0:f7f1f0d76dd6 1194 {
XinZhangMS 0:f7f1f0d76dd6 1195 LogError("trying to set a x509 privatekey while the authentication scheme is not x509");
XinZhangMS 0:f7f1f0d76dd6 1196 result = IOTHUB_CLIENT_INVALID_ARG;
XinZhangMS 0:f7f1f0d76dd6 1197 }
XinZhangMS 0:f7f1f0d76dd6 1198 else
XinZhangMS 0:f7f1f0d76dd6 1199 {
XinZhangMS 0:f7f1f0d76dd6 1200 /*Codes_SRS_IOTHUBCLIENT_LL_02_103: [ The options shall be saved. ]*/
XinZhangMS 0:f7f1f0d76dd6 1201 /*try to make a copy of the privatekey*/
XinZhangMS 0:f7f1f0d76dd6 1202 char* temp;
XinZhangMS 0:f7f1f0d76dd6 1203 if (mallocAndStrcpy_s(&temp, value) != 0)
XinZhangMS 0:f7f1f0d76dd6 1204 {
XinZhangMS 0:f7f1f0d76dd6 1205 /*Codes_SRS_IOTHUBCLIENT_LL_02_104: [ If saving fails, then IoTHubClient_LL_UploadToBlob_SetOption shall fail and return IOTHUB_CLIENT_ERROR. ]*/
XinZhangMS 0:f7f1f0d76dd6 1206 LogError("unable to mallocAndStrcpy_s");
XinZhangMS 0:f7f1f0d76dd6 1207 result = IOTHUB_CLIENT_ERROR;
XinZhangMS 0:f7f1f0d76dd6 1208 }
XinZhangMS 0:f7f1f0d76dd6 1209 else
XinZhangMS 0:f7f1f0d76dd6 1210 {
XinZhangMS 0:f7f1f0d76dd6 1211 /*Codes_SRS_IOTHUBCLIENT_LL_02_105: [ Otherwise IoTHubClient_LL_UploadToBlob_SetOption shall succeed and return IOTHUB_CLIENT_OK. ]*/
XinZhangMS 0:f7f1f0d76dd6 1212 if (handleData->credentials.x509credentials.x509privatekey != NULL) /*free any previous values, if any*/
XinZhangMS 0:f7f1f0d76dd6 1213 {
XinZhangMS 0:f7f1f0d76dd6 1214 free((void*)handleData->credentials.x509credentials.x509privatekey);
XinZhangMS 0:f7f1f0d76dd6 1215 }
XinZhangMS 0:f7f1f0d76dd6 1216 handleData->credentials.x509credentials.x509privatekey = temp;
XinZhangMS 0:f7f1f0d76dd6 1217 result = IOTHUB_CLIENT_OK;
XinZhangMS 0:f7f1f0d76dd6 1218 }
XinZhangMS 0:f7f1f0d76dd6 1219 }
XinZhangMS 0:f7f1f0d76dd6 1220 }
XinZhangMS 0:f7f1f0d76dd6 1221 else if (strcmp(OPTION_TRUSTED_CERT, optionName) == 0)
XinZhangMS 0:f7f1f0d76dd6 1222 {
XinZhangMS 0:f7f1f0d76dd6 1223 if (value == NULL)
XinZhangMS 0:f7f1f0d76dd6 1224 {
XinZhangMS 0:f7f1f0d76dd6 1225 LogError("NULL is a not a valid value for TrustedCerts");
XinZhangMS 0:f7f1f0d76dd6 1226 result = IOTHUB_CLIENT_INVALID_ARG;
XinZhangMS 0:f7f1f0d76dd6 1227 }
XinZhangMS 0:f7f1f0d76dd6 1228 else
XinZhangMS 0:f7f1f0d76dd6 1229 {
XinZhangMS 0:f7f1f0d76dd6 1230 char* tempCopy;
XinZhangMS 0:f7f1f0d76dd6 1231 if (mallocAndStrcpy_s(&tempCopy, value) != 0)
XinZhangMS 0:f7f1f0d76dd6 1232 {
XinZhangMS 0:f7f1f0d76dd6 1233 LogError("failure in mallocAndStrcpy_s");
XinZhangMS 0:f7f1f0d76dd6 1234 result = IOTHUB_CLIENT_ERROR;
XinZhangMS 0:f7f1f0d76dd6 1235 }
XinZhangMS 0:f7f1f0d76dd6 1236 else
XinZhangMS 0:f7f1f0d76dd6 1237 {
XinZhangMS 0:f7f1f0d76dd6 1238 if (handleData->certificates != NULL)
XinZhangMS 0:f7f1f0d76dd6 1239 {
XinZhangMS 0:f7f1f0d76dd6 1240 free(handleData->certificates);
XinZhangMS 0:f7f1f0d76dd6 1241 }
XinZhangMS 0:f7f1f0d76dd6 1242 handleData->certificates = tempCopy;
XinZhangMS 0:f7f1f0d76dd6 1243 result = IOTHUB_CLIENT_OK;
XinZhangMS 0:f7f1f0d76dd6 1244 }
XinZhangMS 0:f7f1f0d76dd6 1245 }
XinZhangMS 0:f7f1f0d76dd6 1246 }
XinZhangMS 0:f7f1f0d76dd6 1247 /*Codes_SRS_IOTHUBCLIENT_LL_32_008: [ OPTION_HTTP_PROXY - then the value will be a pointer to HTTP_PROXY_OPTIONS structure. ]*/
XinZhangMS 0:f7f1f0d76dd6 1248 else if (strcmp(optionName, OPTION_HTTP_PROXY) == 0)
XinZhangMS 0:f7f1f0d76dd6 1249 {
XinZhangMS 0:f7f1f0d76dd6 1250 HTTP_PROXY_OPTIONS* proxy_options = (HTTP_PROXY_OPTIONS *)value;
XinZhangMS 0:f7f1f0d76dd6 1251
XinZhangMS 0:f7f1f0d76dd6 1252 if (proxy_options->host_address == NULL)
XinZhangMS 0:f7f1f0d76dd6 1253 {
XinZhangMS 0:f7f1f0d76dd6 1254 /* Codes_SRS_IOTHUBCLIENT_LL_32_006: [ If `host_address` is NULL, `IoTHubClient_LL_UploadToBlob_SetOption` shall fail and return `IOTHUB_CLIENT_INVALID_ARG`. ]*/
XinZhangMS 0:f7f1f0d76dd6 1255 LogError("NULL host_address in proxy options");
XinZhangMS 0:f7f1f0d76dd6 1256 result = IOTHUB_CLIENT_INVALID_ARG;
XinZhangMS 0:f7f1f0d76dd6 1257 }
XinZhangMS 0:f7f1f0d76dd6 1258 /* Codes_SRS_IOTHUBCLIENT_LL_32_007: [ If only one of `username` and `password` is NULL, `IoTHubClient_LL_UploadToBlob_SetOption` shall fail and return `IOTHUB_CLIENT_INVALID_ARG`. ]*/
XinZhangMS 0:f7f1f0d76dd6 1259 else if (((proxy_options->username == NULL) || (proxy_options->password == NULL)) &&
XinZhangMS 0:f7f1f0d76dd6 1260 (proxy_options->username != proxy_options->password))
XinZhangMS 0:f7f1f0d76dd6 1261 {
XinZhangMS 0:f7f1f0d76dd6 1262 LogError("Only one of username and password for proxy settings was NULL");
XinZhangMS 0:f7f1f0d76dd6 1263 result = IOTHUB_CLIENT_INVALID_ARG;
XinZhangMS 0:f7f1f0d76dd6 1264 }
XinZhangMS 0:f7f1f0d76dd6 1265 else
XinZhangMS 0:f7f1f0d76dd6 1266 {
XinZhangMS 0:f7f1f0d76dd6 1267 if (handleData->http_proxy_options.host_address != NULL)
XinZhangMS 0:f7f1f0d76dd6 1268 {
XinZhangMS 0:f7f1f0d76dd6 1269 free((char *)handleData->http_proxy_options.host_address);
XinZhangMS 0:f7f1f0d76dd6 1270 handleData->http_proxy_options.host_address = NULL;
XinZhangMS 0:f7f1f0d76dd6 1271 }
XinZhangMS 0:f7f1f0d76dd6 1272 if (handleData->http_proxy_options.username != NULL)
XinZhangMS 0:f7f1f0d76dd6 1273 {
XinZhangMS 0:f7f1f0d76dd6 1274 free((char *)handleData->http_proxy_options.username);
XinZhangMS 0:f7f1f0d76dd6 1275 handleData->http_proxy_options.username = NULL;
XinZhangMS 0:f7f1f0d76dd6 1276 }
XinZhangMS 0:f7f1f0d76dd6 1277 if (handleData->http_proxy_options.password != NULL)
XinZhangMS 0:f7f1f0d76dd6 1278 {
XinZhangMS 0:f7f1f0d76dd6 1279 free((char *)handleData->http_proxy_options.password);
XinZhangMS 0:f7f1f0d76dd6 1280 handleData->http_proxy_options.password = NULL;
XinZhangMS 0:f7f1f0d76dd6 1281 }
XinZhangMS 0:f7f1f0d76dd6 1282
XinZhangMS 0:f7f1f0d76dd6 1283 handleData->http_proxy_options.port = proxy_options->port;
XinZhangMS 0:f7f1f0d76dd6 1284
XinZhangMS 0:f7f1f0d76dd6 1285 if (mallocAndStrcpy_s((char **)(&handleData->http_proxy_options.host_address), proxy_options->host_address) != 0)
XinZhangMS 0:f7f1f0d76dd6 1286 {
XinZhangMS 0:f7f1f0d76dd6 1287 LogError("failure in mallocAndStrcpy_s - handleData->http_proxy_options.host_address");
XinZhangMS 0:f7f1f0d76dd6 1288 result = IOTHUB_CLIENT_ERROR;
XinZhangMS 0:f7f1f0d76dd6 1289 }
XinZhangMS 0:f7f1f0d76dd6 1290 else if (proxy_options->username != NULL && mallocAndStrcpy_s((char **)(&handleData->http_proxy_options.username), proxy_options->username) != 0)
XinZhangMS 0:f7f1f0d76dd6 1291 {
XinZhangMS 0:f7f1f0d76dd6 1292 LogError("failure in mallocAndStrcpy_s - handleData->http_proxy_options.username");
XinZhangMS 0:f7f1f0d76dd6 1293 result = IOTHUB_CLIENT_ERROR;
XinZhangMS 0:f7f1f0d76dd6 1294 }
XinZhangMS 0:f7f1f0d76dd6 1295 else if (proxy_options->password != NULL && mallocAndStrcpy_s((char **)(&handleData->http_proxy_options.password), proxy_options->password) != 0)
XinZhangMS 0:f7f1f0d76dd6 1296 {
XinZhangMS 0:f7f1f0d76dd6 1297 LogError("failure in mallocAndStrcpy_s - handleData->http_proxy_options.password");
XinZhangMS 0:f7f1f0d76dd6 1298 result = IOTHUB_CLIENT_ERROR;
XinZhangMS 0:f7f1f0d76dd6 1299 }
XinZhangMS 0:f7f1f0d76dd6 1300 else
XinZhangMS 0:f7f1f0d76dd6 1301 {
XinZhangMS 0:f7f1f0d76dd6 1302 result = IOTHUB_CLIENT_OK;
XinZhangMS 0:f7f1f0d76dd6 1303 }
XinZhangMS 0:f7f1f0d76dd6 1304 }
XinZhangMS 0:f7f1f0d76dd6 1305 }
XinZhangMS 0:f7f1f0d76dd6 1306 else if (strcmp(optionName, OPTION_CURL_VERBOSE) == 0)
XinZhangMS 0:f7f1f0d76dd6 1307 {
XinZhangMS 0:f7f1f0d76dd6 1308 handleData->curl_verbose = *(size_t*)value;
XinZhangMS 0:f7f1f0d76dd6 1309 result = IOTHUB_CLIENT_OK;
XinZhangMS 0:f7f1f0d76dd6 1310 }
XinZhangMS 0:f7f1f0d76dd6 1311 else if (strcmp(optionName, OPTION_BLOB_UPLOAD_TIMEOUT_SECS) == 0)
XinZhangMS 0:f7f1f0d76dd6 1312 {
XinZhangMS 0:f7f1f0d76dd6 1313 handleData->blob_upload_timeout_secs = *(size_t*)value;
XinZhangMS 0:f7f1f0d76dd6 1314 result = IOTHUB_CLIENT_OK;
XinZhangMS 0:f7f1f0d76dd6 1315 }
XinZhangMS 0:f7f1f0d76dd6 1316 else
XinZhangMS 0:f7f1f0d76dd6 1317 {
XinZhangMS 0:f7f1f0d76dd6 1318 /*Codes_SRS_IOTHUBCLIENT_LL_02_102: [ If an unknown option is presented then IoTHubClient_LL_UploadToBlob_SetOption shall return IOTHUB_CLIENT_INVALID_ARG. ]*/
XinZhangMS 0:f7f1f0d76dd6 1319 result = IOTHUB_CLIENT_INVALID_ARG;
XinZhangMS 0:f7f1f0d76dd6 1320 }
XinZhangMS 0:f7f1f0d76dd6 1321 }
XinZhangMS 0:f7f1f0d76dd6 1322 return result;
XinZhangMS 0:f7f1f0d76dd6 1323 }
XinZhangMS 0:f7f1f0d76dd6 1324
XinZhangMS 0:f7f1f0d76dd6 1325
XinZhangMS 0:f7f1f0d76dd6 1326 #endif /*DONT_USE_UPLOADTOBLOB*/
XinZhangMS 0:f7f1f0d76dd6 1327
XinZhangMS 0:f7f1f0d76dd6 1328