コード例 #1
0
static void sendHttpRequestMethodExpectedCalls()
{
    STRICT_EXPECTED_CALL(environment_get_variable(IGNORED_PTR_ARG)).CallCannotFail();
    STRICT_EXPECTED_CALL(HTTPHeaders_Alloc());
    STRICT_EXPECTED_CALL(HTTPHeaders_AddHeaderNameValuePair(IGNORED_PTR_ARG, IGNORED_PTR_ARG, IGNORED_PTR_ARG));
    STRICT_EXPECTED_CALL(HTTPHeaders_AddHeaderNameValuePair(IGNORED_PTR_ARG, IGNORED_PTR_ARG, IGNORED_PTR_ARG));
    STRICT_EXPECTED_CALL(gballoc_malloc(IGNORED_NUM_ARG));
    STRICT_EXPECTED_CALL(UniqueId_Generate(IGNORED_PTR_ARG, IGNORED_NUM_ARG));
    STRICT_EXPECTED_CALL(HTTPHeaders_AddHeaderNameValuePair(IGNORED_PTR_ARG, IGNORED_PTR_ARG, IGNORED_PTR_ARG));
    STRICT_EXPECTED_CALL(HTTPHeaders_AddHeaderNameValuePair(IGNORED_PTR_ARG, IGNORED_PTR_ARG, IGNORED_PTR_ARG));
    STRICT_EXPECTED_CALL(HTTPHeaders_AddHeaderNameValuePair(IGNORED_PTR_ARG, IGNORED_PTR_ARG, IGNORED_PTR_ARG));
    STRICT_EXPECTED_CALL(gballoc_free(IGNORED_PTR_ARG));    //cannot fail

    STRICT_EXPECTED_CALL(STRING_c_str(IGNORED_PTR_ARG));
    STRICT_EXPECTED_CALL(IoTHubClient_Auth_Get_SasToken(IGNORED_PTR_ARG, IGNORED_PTR_ARG, IGNORED_NUM_ARG, IGNORED_PTR_ARG));
    STRICT_EXPECTED_CALL(HTTPHeaders_ReplaceHeaderNameValuePair(IGNORED_PTR_ARG, IGNORED_PTR_ARG, IGNORED_PTR_ARG));
    STRICT_EXPECTED_CALL(STRING_c_str(IGNORED_PTR_ARG));
    STRICT_EXPECTED_CALL(HTTPHeaders_ReplaceHeaderNameValuePair(IGNORED_PTR_ARG, IGNORED_PTR_ARG, IGNORED_PTR_ARG));
    STRICT_EXPECTED_CALL(STRING_delete(IGNORED_PTR_ARG));   //cannot fail
    STRICT_EXPECTED_CALL(STRING_delete(IGNORED_PTR_ARG));   //cannot fail
    STRICT_EXPECTED_CALL(gballoc_free(IGNORED_PTR_ARG));    //cannot fail

    STRICT_EXPECTED_CALL(STRING_c_str(IGNORED_PTR_ARG));
    STRICT_EXPECTED_CALL(HTTPAPIEX_Create(IGNORED_PTR_ARG));
    STRICT_EXPECTED_CALL(IoTHubClient_Auth_Get_TrustBundle(IGNORED_PTR_ARG, IGNORED_PTR_ARG));
    STRICT_EXPECTED_CALL(HTTPAPIEX_SetOption(IGNORED_PTR_ARG, IGNORED_PTR_ARG, IGNORED_PTR_ARG));
    STRICT_EXPECTED_CALL(HTTPAPIEX_ExecuteRequest(IGNORED_PTR_ARG, HTTPAPI_REQUEST_POST, IGNORED_PTR_ARG, IGNORED_PTR_ARG, IGNORED_PTR_ARG, IGNORED_PTR_ARG, NULL, IGNORED_PTR_ARG));
    STRICT_EXPECTED_CALL(HTTPHeaders_Free(IGNORED_PTR_ARG));    //cannot fail
    STRICT_EXPECTED_CALL(STRING_delete(IGNORED_PTR_ARG));       //cannot fail
    STRICT_EXPECTED_CALL(HTTPAPIEX_Destroy(IGNORED_PTR_ARG));   //cannot fail
    STRICT_EXPECTED_CALL(gballoc_free(IGNORED_PTR_ARG));        //cannot fail
}
コード例 #2
0
static int prov_sc_get_record(PROVISIONING_SERVICE_CLIENT_HANDLE prov_client, const char* id, void** handle_ptr, HANDLE_FUNCTION_VECTOR vector, const char* path_format)
{
    int result = 0;

    if (prov_client == NULL)
    {
        LogError("Invalid Provisioning Client Handle");
        result = __FAILURE__;
    }
    else if (id == NULL)
    {
        LogError("Invalid id");
        result = __FAILURE__;
    }
    else if (handle_ptr == NULL)
    {
        LogError("Invalid handle");
        result = __FAILURE__;
    }
    else
    {
        STRING_HANDLE registration_path = create_registration_path(path_format, id);
        if (registration_path == NULL)
        {
            LogError("Failed to construct a registration path");
            result = __FAILURE__;
        }
        else
        {
            HTTP_HEADERS_HANDLE request_headers;
            if ((request_headers = construct_http_headers(prov_client, NULL, HTTP_CLIENT_REQUEST_GET)) == NULL)
            {
                LogError("Failure constructing http headers");
                result = __FAILURE__;
            }
            else
            {
                result = rest_call(prov_client, HTTP_CLIENT_REQUEST_GET, STRING_c_str(registration_path), request_headers, NULL);

                if (result == 0)
                {
                    void* handle;
                    if ((handle = vector.deserializeFromJson(prov_client->response)) == NULL)
                    {
                        LogError("Failure constructing new enrollment structure from json response");
                        result = __FAILURE__;
                    }
                    *handle_ptr = handle;
                }
                clear_response(prov_client);
            }
            HTTPHeaders_Free(request_headers);
        }
        STRING_delete(registration_path);
    }

    return result;
}
コード例 #3
0
ファイル: httpapiex.c プロジェクト: Ahmed-Salama/Project_JAR
/*any other code is error*/
static int buildRequestHttpHeadersHandle(HTTPAPIEX_HANDLE_DATA *handleData, BUFFER_HANDLE requestContent, HTTP_HEADERS_HANDLE originalRequestHttpHeadersHandle, bool* isOriginalRequestHttpHeadersHandle, HTTP_HEADERS_HANDLE* toBeUsedRequestHttpHeadersHandle)
{
    int result;


    if (originalRequestHttpHeadersHandle != NULL)
    {
        *toBeUsedRequestHttpHeadersHandle = originalRequestHttpHeadersHandle;
        *isOriginalRequestHttpHeadersHandle = true;

    }
    else
    {
        /*Codes_SRS_HTTPAPIEX_02_009: [If parameter requestHttpHeadersHandle is NULL then HTTPAPIEX_ExecuteRequest shall allocate a temporary internal instance of HTTPHEADERS, shall add to that instance the following headers
        Host:{hostname} - as it was indicated by the call to HTTPAPIEX_Create API call
        Content-Length:the size of the requestContent parameter, and use this instance to all the subsequent calls to HTTPAPI_ExecuteRequest as parameter httpHeadersHandle.]
        */
        *isOriginalRequestHttpHeadersHandle = false;
        *toBeUsedRequestHttpHeadersHandle = HTTPHeaders_Alloc();
    }

    if (*toBeUsedRequestHttpHeadersHandle == NULL)
    {
        result = __LINE__;
        LogError("unable to HTTPHeaders_Alloc\r\n");
    }
    else
    {
        char temp[22];
        (void)size_tToString(temp, 22, BUFFER_length(requestContent)); /*cannot fail, MAX_uint64 has 19 digits*/
        /*Codes_SRS_HTTPAPIEX_02_011: [If parameter requestHttpHeadersHandle is not NULL then HTTPAPIEX_ExecuteRequest shall create or update the following headers of the request:
        Host:{hostname}
        Content-Length:the size of the requestContent parameter, and shall use the so constructed HTTPHEADERS object to all calls to HTTPAPI_ExecuteRequest as parameter httpHeadersHandle.]
        */
        /*Codes_SRS_HTTPAPIEX_02_009: [If parameter requestHttpHeadersHandle is NULL then HTTPAPIEX_ExecuteRequest shall allocate a temporary internal instance of HTTPHEADERS, shall add to that instance the following headers
        Host:{hostname} - as it was indicated by the call to HTTPAPIEX_Create API call
        Content-Length:the size of the requestContent parameter, and use this instance to all the subsequent calls to HTTPAPI_ExecuteRequest as parameter httpHeadersHandle.]
        */
        if (!(
            (HTTPHeaders_ReplaceHeaderNameValuePair(*toBeUsedRequestHttpHeadersHandle, "Host", STRING_c_str(handleData->hostName)) == HTTP_HEADERS_OK) &&
            (HTTPHeaders_ReplaceHeaderNameValuePair(*toBeUsedRequestHttpHeadersHandle, "Content-Length", temp) == HTTP_HEADERS_OK)
            ))
        {
            if (! *isOriginalRequestHttpHeadersHandle)
            { 
                HTTPHeaders_Free(*toBeUsedRequestHttpHeadersHandle);
            }
            *toBeUsedRequestHttpHeadersHandle = NULL;
            result = __LINE__;
        }
        else
        {
            result = 0;
        }
    }
    return result;
}
コード例 #4
0
void prov_sc_destroy(PROVISIONING_SERVICE_CLIENT_HANDLE prov_client)
{
    if (prov_client != NULL)
    {
        free(prov_client->provisioning_service_uri);
        free(prov_client->key_name);
        free(prov_client->access_key);
        free(prov_client->response);
        HTTPHeaders_Free(prov_client->response_headers);
        free(prov_client->certificate);
        free(prov_client);
    }
}
コード例 #5
0
static int prov_sc_delete_record_by_param(PROVISIONING_SERVICE_CLIENT_HANDLE prov_client, const char* id, const char* etag, const char* path_format)
{
    int result = 0;

    if (prov_client == NULL)
    {
        LogError("Invalid Provisioning Client Handle");
        result = __FAILURE__;
    }
    else if (id == NULL)
    {
        LogError("Invalid Id");
        result = __FAILURE__;
    }
    else
    {
        STRING_HANDLE registration_path = create_registration_path(path_format, id);
        if (registration_path == NULL)
        {
            LogError("Failed to construct a registration path");
            result = __FAILURE__;
        }
        else
        {
            HTTP_HEADERS_HANDLE request_headers;
            if ((request_headers = construct_http_headers(prov_client, etag, HTTP_CLIENT_REQUEST_DELETE)) == NULL)
            {
                LogError("Failure constructing http headers");
                result = __FAILURE__;
            }
            else
            {
                result = rest_call(prov_client, HTTP_CLIENT_REQUEST_DELETE, STRING_c_str(registration_path), request_headers, NULL);
                clear_response(prov_client);
            }
            HTTPHeaders_Free(request_headers);
        }
        STRING_delete(registration_path);
    }

    return result;
}
コード例 #6
0
static int prov_sc_query_records(PROVISIONING_SERVICE_CLIENT_HANDLE prov_client, PROVISIONING_QUERY_SPECIFICATION* query_spec, char** cont_token_ptr, PROVISIONING_QUERY_RESPONSE** query_res_ptr, const char* path_format)
{
    int result = 0;

    if (prov_client == NULL)
    {
        LogError("Invalid Provisioning Client Handle");
        result = __FAILURE__;
    }
    else if (query_spec == NULL || query_spec->version != PROVISIONING_QUERY_SPECIFICATION_VERSION_1)
    {
        LogError("Invalid Query details");
        result = __FAILURE__;
    }
    else if (cont_token_ptr == NULL)
    {
        LogError("Invalid Continuation Token pointer");
        result = __FAILURE__;
    }
    else if (query_res_ptr == NULL)
    {
        LogError("Invalid Query Response pointer");
        result = __FAILURE__;
    }
    else
    {
        char* content = NULL;

        //do not serialize the query specification if there is no query_string (i.e. DRS query)
        if ((query_spec->query_string != NULL) && ((content = querySpecification_serializeToJson(query_spec)) == NULL))
        {
            LogError("Failure serializing query specification");
            result = __FAILURE__;
        }
        else
        {
            STRING_HANDLE registration_path = create_registration_path(path_format, query_spec->registration_id);
            if (registration_path == NULL)
            {
                LogError("Failed to construct a registration path");
                result = __FAILURE__;
            }
            else
            {
                HTTP_HEADERS_HANDLE request_headers;
                if ((request_headers = construct_http_headers(prov_client, NULL, HTTP_CLIENT_REQUEST_POST)) == NULL)
                {
                    LogError("Failure constructing http headers");
                    result = __FAILURE__;
                }
                else if ((add_query_headers(request_headers, query_spec->page_size, *cont_token_ptr)) != 0)
                {
                    LogError("Failure adding query headers");
                    result = __FAILURE__;
                }
                else
                {
                    result = rest_call(prov_client, HTTP_CLIENT_REQUEST_POST, STRING_c_str(registration_path), request_headers, content);

                    if (result == 0)
                    {
                        const char* resp_type = NULL;
                        char* new_cont_token = NULL;
                        PROVISIONING_QUERY_TYPE type;

                        if (get_response_headers(prov_client, &new_cont_token, &resp_type) != 0)
                        {
                            LogError("Failure reading response headers");
                            result = __FAILURE__;
                        }
                        else if ((type = queryType_stringToEnum(resp_type)) == QUERY_TYPE_INVALID)
                        {
                            LogError("Failure to parse response type");
                            result = __FAILURE__;
                        }
                        else if ((*query_res_ptr = queryResponse_deserializeFromJson(prov_client->response, type)) == NULL)
                        {
                            LogError("Failure deserializing query response");
                            result = __FAILURE__;
                        }
                        free(*cont_token_ptr);
                        *cont_token_ptr = new_cont_token;
                    }
                    else
                    {
                        LogError("Rest call failed");
                    }
                    clear_response(prov_client);
                }
                HTTPHeaders_Free(request_headers);
            }
            STRING_delete(registration_path);
        }
        free(content);
    }

    return result;
}
コード例 #7
0
static int prov_sc_run_bulk_operation(PROVISIONING_SERVICE_CLIENT_HANDLE prov_client, PROVISIONING_BULK_OPERATION* bulk_op, PROVISIONING_BULK_OPERATION_RESULT** bulk_res_ptr , const char* path_format)
{
    int result = 0;

    if (prov_client == NULL)
    {
        LogError("Invalid Provisioning Client Handle");
        result = __FAILURE__;
    }
    else if (bulk_op == NULL)
    {
        LogError("Invalid Bulk Op");
        result = __FAILURE__;
    }
    else if (bulk_op->version != PROVISIONING_BULK_OPERATION_VERSION_1)
    {
        LogError("Invalid Bulk Op Version #");
        result = __FAILURE__;
    }
    else if (bulk_res_ptr == NULL)
    {
        LogError("Invalid Bulk Op Result pointer");
        result = __FAILURE__;
    }
    else
    {
        char* content;
        if ((content = bulkOperation_serializeToJson(bulk_op)) == NULL)
        {
            LogError("Failure serializing bulk operation");
            result = __FAILURE__;
        }
        else
        {
            STRING_HANDLE registration_path = create_registration_path(path_format, NULL);
            if (registration_path == NULL)
            {
                LogError("Failed to construct a registration path");
                result = __FAILURE__;
            }
            else
            {
                HTTP_HEADERS_HANDLE request_headers;
                if ((request_headers = construct_http_headers(prov_client, NULL, HTTP_CLIENT_REQUEST_POST)) == NULL)
                {
                    LogError("Failure constructing http headers");
                    result = __FAILURE__;
                }
                else
                {
                    result = rest_call(prov_client, HTTP_CLIENT_REQUEST_POST, STRING_c_str(registration_path), request_headers, content);
                    
                    if (result == 0)
                    {
                        if ((*bulk_res_ptr = bulkOperationResult_deserializeFromJson(prov_client->response)) == NULL)
                        {
                            LogError("Failure deserializing bulk operation result");
                            result = __FAILURE__;
                        }
                    }
                    else
                    {
                        LogError("Rest call failed");
                    }
                    clear_response(prov_client);
                }
                HTTPHeaders_Free(request_headers);
            }
            STRING_delete(registration_path);
        }
        free(content);
    }

    return result;
}
コード例 #8
0
static int prov_sc_create_or_update_record(PROVISIONING_SERVICE_CLIENT_HANDLE prov_client, void** handle_ptr, HANDLE_FUNCTION_VECTOR vector, const char* path_format)
{
    int result = 0;
    void* handle;

    if (prov_client == NULL)
    {
        LogError("Invalid Provisioning Client Handle");
        result = __FAILURE__;
    }
    else if ((handle_ptr == NULL) || ((handle = *handle_ptr) == NULL))
    {
        LogError("Invalid handle");
        result = __FAILURE__;
    }
    else
    {
        char* content;
        if ((content = vector.serializeToJson(handle)) == NULL)
        {
            LogError("Failure serializing enrollment");
            result = __FAILURE__;
        }
        else
        {
            STRING_HANDLE registration_path = NULL;
            const char* id = NULL;
            if ((id = vector.getId(handle)) == NULL)
            {
                LogError("Given model does not have a valid ID");
                result = __FAILURE__;
            }
            else if ((registration_path = create_registration_path(path_format, id)) == NULL)
            {
                LogError("Failed to construct a registration path");
                result = __FAILURE__;
            }
            else
            {
                HTTP_HEADERS_HANDLE request_headers;
                if ((request_headers = construct_http_headers(prov_client, vector.getEtag(handle), HTTP_CLIENT_REQUEST_PUT)) == NULL)
                {
                    LogError("Failure constructing headers");
                    result = __FAILURE__;
                }
                else
                {
                    result = rest_call(prov_client, HTTP_CLIENT_REQUEST_PUT, STRING_c_str(registration_path), request_headers, content);

                    if (result == 0)
                    {
                        INDIVIDUAL_ENROLLMENT_HANDLE new_handle;
                        if ((new_handle = vector.deserializeFromJson(prov_client->response)) == NULL)
                        {
                            LogError("Failure constructing new enrollment structure from json response");
                            result = __FAILURE__;
                        }

                        //Free the user submitted enrollment, and replace the pointer reference to a new enrollment from the provisioning service
                        vector.destroy(handle);
                        *handle_ptr = new_handle;
                    }
                    else
                    {
                        LogError("Rest call failed");
                    }
                    clear_response(prov_client);
                }
                HTTPHeaders_Free(request_headers);
            }
            STRING_delete(registration_path);
        }
        free(content);
    }

    return result;
}
コード例 #9
0
static IOTHUB_DEVICE_METHOD_RESULT sendHttpRequestDeviceMethod(IOTHUB_SERVICE_CLIENT_DEVICE_METHOD_HANDLE serviceClientDeviceMethodHandle, IOTHUB_DEVICEMETHOD_REQUEST_MODE iotHubDeviceMethodRequestMode, const char* deviceName, BUFFER_HANDLE deviceJsonBuffer, BUFFER_HANDLE responseBuffer)
{
    IOTHUB_DEVICE_METHOD_RESULT result;

    STRING_HANDLE uriResouce;
    STRING_HANDLE accessKey;
    STRING_HANDLE keyName;
    HTTPAPIEX_SAS_HANDLE httpExApiSasHandle;
    HTTPAPIEX_HANDLE httpExApiHandle;
    HTTP_HEADERS_HANDLE httpHeader;

    if ((uriResouce = STRING_construct(serviceClientDeviceMethodHandle->hostname)) == NULL)
    {
        LogError("STRING_construct failed for uriResource");
        result = IOTHUB_DEVICE_METHOD_ERROR;
    }
    else if ((accessKey = STRING_construct(serviceClientDeviceMethodHandle->sharedAccessKey)) == NULL)
    {
        LogError("STRING_construct failed for accessKey");
        STRING_delete(uriResouce);
        result = IOTHUB_DEVICE_METHOD_ERROR;
    }
    else if ((keyName = STRING_construct(serviceClientDeviceMethodHandle->keyName)) == NULL)
    {
        LogError("STRING_construct failed for keyName");
        STRING_delete(accessKey);
        STRING_delete(uriResouce);
        result = IOTHUB_DEVICE_METHOD_ERROR;
    }
    else if ((httpHeader = createHttpHeader()) == NULL)
    {
        LogError("HttpHeader creation failed");
        STRING_delete(keyName);
        STRING_delete(accessKey);
        STRING_delete(uriResouce);
        result = IOTHUB_DEVICE_METHOD_ERROR;
    }
    else if ((httpExApiSasHandle = HTTPAPIEX_SAS_Create(accessKey, uriResouce, keyName)) == NULL)
    {
        LogError("HTTPAPIEX_SAS_Create failed");
        HTTPHeaders_Free(httpHeader);
        STRING_delete(keyName);
        STRING_delete(accessKey);
        STRING_delete(uriResouce);
        result = IOTHUB_DEVICE_METHOD_HTTPAPI_ERROR;
    }
    else if ((httpExApiHandle = HTTPAPIEX_Create(serviceClientDeviceMethodHandle->hostname)) == NULL)
    {
        LogError("HTTPAPIEX_Create failed");
        HTTPAPIEX_SAS_Destroy(httpExApiSasHandle);
        HTTPHeaders_Free(httpHeader);
        STRING_delete(keyName);
        STRING_delete(accessKey);
        STRING_delete(uriResouce);
        result = IOTHUB_DEVICE_METHOD_HTTPAPI_ERROR;
    }
    else 
    {
        HTTPAPI_REQUEST_TYPE httpApiRequestType = HTTPAPI_REQUEST_GET;
        STRING_HANDLE relativePath;
        unsigned int statusCode = 0;
        unsigned char is_error = 0;

        if (iotHubDeviceMethodRequestMode == IOTHUB_DEVICEMETHOD_REQUEST_INVOKE)
        {
            httpApiRequestType = HTTPAPI_REQUEST_POST;
        }
        else
        {
            is_error = 1;
        }

        if (is_error)
        {
            LogError("Invalid request type");
            result = IOTHUB_DEVICE_METHOD_HTTPAPI_ERROR;
        }
        else
        {
            if ((relativePath = createRelativePath(iotHubDeviceMethodRequestMode, deviceName)) == NULL)
            {
                LogError("Failure creating relative path");
                result = IOTHUB_DEVICE_METHOD_ERROR;
            }
            else if (HTTPAPIEX_SAS_ExecuteRequest(httpExApiSasHandle, httpExApiHandle, httpApiRequestType, STRING_c_str(relativePath), httpHeader, deviceJsonBuffer, &statusCode, NULL, responseBuffer) != HTTPAPIEX_OK)
            {
                LogError("HTTPAPIEX_SAS_ExecuteRequest failed");
                STRING_delete(relativePath);
                result = IOTHUB_DEVICE_METHOD_HTTPAPI_ERROR;
            }
            else
            {
                STRING_delete(relativePath);
                if (statusCode == 200)
                {
                    result = IOTHUB_DEVICE_METHOD_OK;
                }
                else
                {
                    LogError("Http Failure status code %d.", statusCode);
                    result = IOTHUB_DEVICE_METHOD_ERROR;
                }
            }
        }
        HTTPAPIEX_Destroy(httpExApiHandle);
        HTTPAPIEX_SAS_Destroy(httpExApiSasHandle);
        HTTPHeaders_Free(httpHeader);
        STRING_delete(keyName);
        STRING_delete(accessKey);
        STRING_delete(uriResouce);
    }
    return result;
}
コード例 #10
0
ファイル: blob.c プロジェクト: FarizaH/azure-iot-sdks
BLOB_RESULT Blob_UploadFromSasUri(const char* SASURI, const unsigned char* source, size_t size)
{
    BLOB_RESULT result;
    /*Codes_SRS_BLOB_02_001: [ If SASURI is NULL then Blob_UploadFromSasUri shall fail and return BLOB_INVALID_ARG. ]*/
    if (SASURI == NULL)
    {
        LogError("parameter SASURI is NULL");
        result = BLOB_INVALID_ARG;
    }
    else
    {
        /*Codes_SRS_BLOB_02_002: [ If source is NULL and size is not zero then Blob_UploadFromSasUri shall fail and return BLOB_INVALID_ARG. ]*/
        if (
            (size > 0) &&
            (source == NULL)
           )
        {
            LogError("combination of source = %p and size = %zd is invalid", source, size);
            result = BLOB_INVALID_ARG;
        }
        /*Codes_SRS_BLOB_02_003: [ If size is bigger or equal to 64M then Blob_UploadFromSasUri shall fail and return BLOB_NOT_IMPLEMENTED. ]*/
        else if (size >= 64 * 1024 * 1024)
        {
            LogError("upload of files greater than 64M is not implemented");
            result = BLOB_NOT_IMPLEMENTED;
        }
        else
        {
            /*Codes_SRS_BLOB_02_004: [ Blob_UploadFromSasUri shall copy from SASURI the hostname to a new const char*. ]*/
            /*to find the hostname, the following logic is applied:*/
            /*the hostname starts at the first character after ":\\"*/
            /*the hostname ends at the first character before the next "\" after ":\\"*/
            const char* hostnameBegin = strstr(SASURI, ":\\\\");
            if (hostnameBegin == NULL)
            {
                /*Codes_SRS_BLOB_02_005: [ If the hostname cannot be determined, then Blob_UploadFromSasUri shall fail and return BLOB_INVALID_ARG. ]*/
                LogError("hostname cannot be determined");
                result = BLOB_INVALID_ARG;
            }
            else
            {
                hostnameBegin += 3; /*have to skip 3 characters which are ":\\"*/
                const char* hostnameEnd = strchr(hostnameBegin, '\\');
                if (hostnameEnd == NULL)
                {
                    /*Codes_SRS_BLOB_02_005: [ If the hostname cannot be determined, then Blob_UploadFromSasUri shall fail and return BLOB_INVALID_ARG. ]*/
                    LogError("hostname cannot be determined");
                    result = BLOB_INVALID_ARG;
                }
                else
                {
                    size_t hostnameSize = hostnameEnd - hostnameBegin;
                    char* hostname = (char*)malloc(hostnameSize + 1); /*+1 because of '\0' at the end*/
                    if (hostname == NULL)
                    {
                        /*Codes_SRS_BLOB_02_016: [ If the hostname copy cannot be made then then Blob_UploadFromSasUri shall fail and return BLOB_ERROR ]*/
                        LogError("oom - out of memory");
                        result = BLOB_ERROR;
                    }
                    else
                    {
                        HTTPAPIEX_HANDLE httpApiExHandle;
                        memcpy(hostname, hostnameBegin, hostnameSize);
                        hostname[hostnameSize] = '\0';

                        /*Codes_SRS_BLOB_02_006: [ Blob_UploadFromSasUri shall create a new HTTPAPI_EX_HANDLE by calling HTTPAPIEX_Create passing the hostname. ]*/
                        httpApiExHandle = HTTPAPIEX_Create(hostname);
                        if (httpApiExHandle == NULL)
                        {
                            /*Codes_SRS_BLOB_02_007: [ If HTTPAPIEX_Create fails then Blob_UploadFromSasUri shall fail and return BLOB_ERROR. ]*/
                            LogError("unable to create a HTTPAPIEX_HANDLE");
                            result = BLOB_ERROR;
                        }
                        else
                        {
                            /*Codes_SRS_BLOB_02_008: [ Blob_UploadFromSasUri shall compute the relative path of the request from the SASURI parameter. ]*/
                            const char* relativePath = hostnameEnd; /*this is where the relative path begins in the SasUri*/

                            /*Codes_SRS_BLOB_02_010: [ Blob_UploadFromSasUri shall create a BUFFER_HANDLE from source and size parameters. ]*/
                            BUFFER_HANDLE requestBuffer = BUFFER_create(source, size);
                            if (requestBuffer == NULL)
                            {
                                /*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. ]*/
                                LogError("unable to BUFFER_create");
                                result = BLOB_ERROR;
                            }
                            else
                            {
                                /*Codes_SRS_BLOB_02_009: [ Blob_UploadFromSasUri shall create an HTTP_HEADERS_HANDLE for the request HTTP headers carrying the following headers: ]*/
                                HTTP_HEADERS_HANDLE requestHttpHeaders = HTTPHeaders_Alloc();
                                if (requestHttpHeaders == NULL)
                                {
                                    /*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. ]*/
                                    LogError("unable to HTTPHeaders_Alloc");
                                    result = BLOB_ERROR;
                                }
                                else
                                {
                                    if (HTTPHeaders_AddHeaderNameValuePair(requestHttpHeaders, "x-ms-blob-type", "BlockBlob") != HTTP_HEADERS_OK)
                                    {
                                        /*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. ]*/
                                        LogError("unable to HTTPHeaders_AddHeaderNameValuePair");
                                        result = BLOB_ERROR;
                                    }
                                    else
                                    {
                                        int statusCode;
                                        /*Codes_SRS_BLOB_02_012: [ Blob_UploadFromSasUri shall call HTTPAPIEX_ExecuteRequest passing the parameters previously build. ]*/
                                        if (HTTPAPIEX_ExecuteRequest(httpApiExHandle, HTTPAPI_REQUEST_PUT, relativePath, requestHttpHeaders, requestBuffer, &statusCode, NULL, NULL) != HTTPAPIEX_OK)
                                        {
                                            /*Codes_SRS_BLOB_02_013: [ If HTTPAPIEX_ExecuteRequest fails, then Blob_UploadFromSasUri shall fail and return BLOB_HTTP_ERROR. ]*/
                                            LogError("failed to HTTPAPIEX_ExecuteRequest");
                                            result = BLOB_HTTP_ERROR;
                                        }
                                        else
                                        {
                                            if (statusCode >= 300)
                                            {
                                                /*Codes_SRS_BLOB_02_014: [ If the statusCode returned by HTTPAPIEX_ExecuteRequest is greater or equal to 300, then Blob_UploadFromSasUri shall fail and return BLOB_HTTP_ERROR. ]*/
                                                LogError("server returns %d HTTP code", statusCode);
                                                result = BLOB_HTTP_ERROR;
                                            }
                                            else
                                            {
                                                /*Codes_SRS_BLOB_02_015: [ Otherwise, HTTPAPIEX_ExecuteRequest shall succeed and return BLOB_OK. ]*/
                                                result = BLOB_OK;
                                            }
                                        }
                                    }
                                    HTTPHeaders_Free(requestHttpHeaders);
                                }
                                BUFFER_delete(requestBuffer);
                            }
                            HTTPAPIEX_Destroy(httpApiExHandle);
                        }
                        free(hostname);
                    }
                }
            }
        }
    }
    return result;
}
コード例 #11
0
ファイル: blob.c プロジェクト: AkhilVashisht/azure-iot-sdks
BLOB_RESULT Blob_UploadFromSasUri(const char* SASURI, const unsigned char* source, size_t size, unsigned int* httpStatus, BUFFER_HANDLE httpResponse)
{
    BLOB_RESULT result;
    /*Codes_SRS_BLOB_02_001: [ If SASURI is NULL then Blob_UploadFromSasUri shall fail and return BLOB_INVALID_ARG. ]*/
    if (SASURI == NULL)
    {
        LogError("parameter SASURI is NULL");
        result = BLOB_INVALID_ARG;
    }
    else
    {
        /*Codes_SRS_BLOB_02_002: [ If source is NULL and size is not zero then Blob_UploadFromSasUri shall fail and return BLOB_INVALID_ARG. ]*/
        if (
            (size > 0) &&
            (source == NULL)
            )
        {
            LogError("combination of source = %p and size = %zu is invalid", source, size);
            result = BLOB_INVALID_ARG;
        }
        /*Codes_SRS_BLOB_02_034: [ If size is bigger than 50000*4*1024*1024 then Blob_UploadFromSasUri shall fail and return BLOB_INVALID_ARG. ]*/
        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."*/
        {
            LogError("size too big (%zu)", size);
            result = BLOB_INVALID_ARG;
        }
        else
        {
            /*Codes_SRS_BLOB_02_017: [ Blob_UploadFromSasUri shall copy from SASURI the hostname to a new const char* ]*/
            /*Codes_SRS_BLOB_02_004: [ Blob_UploadFromSasUri shall copy from SASURI the hostname to a new const char*. ]*/
            /*to find the hostname, the following logic is applied:*/
            /*the hostname starts at the first character after "://"*/
            /*the hostname ends at the first character before the next "/" after "://"*/
            const char* hostnameBegin = strstr(SASURI, "://");
            if (hostnameBegin == NULL)
            {
                /*Codes_SRS_BLOB_02_005: [ If the hostname cannot be determined, then Blob_UploadFromSasUri shall fail and return BLOB_INVALID_ARG. ]*/
                LogError("hostname cannot be determined");
                result = BLOB_INVALID_ARG;
            }
            else
            {
                hostnameBegin += 3; /*have to skip 3 characters which are "://"*/
                const char* hostnameEnd = strchr(hostnameBegin, '/');
                if (hostnameEnd == NULL)
                {
                    /*Codes_SRS_BLOB_02_005: [ If the hostname cannot be determined, then Blob_UploadFromSasUri shall fail and return BLOB_INVALID_ARG. ]*/
                    LogError("hostname cannot be determined");
                    result = BLOB_INVALID_ARG;
                }
                else
                {
                    size_t hostnameSize = hostnameEnd - hostnameBegin;
                    char* hostname = (char*)malloc(hostnameSize + 1); /*+1 because of '\0' at the end*/
                    if (hostname == NULL)
                    {
                        /*Codes_SRS_BLOB_02_016: [ If the hostname copy cannot be made then then Blob_UploadFromSasUri shall fail and return BLOB_ERROR ]*/
                        LogError("oom - out of memory");
                        result = BLOB_ERROR;
                    }
                    else
                    {
                        HTTPAPIEX_HANDLE httpApiExHandle;
                        memcpy(hostname, hostnameBegin, hostnameSize);
                        hostname[hostnameSize] = '\0';

                        /*Codes_SRS_BLOB_02_006: [ Blob_UploadFromSasUri shall create a new HTTPAPI_EX_HANDLE by calling HTTPAPIEX_Create passing the hostname. ]*/
                        /*Codes_SRS_BLOB_02_018: [ Blob_UploadFromSasUri shall create a new HTTPAPI_EX_HANDLE by calling HTTPAPIEX_Create passing the hostname. ]*/
                        httpApiExHandle = HTTPAPIEX_Create(hostname);
                        if (httpApiExHandle == NULL)
                        {
                            /*Codes_SRS_BLOB_02_007: [ If HTTPAPIEX_Create fails then Blob_UploadFromSasUri shall fail and return BLOB_ERROR. ]*/
                            LogError("unable to create a HTTPAPIEX_HANDLE");
                            result = BLOB_ERROR;
                        }
                        else
                        {
                            /*Codes_SRS_BLOB_02_008: [ Blob_UploadFromSasUri shall compute the relative path of the request from the SASURI parameter. ]*/
                            /*Codes_SRS_BLOB_02_019: [ Blob_UploadFromSasUri shall compute the base relative path of the request from the SASURI parameter. ]*/
                            const char* relativePath = hostnameEnd; /*this is where the relative path begins in the SasUri*/

                            if (size < 64 * 1024 * 1024) /*code path for sizes <64MB*/
                            {
                                /*Codes_SRS_BLOB_02_010: [ Blob_UploadFromSasUri shall create a BUFFER_HANDLE from source and size parameters. ]*/
                                BUFFER_HANDLE requestBuffer = BUFFER_create(source, size);
                                if (requestBuffer == NULL)
                                {
                                    /*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. ]*/
                                    LogError("unable to BUFFER_create");
                                    result = BLOB_ERROR;
                                }
                                else
                                {
                                    /*Codes_SRS_BLOB_02_009: [ Blob_UploadFromSasUri shall create an HTTP_HEADERS_HANDLE for the request HTTP headers carrying the following headers: ]*/
                                    HTTP_HEADERS_HANDLE requestHttpHeaders = HTTPHeaders_Alloc();
                                    if (requestHttpHeaders == NULL)
                                    {
                                        /*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. ]*/
                                        LogError("unable to HTTPHeaders_Alloc");
                                        result = BLOB_ERROR;
                                    }
                                    else
                                    {
                                        if (HTTPHeaders_AddHeaderNameValuePair(requestHttpHeaders, "x-ms-blob-type", "BlockBlob") != HTTP_HEADERS_OK)
                                        {
                                            /*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. ]*/
                                            LogError("unable to HTTPHeaders_AddHeaderNameValuePair");
                                            result = BLOB_ERROR;
                                        }
                                        else
                                        {
                                            /*Codes_SRS_BLOB_02_012: [ Blob_UploadFromSasUri shall call HTTPAPIEX_ExecuteRequest passing the parameters previously build, httpStatus and httpResponse ]*/
                                            if (HTTPAPIEX_ExecuteRequest(httpApiExHandle, HTTPAPI_REQUEST_PUT, relativePath, requestHttpHeaders, requestBuffer, httpStatus, NULL, httpResponse) != HTTPAPIEX_OK)
                                            {
                                                /*Codes_SRS_BLOB_02_013: [ If HTTPAPIEX_ExecuteRequest fails, then Blob_UploadFromSasUri shall fail and return BLOB_HTTP_ERROR. ]*/
                                                LogError("failed to HTTPAPIEX_ExecuteRequest");
                                                result = BLOB_HTTP_ERROR;
                                            }
                                            else
                                            {
                                                /*Codes_SRS_BLOB_02_015: [ Otherwise, HTTPAPIEX_ExecuteRequest shall succeed and return BLOB_OK. ]*/
                                                result = BLOB_OK;
                                            }
                                        }
                                        HTTPHeaders_Free(requestHttpHeaders);
                                    }
                                    BUFFER_delete(requestBuffer);
                                }
                            }
                            else /*code path for size >= 64MB*/
                            {
                                size_t toUpload = size;
                                /*Codes_SRS_BLOB_02_028: [ Blob_UploadFromSasUri shall construct an XML string with the following content: ]*/
                                STRING_HANDLE xml = STRING_construct("<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<BlockList>"); /*the XML "build as we go"*/
                                if (xml == NULL)
                                {
                                    /*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 ]*/
                                    LogError("failed to STRING_construct");
                                    result = BLOB_HTTP_ERROR;
                                }
                                else
                                {
                                    /*Codes_SRS_BLOB_02_021: [ For every block of 4MB the following operations shall happen: ]*/
                                    unsigned int blockID = 0;
                                    result = BLOB_ERROR;

                                    int isError = 0; /*used to cleanly exit the loop*/
                                    do
                                    {
                                        /*setting this block size*/
                                        size_t thisBlockSize = (toUpload > BLOCK_SIZE) ? BLOCK_SIZE : toUpload;
                                        /*Codes_SRS_BLOB_02_020: [ Blob_UploadFromSasUri shall construct a BASE64 encoded string from the block ID (000000... 0499999) ]*/
                                        char temp[7]; /*this will contain 000000... 049999*/
                                        if (sprintf(temp, "%6u", (unsigned int)blockID) != 6) /*produces 000000... 049999*/
                                        {
                                            /*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 ]*/
                                            LogError("failed to sprintf");
                                            result = BLOB_ERROR;
                                            isError = 1;
                                        }
                                        else
                                        {
                                            STRING_HANDLE blockIdString = Base64_Encode_Bytes((const unsigned char*)temp, 6);
                                            if (blockIdString == NULL)
                                            {
                                                /*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 ]*/
                                                LogError("unable to Base64_Encode_Bytes");
                                                result = BLOB_ERROR;
                                                isError = 1;
                                            }
                                            else
                                            {
                                                /*add the blockId base64 encoded to the XML*/
                                                if (!(
                                                    (STRING_concat(xml, "<Latest>")==0) &&
                                                    (STRING_concat_with_STRING(xml, blockIdString)==0) &&
                                                    (STRING_concat(xml, "</Latest>") == 0)
                                                    ))
                                                {
                                                    /*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 ]*/
                                                    LogError("unable to STRING_concat");
                                                    result = BLOB_ERROR;
                                                    isError = 1;
                                                }
                                                else
                                                {
                                                    /*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" ]*/
                                                    STRING_HANDLE newRelativePath = STRING_construct(relativePath);
                                                    if (newRelativePath == NULL)
                                                    {
                                                        /*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 ]*/
                                                        LogError("unable to STRING_construct");
                                                        result = BLOB_ERROR;
                                                        isError = 1;
                                                    }
                                                    else
                                                    {
                                                        if (!(
                                                            (STRING_concat(newRelativePath, "&comp=block&blockid=") == 0) &&
                                                            (STRING_concat_with_STRING(newRelativePath, blockIdString) == 0)
                                                            ))
                                                        {
                                                            /*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 ]*/
                                                            LogError("unable to STRING concatenate");
                                                            result = BLOB_ERROR;
                                                            isError = 1;
                                                        }
                                                        else
                                                        {
                                                            /*Codes_SRS_BLOB_02_023: [ Blob_UploadFromSasUri shall create a BUFFER_HANDLE from source and size parameters. ]*/
                                                            BUFFER_HANDLE requestContent = BUFFER_create(source + (size - toUpload), thisBlockSize);
                                                            if (requestContent == NULL)
                                                            {
                                                                /*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 ]*/
                                                                LogError("unable to BUFFER_create");
                                                                result = BLOB_ERROR;
                                                                isError = 1;
                                                            }
                                                            else
                                                            {
                                                                /*Codes_SRS_BLOB_02_024: [ Blob_UploadFromSasUri shall call HTTPAPIEX_ExecuteRequest with a PUT operation, passing httpStatus and httpResponse. ]*/
                                                                if (HTTPAPIEX_ExecuteRequest(
                                                                    httpApiExHandle,
                                                                    HTTPAPI_REQUEST_PUT,
                                                                    STRING_c_str(newRelativePath),
                                                                    NULL,
                                                                    requestContent,
                                                                    httpStatus,
                                                                    NULL,
                                                                    httpResponse) != HTTPAPIEX_OK
                                                                    )
                                                                {
                                                                    /*Codes_SRS_BLOB_02_025: [ If HTTPAPIEX_ExecuteRequest fails then Blob_UploadFromSasUri shall fail and return BLOB_HTTP_ERROR. ]*/
                                                                    LogError("unable to HTTPAPIEX_ExecuteRequest");
                                                                    result = BLOB_HTTP_ERROR;
                                                                    isError = 1;
                                                                }
                                                                else if (*httpStatus >= 300)
                                                                {
                                                                    /*Codes_SRS_BLOB_02_026: [ Otherwise, if HTTP response code is >=300 then Blob_UploadFromSasUri shall succeed and return BLOB_OK. ]*/
                                                                    LogError("HTTP status from storage does not indicate success (%d)", (int)*httpStatus);
                                                                    result = BLOB_OK;
                                                                    isError = 1;
                                                                }
                                                                else
                                                                {
                                                                    /*Codes_SRS_BLOB_02_027: [ Otherwise Blob_UploadFromSasUri shall continue execution. ]*/
                                                                }
                                                                BUFFER_delete(requestContent);
                                                            }
                                                        }
                                                        STRING_delete(newRelativePath);
                                                    }
                                                }
                                                STRING_delete(blockIdString);
                                            }
                                        }

                                        blockID++;
                                        toUpload -= thisBlockSize;
                                    } while ((toUpload > 0) && !isError);

                                    if (isError)
                                    {
                                        /*do nothing, it will be reported "as is"*/
                                    }
                                    else
                                    {
                                        /*complete the XML*/
                                        if (STRING_concat(xml, "</BlockList>") != 0)
                                        {
                                            /*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 ]*/
                                            LogError("failed to STRING_concat");
                                            result = BLOB_ERROR;
                                        }
                                        else
                                        {
                                            /*Codes_SRS_BLOB_02_029: [Blob_UploadFromSasUri shall construct a new relativePath from following string : base relativePath + "&comp=blocklist"]*/
                                            STRING_HANDLE newRelativePath = STRING_construct(relativePath);
                                            if (newRelativePath == NULL)
                                            {
                                                /*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 ]*/
                                                LogError("failed to STRING_construct");
                                                result = BLOB_ERROR;
                                            }
                                            else
                                            {
                                                if (STRING_concat(newRelativePath, "&comp=blocklist") != 0)
                                                {
                                                    /*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 ]*/
                                                    LogError("failed to STRING_concat");
                                                    result = BLOB_ERROR;
                                                }
                                                else
                                                {
                                                    /*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. ]*/
                                                    const char* s = STRING_c_str(xml);
                                                    BUFFER_HANDLE xmlAsBuffer = BUFFER_create((const unsigned char*)s, strlen(s));
                                                    if (xmlAsBuffer == NULL)
                                                    {
                                                        /*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 ]*/
                                                        LogError("failed to BUFFER_create");
                                                        result = BLOB_ERROR;
                                                    }
                                                    else
                                                    {
                                                        if (HTTPAPIEX_ExecuteRequest(
                                                            httpApiExHandle,
                                                            HTTPAPI_REQUEST_PUT,
                                                            STRING_c_str(newRelativePath),
                                                            NULL,
                                                            xmlAsBuffer,
                                                            httpStatus,
                                                            NULL,
                                                            httpResponse
                                                        ) != HTTPAPIEX_OK)
                                                        {
                                                            /*Codes_SRS_BLOB_02_031: [ If HTTPAPIEX_ExecuteRequest fails then Blob_UploadFromSasUri shall fail and return BLOB_HTTP_ERROR. ]*/
                                                            LogError("unable to HTTPAPIEX_ExecuteRequest");
                                                            result = BLOB_HTTP_ERROR;
                                                        }
                                                        else
                                                        {
                                                            /*Codes_SRS_BLOB_02_032: [ Otherwise, Blob_UploadFromSasUri shall succeed and return BLOB_OK. ]*/
                                                            result = BLOB_OK;
                                                        }
                                                        BUFFER_delete(xmlAsBuffer);
                                                    }
                                                }
                                                STRING_delete(newRelativePath);
                                            }
                                        }
                                    }
                                    STRING_delete(xml);
                                }
                            }
                            HTTPAPIEX_Destroy(httpApiExHandle);
                        }
                        free(hostname);
                    }
                }
            }
        }
    }
    return result;
}
コード例 #12
0
ファイル: httpapiex.c プロジェクト: Ahmed-Salama/Project_JAR
HTTPAPIEX_RESULT HTTPAPIEX_ExecuteRequest(HTTPAPIEX_HANDLE handle, HTTPAPI_REQUEST_TYPE requestType, const char* relativePath,
    HTTP_HEADERS_HANDLE requestHttpHeadersHandle, BUFFER_HANDLE requestContent, unsigned int* statusCode,
    HTTP_HEADERS_HANDLE responseHttpHeadersHandle, BUFFER_HANDLE responseContent)
{
    HTTPAPIEX_RESULT result;
    /*Codes_SRS_HTTPAPIEX_02_006: [If parameter handle is NULL then HTTPAPIEX_ExecuteRequest shall fail and return HTTPAPIEX_INVALID_ARG.]*/
    if (handle == NULL)
    {
        result = HTTPAPIEX_INVALID_ARG;
        LOG_HTTAPIEX_ERROR();
    }
    else
    {
        /*Codes_SRS_HTTPAPIEX_02_007: [If parameter requestType does not indicate a valid request, HTTPAPIEX_ExecuteRequest shall fail and return HTTPAPIEX_INVALID_ARG.] */
        if (requestType >= COUNT_ARG(HTTPAPI_REQUEST_TYPE_VALUES))
        {
            result = HTTPAPIEX_INVALID_ARG;
            LOG_HTTAPIEX_ERROR();
        }
        else
        {
            HTTPAPIEX_HANDLE_DATA *handleData = (HTTPAPIEX_HANDLE_DATA *)handle;

            /*call to buildAll*/
            const char* toBeUsedRelativePath;
            HTTP_HEADERS_HANDLE toBeUsedRequestHttpHeadersHandle; bool isOriginalRequestHttpHeadersHandle;
            BUFFER_HANDLE toBeUsedRequestContent; bool isOriginalRequestContent;
            unsigned int* toBeUsedStatusCode;
            HTTP_HEADERS_HANDLE toBeUsedResponseHttpHeadersHandle; bool isOriginalResponseHttpHeadersHandle;
            BUFFER_HANDLE toBeUsedResponseContent;  bool isOriginalResponseContent;

            if (buildAllRequests(handleData, requestType, relativePath, requestHttpHeadersHandle, requestContent, statusCode, responseHttpHeadersHandle, responseContent,
                &toBeUsedRelativePath,
                &toBeUsedRequestHttpHeadersHandle, &isOriginalRequestHttpHeadersHandle,
                &toBeUsedRequestContent, &isOriginalRequestContent,
                &toBeUsedStatusCode,
                &toBeUsedResponseHttpHeadersHandle, &isOriginalResponseHttpHeadersHandle,
                &toBeUsedResponseContent, &isOriginalResponseContent) != 0)
            {
                result = HTTPAPIEX_ERROR;
                LOG_HTTAPIEX_ERROR();
            }
            else
            {

                /*Codes_SRS_HTTPAPIEX_02_023: [HTTPAPIEX_ExecuteRequest shall try to execute the HTTP call by ensuring the following API call sequence is respected:]*/
                /*Codes_SRS_HTTPAPIEX_02_024: [If any point in the sequence fails, HTTPAPIEX_ExecuteRequest shall attempt to recover by going back to the previous step and retrying that step.]*/
                /*Codes_SRS_HTTPAPIEX_02_025: [If the first step fails, then the sequence fails.]*/
                /*Codes_SRS_HTTPAPIEX_02_026: [A step shall be retried at most once.]*/
                /*Codes_SRS_HTTPAPIEX_02_027: [If a step has been retried then all subsequent steps shall be retried too.]*/
                bool st[3] = { false, false, false }; /*the three levels of possible failure in resilient send: HTTAPI_Init, HTTPAPI_CreateConnection, HTTPAPI_ExecuteRequest*/
                if (handleData->k == -1)
                {
                    handleData->k = 0;
                }

                do
                {
                    bool goOn;

                    if (handleData->k > 2)
                    {
                        /* error */
                        break;
                    }

                    if (st[handleData->k] == true) /*already been tried*/
                    {
                        goOn = false;
                    }
                    else
                    {
                        switch (handleData->k)
                        {
                        case 0:
                        {
                            if (HTTPAPI_Init() != HTTPAPI_OK)
                            {
                                goOn = false;
                            }
                            else
                            {
                                goOn = true;
                            }
                            break;
                        }
                        case 1:
                        {
                            if ((handleData->httpHandle = HTTPAPI_CreateConnection(STRING_c_str(handleData->hostName))) == NULL)
                            {
                                goOn = false;
                            }
                            else
                            {
                                size_t i;
                                size_t vectorSize = VECTOR_size(handleData->savedOptions);
                                for (i = 0; i < vectorSize; i++)
                                {
                                    /*Codes_SRS_HTTPAPIEX_02_035: [HTTPAPIEX_ExecuteRequest shall pass all the saved options (see HTTPAPIEX_SetOption) to the newly create HTTPAPI_HANDLE in step 2 by calling HTTPAPI_SetOption.]*/
                                    /*Codes_SRS_HTTPAPIEX_02_036: [If setting the option fails, then the failure shall be ignored.] */
                                    HTTPAPIEX_SAVED_OPTION* option = VECTOR_element(handleData->savedOptions, i);
                                    if (HTTPAPI_SetOption(handleData->httpHandle, option->optionName, option->value) != HTTPAPI_OK)
                                    {
                                        LogError("HTTPAPI_SetOption failed when called for option %s\r\n", option->optionName);
                                    }
                                }
                                goOn = true;
                            }
                            break;
                        }
                        case 2:
                        {
                            if (HTTPAPI_ExecuteRequest(handleData->httpHandle, requestType, toBeUsedRelativePath, toBeUsedRequestHttpHeadersHandle, BUFFER_u_char(toBeUsedRequestContent), BUFFER_length(toBeUsedRequestContent), toBeUsedStatusCode, toBeUsedResponseHttpHeadersHandle, toBeUsedResponseContent) != HTTPAPI_OK)
                            {
                                goOn = false;
                            }
                            else
                            {
                                goOn = true;
                            }
                            break;
                        }
                        default:
                        {
                            /*serious error*/
                            goOn = false;
                            break;
                        }
                        }
                    }

                    if (goOn)
                    {
                        if (handleData->k == 2)
                        {
                            /*Codes_SRS_HTTPAPIEX_02_028: [HTTPAPIEX_ExecuteRequest shall return HTTPAPIEX_OK when a call to HTTPAPI_ExecuteRequest has been completed successfully.]*/
                            result = HTTPAPIEX_OK;
                            goto out;
                        }
                        else
                        {
                            st[handleData->k] = true;
                            handleData->k++;
                            st[handleData->k] = false;
                        }
                    }
                    else
                    {
                        st[handleData->k] = false;
                        handleData->k--;
                        switch (handleData->k)
                        {
                        case 0:
                        {
                            HTTPAPI_Deinit();
                            break;
                        }
                        case 1:
                        {
                            HTTPAPI_CloseConnection(handleData->httpHandle);
                            handleData->httpHandle = NULL;
                            break;
                        }
                        case 2:
                        {
                            break;
                        }
                        default:
                        {
                            break;
                        }
                        }
                    }
                } while (handleData->k >= 0);
                /*Codes_SRS_HTTPAPIEX_02_029: [Otherwise, HTTAPIEX_ExecuteRequest shall return HTTPAPIEX_RECOVERYFAILED.] */
                result = HTTPAPIEX_RECOVERYFAILED;
                LogError("unable to recover sending to a working state\r\n");
            out:;
                /*in all cases, unbuild the temporaries*/
                if (isOriginalRequestContent == false)
                {
                    BUFFER_delete(toBeUsedRequestContent);
                }
                if (isOriginalRequestHttpHeadersHandle == false)
                {
                    HTTPHeaders_Free(toBeUsedRequestHttpHeadersHandle);
                }
                if (isOriginalResponseContent == false)
                {
                    BUFFER_delete(toBeUsedResponseContent);
                }
                if (isOriginalResponseHttpHeadersHandle == false)
                {
                    HTTPHeaders_Free(toBeUsedResponseHttpHeadersHandle);
                }
            }
        }
    }
    return result;
}
コード例 #13
0
ファイル: httpapiex.c プロジェクト: Ahmed-Salama/Project_JAR
static int buildAllRequests(HTTPAPIEX_HANDLE_DATA* handle, HTTPAPI_REQUEST_TYPE requestType, const char* relativePath,
    HTTP_HEADERS_HANDLE requestHttpHeadersHandle, BUFFER_HANDLE requestContent, unsigned int* statusCode,
    HTTP_HEADERS_HANDLE responseHttpHeadersHandle, BUFFER_HANDLE responseContent,

    const char** toBeUsedRelativePath, 
    HTTP_HEADERS_HANDLE *toBeUsedRequestHttpHeadersHandle, bool *isOriginalRequestHttpHeadersHandle,
    BUFFER_HANDLE *toBeUsedRequestContent, bool *isOriginalRequestContent,
    unsigned int** toBeUsedStatusCode,
    HTTP_HEADERS_HANDLE *toBeUsedResponseHttpHeadersHandle, bool *isOriginalResponseHttpHeadersHandle,
    BUFFER_HANDLE *toBeUsedResponseContent, bool *isOriginalResponseContent)
{
    int result;
    (void)requestType;
    /*Codes_SRS_HTTPAPIEX_02_013: [If requestContent is NULL then HTTPAPIEX_ExecuteRequest shall behave as if a buffer of zero size would have been used, that is, it shall call HTTPAPI_ExecuteRequest with parameter content = NULL and contentLength = 0.]*/
    /*Codes_SRS_HTTPAPIEX_02_014: [If requestContent is not NULL then its content and its size shall be used for parameters content and contentLength of HTTPAPI_ExecuteRequest.] */
    if (buildBufferIfNotExist(requestContent, isOriginalRequestContent, toBeUsedRequestContent) != 0)
    {
        result = __LINE__;
        LogError("unable to build the request content\r\n");
    }
    else
    {
        if (buildRequestHttpHeadersHandle(handle, *toBeUsedRequestContent, requestHttpHeadersHandle, isOriginalRequestHttpHeadersHandle, toBeUsedRequestHttpHeadersHandle) != 0)
        {
            /*Codes_SRS_HTTPAPIEX_02_010: [If any of the operations in SRS_HTTAPIEX_02_009 fails, then HTTPAPIEX_ExecuteRequest shall return HTTPAPIEX_ERROR.] */
            result = __LINE__;
            if (*isOriginalRequestContent == false) 
            {
                BUFFER_delete(*toBeUsedRequestContent);
            }
            LogError("unable to build the request http headers handle\r\n");
        }
        else
        {
            /*Codes_SRS_HTTPAPIEX_02_008: [If parameter relativePath is NULL then HTTPAPIEX_INVALID_ARG shall not assume a relative path - that is, it will assume an empty path ("").] */
            if (relativePath == NULL)
            {
                *toBeUsedRelativePath = "";
            }
            else
            {
                *toBeUsedRelativePath = relativePath;
            }

            /*Codes_SRS_HTTPAPIEX_02_015: [If statusCode is NULL then HTTPAPIEX_ExecuteRequest shall not write in statusCode the HTTP status code, and it will use a temporary internal int for parameter statusCode to the calls of HTTPAPI_ExecuteRequest.] */
            if (statusCode == NULL)
            {
                /*Codes_SRS_HTTPAPIEX_02_016: [If statusCode is not NULL then If statusCode is NULL then HTTPAPIEX_ExecuteRequest shall use it for parameter statusCode to the calls of HTTPAPI_ExecuteRequest.] */
                *toBeUsedStatusCode = &dummyStatusCode;
            }
            else
            {
                *toBeUsedStatusCode = statusCode;
            }

            /*Codes_SRS_HTTPAPIEX_02_017: [If responseHeaders handle is NULL then HTTPAPIEX_ExecuteRequest shall create a temporary internal instance of HTTPHEADERS object and use that for responseHeaders parameter of HTTPAPI_ExecuteRequest call.] */
            /*Codes_SRS_HTTPAPIEX_02_019: [If responseHeaders is not NULL, then then HTTPAPIEX_ExecuteRequest shall use that object as parameter responseHeaders of HTTPAPI_ExecuteRequest call.] */
            if (buildResponseHttpHeadersHandle(responseHttpHeadersHandle, isOriginalResponseHttpHeadersHandle, toBeUsedResponseHttpHeadersHandle) != 0)
            {
                /*Codes_SRS_HTTPAPIEX_02_018: [If creating the temporary http headers in SRS_HTTPAPIEX_02_017 fails then HTTPAPIEX_ExecuteRequest shall return HTTPAPIEX_ERROR.] */
                result = __LINE__;
                if (*isOriginalRequestContent == false)
                {
                    BUFFER_delete(*toBeUsedRequestContent);
                }
                if (*isOriginalRequestHttpHeadersHandle == false)
                {
                    HTTPHeaders_Free(*toBeUsedRequestHttpHeadersHandle);
                }
                LogError("unable to build response content\r\n");
            }
            else
            {
                /*Codes_SRS_HTTPAPIEX_02_020: [If responseContent is NULL then HTTPAPIEX_ExecuteRequest shall create a temporary internal BUFFER object and use that as parameter responseContent of HTTPAPI_ExecuteRequest call.] */
                /*Codes_SRS_HTTPAPIEX_02_022: [If responseContent is not NULL then HTTPAPIEX_ExecuteRequest use that as parameter responseContent of HTTPAPI_ExecuteRequest call.] */
                if (buildBufferIfNotExist(responseContent, isOriginalResponseContent, toBeUsedResponseContent) != 0)
                {
                    /*Codes_SRS_HTTPAPIEX_02_021: [If creating the BUFFER_HANDLE in SRS_HTTPAPIEX_02_020 fails, then HTTPAPIEX_ExecuteRequest shall return HTTPAPIEX_ERROR.] */
                    result = __LINE__;
                    if (*isOriginalRequestContent == false)
                    {
                        BUFFER_delete(*toBeUsedRequestContent);
                    }
                    if (*isOriginalRequestHttpHeadersHandle == false)
                    {
                        HTTPHeaders_Free(*toBeUsedRequestHttpHeadersHandle);
                    }
                    if (*isOriginalResponseHttpHeadersHandle == false)
                    {
                        HTTPHeaders_Free(*toBeUsedResponseHttpHeadersHandle);
                    }
                    LogError("unable to build response content\r\n");
                }
                else
                {
                    result = 0;
                }
            }
        }
    }
    return result;
}
コード例 #14
0
static BUFFER_HANDLE sendDeviceRegistryInfo(IOTHUB_ACCOUNT_INFO* accountInfo, BUFFER_HANDLE deviceBuffer, HTTPAPI_REQUEST_TYPE requestType)
{
    BUFFER_HANDLE result;

    STRING_HANDLE accessKey = STRING_construct(accountInfo->sharedAccessKey);
    STRING_HANDLE uriResouce = STRING_construct(accountInfo->hostname);
    STRING_HANDLE keyName = STRING_construct(accountInfo->keyName);
    if (accessKey != NULL && uriResouce != NULL && keyName != NULL)
    {
        HTTPAPIEX_SAS_HANDLE httpHandle = HTTPAPIEX_SAS_Create(accessKey, uriResouce, keyName);
        if (httpHandle != NULL)
        {
            HTTPAPIEX_HANDLE httpExApi = HTTPAPIEX_Create(accountInfo->hostname);
            if (httpExApi == NULL)
            {
                LogError("Failure creating httpApiEx with hostname: %s.\r\n", accountInfo->hostname);
                result = NULL;
            }
            else
            {
                char relativePath[256];
                if (sprintf_s(relativePath, 256, RELATIVE_PATH_FMT, accountInfo->deviceId, URL_API_VERSION) <= 0)
                {
                    LogError("Failure creating relative path.\r\n");
                    result = NULL;
                }
                else
                {

                    unsigned int statusCode = 0;

                    // Send PUT method to url
                    HTTP_HEADERS_HANDLE httpHeader = getContentHeaders((deviceBuffer == NULL) ? true : false);
                    if (httpHeader == NULL)
                    {
                        result = NULL;
                    }
                    else
                    {
                        BUFFER_HANDLE responseContent = BUFFER_new();
                        if (HTTPAPIEX_SAS_ExecuteRequest(httpHandle, httpExApi, requestType, relativePath, httpHeader, deviceBuffer, &statusCode, NULL, responseContent) != HTTPAPIEX_OK)
                        {
                            LogError("Failure calling HTTPAPIEX_SAS_ExecuteRequest.\r\n");
                            result = NULL;
                        }
                        else
                        {
                            // 409 means the device is already created so we don't need
                            // to create another one.
                            if (statusCode != 409 && statusCode > 300)
                            {
                                LogError("Http Failure status code %d.\r\n", statusCode);
                                BUFFER_delete(responseContent);
                                result = NULL;
                            }
                            else
                            {
                                result = responseContent;
                            }
                        }
                    }
                    HTTPHeaders_Free(httpHeader);
                }
                HTTPAPIEX_Destroy(httpExApi);
            }
            HTTPAPIEX_SAS_Destroy(httpHandle);
        }
        else
        {
            LogError("Http Failure with HTTPAPIEX_SAS_Create.\r\n");
            result = NULL;
        }
    }
    STRING_delete(accessKey);
    STRING_delete(uriResouce);
    STRING_delete(keyName);
    return result;
}