Ejemplo n.º 1
0
static STRING_HANDLE construct_url()
{
    STRING_HANDLE result;

    /*Codes_SRS_BROKER_17_002: [ Broker_Create shall create a unique id. ]*/
    char uuid[BROKER_GUID_SIZE];
    memset(uuid, 0, BROKER_GUID_SIZE);
    if (UniqueId_Generate(uuid, BROKER_GUID_SIZE) != UNIQUEID_OK)
    {
        LogError("Unable to generate unique Id.");
        result = NULL;
    }
    else
    {
        /*Codes_SRS_BROKER_17_003: [ Broker_Create shall initialize a url consisting of "inproc://" + unique id. ]*/
        result = STRING_construct(INPROC_URL_HEAD);
        if (result == NULL)
        {
            LogError("Unable to construct url.");
        }
        else
        {
            if (STRING_concat(result, uuid) != 0)
            {
                /*Codes_SRS_BROKER_13_003: [ This function shall return NULL if an underlying API call to the platform causes an error. ]*/
                STRING_delete(result);
                LogError("Unable to append uuid to url.");
                result = NULL;
            }
        }
    }
    return result;
}
Ejemplo n.º 2
0
JSON_ENCODER_TOSTRING_RESULT JSONEncoder_CharPtr_ToString(STRING_HANDLE destination, const void* value)
{
    JSON_ENCODER_TOSTRING_RESULT result;

    /*Coes_SRS_JSON_ENCODER_99_047:[ JSONEncoder_CharPtr_ToString shall return JSON_ENCODER_TOSTRING_INVALID_ARG if destination or value parameters passed to it are NULL.]*/
    if ((destination == NULL) ||
        (value == NULL))
    {
        result = JSON_ENCODER_TOSTRING_INVALID_ARG;
        LogError("(result = %s)\r\n", ENUM_TO_STRING(JSON_ENCODER_TOSTRING_RESULT, result));
    }
    /*Codes_SRS_JSON_ENCODER_99_048:[ JSONEncoder_CharPtr_ToString shall use strcpy_s to copy from value to destination.]*/
    else if (STRING_concat(destination, (const char*)value) != 0)
    {
        /*Codes_SRS_JSON_ENCODER_99_049:[ If strcpy_s fails then JSONEncoder_CharPtr_ToString shall return JSON_ENCODER_TOSTRING_ERROR.]*/
        result = JSON_ENCODER_TOSTRING_ERROR;
        LogError("(result = %s)\r\n", ENUM_TO_STRING(JSON_ENCODER_TOSTRING_RESULT, result));
    }
    else
    {
        /*Codes_SRS_JSON_ENCODER_99_050:[ If strcpy_s doesn't fail, then JSONEncoder_CharPtr_ToString shall return JSON_ENCODER_TOSTRING_OK]*/
        result = JSON_ENCODER_TOSTRING_OK;
    }

    return result;
}
Ejemplo n.º 3
0
MULTITREE_RESULT MultiTree_GetName(MULTITREE_HANDLE treeHandle, STRING_HANDLE destination)
{
    MULTITREE_RESULT result;
    /*Codes_SRS_MULTITREE_99_037:[ If treeHandle is NULL, the function shall return MULTITREE_INVALID_ARG.]*/
    if (treeHandle == NULL)
    {
        result = MULTITREE_INVALID_ARG;
        LogError("(result = %s)", ENUM_TO_STRING(MULTITREE_RESULT, result));
    }
    /*Codes_SRS_MULTITREE_99_038:[If destination is NULL, the function shall return MULTITREE_INVALID_ARG.]*/
    else if (destination == NULL)
    {
        result = MULTITREE_INVALID_ARG;
        LogError("(result = %s)", ENUM_TO_STRING(MULTITREE_RESULT, result));
    }
    else
    {
        MULTITREE_HANDLE_DATA *node = (MULTITREE_HANDLE_DATA*)treeHandle;
        /*Codes_SRS_MULTITREE_99_051:[ The function returns MULTITREE_EMPTY_CHILD_NAME when used with the root of the tree.]*/
        if (node->name == NULL)
        {
            result = MULTITREE_EMPTY_CHILD_NAME;
            LogError("(result = %s)", ENUM_TO_STRING(MULTITREE_RESULT, result));
        }
        /*Codes_SRS_MULTITREE_99_036:[ This function fills the buffer pointed to by parameter destination with the name of the root node of the tree designated by parameter treeHandle.]*/
        else if (STRING_concat(destination, node->name)!=0)
        {
            /*Codes_SRS_MULTITREE_99_040:[ The function returns MULTITREE_ERROR to indicate any other error.]*/
            result = MULTITREE_ERROR;
            LogError("(result = %s)", ENUM_TO_STRING(MULTITREE_RESULT, result));
        }
        else
        {
            /*Codes_SRS_MULTITREE_99_039:[ The function returns MULTITREE_OK when destination contains the name of the root node of the tree designated by treeHandle parameter.]*/
            result = MULTITREE_OK;
        }
    }

    return result;
}
Ejemplo n.º 4
0
JSON_ENCODER_RESULT JSONEncoder_EncodeTree(MULTITREE_HANDLE treeHandle, STRING_HANDLE destination, JSON_ENCODER_TOSTRING_FUNC toStringFunc)
{
    JSON_ENCODER_RESULT result;

    size_t childCount;

    /* Codes_SRS_JSON_ENCODER_99_032:[If any of the arguments passed to JSONEncoder_EncodeTree is NULL then JSON_ENCODER_INVALID_ARG shall be returned.] */
    if ((treeHandle == NULL) ||
        (destination == NULL) ||
        (toStringFunc == NULL))
    {
        result = JSON_ENCODER_INVALID_ARG;
        LogError("(result = %s)\r\n", ENUM_TO_STRING(JSON_ENCODER_RESULT, result));
    }
    /*Codes_SRS_JSON_ENCODER_99_035:[ JSON encoder shall inquire the number of child nodes (further called childCount) of the current node (given by parameter treeHandle.]*/
    else if (MultiTree_GetChildCount(treeHandle, &childCount) != MULTITREE_OK)
    {
        result = JSON_ENCODER_MULTITREE_ERROR;
        LogError("(result = %s)\r\n", ENUM_TO_STRING(JSON_ENCODER_RESULT, result));
    }
    else
    {
        size_t i;
        /*Codes_SRS_JSON_ENCODER_99_036:[ The string "{" shall be added to the output;]*/
        if (STRING_concat(destination,  "{") != 0)
        {
            result = JSON_ENCODER_ERROR;
            LogError("(result = %s)\r\n", ENUM_TO_STRING(JSON_ENCODER_RESULT, result));
        }
        else
        {
            result = JSON_ENCODER_OK;
            for (i = 0; (i < childCount) && (result == JSON_ENCODER_OK); i++)
            {
                MULTITREE_HANDLE childTreeHandle;

                if ((i > 0) &&
                    (STRING_concat(destination, ", ") != 0))
                {
                    result = JSON_ENCODER_ERROR;
                    LogError("(result = %s)\r\n", ENUM_TO_STRING(JSON_ENCODER_RESULT, result));
                }
                else if (STRING_concat(destination, "\"") != 0)
                {
                    result = JSON_ENCODER_ERROR;
                    LogError("(result = %s)\r\n", ENUM_TO_STRING(JSON_ENCODER_RESULT, result));
                }
                else
                {
                    STRING_HANDLE name = STRING_new();
                    if (name == NULL)
                    {
                        result = JSON_ENCODER_ERROR;
                        LogError("(result = %s)\r\n", ENUM_TO_STRING(JSON_ENCODER_RESULT, result));
                    }
                    else
                    {
                        if (MultiTree_GetChild(treeHandle, i, &childTreeHandle) != MULTITREE_OK)
                        {
                            result = JSON_ENCODER_MULTITREE_ERROR;
                            LogError("(result = %s)\r\n", ENUM_TO_STRING(JSON_ENCODER_RESULT, result));
                        }
                        else if (MultiTree_GetName(childTreeHandle, name) != MULTITREE_OK)
                        {
                            result = JSON_ENCODER_MULTITREE_ERROR;
                            LogError("(result = %s)\r\n", ENUM_TO_STRING(JSON_ENCODER_RESULT, result));
                        }
                        else if (STRING_concat_with_STRING(destination, name) != 0)
                        {
                            result = JSON_ENCODER_ERROR;
                            LogError("(result = %s)\r\n", ENUM_TO_STRING(JSON_ENCODER_RESULT, result));
                        }
                        else if (STRING_concat(destination, "\":") != 0)
                        {
                            result = JSON_ENCODER_ERROR;
                            LogError("(result = %s)\r\n", ENUM_TO_STRING(JSON_ENCODER_RESULT, result));
                        }
                        else
                        {
                            size_t innerChildCount;
                            if (MultiTree_GetChildCount(childTreeHandle, &innerChildCount) != MULTITREE_OK)
                            {
                                result = JSON_ENCODER_MULTITREE_ERROR;
                                LogError("(result = %s)\r\n", ENUM_TO_STRING(JSON_ENCODER_RESULT, result));
                            }
                            else
                            {
                                if (innerChildCount > 0)
                                {
                                    STRING_HANDLE child = STRING_new();
                                    if (child == NULL)
                                    {
                                        result = JSON_ENCODER_ERROR;
                                        LogError("(result = %s)\r\n", ENUM_TO_STRING(JSON_ENCODER_RESULT, result));
                                    }
                                    else
                                    {
                                        if ((result = JSONEncoder_EncodeTree(childTreeHandle, child, toStringFunc)) != JSON_ENCODER_OK)
                                        {
                                            LogError("(result = %s)\r\n", ENUM_TO_STRING(JSON_ENCODER_RESULT, result));
                                        }
                                        else if (STRING_concat_with_STRING(destination, child)!=0)
                                        {
                                            result = JSON_ENCODER_ERROR;
                                            LogError("(result = %s)\r\n", ENUM_TO_STRING(JSON_ENCODER_RESULT, result));
                                        }
                                        STRING_delete(child);
                                    }
                                }
                                else
                                {
                                    const void* value;
                                    if (MultiTree_GetValue(childTreeHandle, &value) != MULTITREE_OK)
                                    {
                                        result = JSON_ENCODER_MULTITREE_ERROR;
                                        LogError("(result = %s)\r\n", ENUM_TO_STRING(JSON_ENCODER_RESULT, result));

                                    }
                                    else
                                    {
                                        STRING_HANDLE childValue = STRING_new();
                                        if (childValue == NULL)
                                        {
                                            result = JSON_ENCODER_ERROR;
                                            LogError("(result = %s)\r\n", ENUM_TO_STRING(JSON_ENCODER_RESULT, result));
                                        }
                                        else
                                        {
                                            if (toStringFunc(childValue, value) != JSON_ENCODER_TOSTRING_OK)
                                            {
                                                result = JSON_ENCODER_TOSTRING_FUNCTION_ERROR;
                                                LogError("(result = %s)\r\n", ENUM_TO_STRING(JSON_ENCODER_RESULT, result));
                                            }
                                            else if (STRING_concat_with_STRING(destination, childValue)!=0)
                                            {
                                                result = JSON_ENCODER_ERROR;
                                                LogError("(result = %s)\r\n", ENUM_TO_STRING(JSON_ENCODER_RESULT, result));
                                            }
                                            else
                                            {
                                                /*do nothing, result = JSON_ENCODER_OK is set above at the beginning of the FOR loop*/
                                            }
                                            STRING_delete(childValue);
                                        }
                                    }
                                }
                            }
                        }
                        STRING_delete(name);
                    }
                }
            }

            if ((i == childCount) && (result == JSON_ENCODER_OK))
            {
                if (STRING_concat(destination,  "}") != 0)
                {
                    result = JSON_ENCODER_ERROR;
                    LogError("(result = %s)\r\n", ENUM_TO_STRING(JSON_ENCODER_RESULT, result));
                }
                else
                {
                    /* Codes_SRS_JSON_ENCODER_99_031:[On success, JSONEncoder_EncodeTree shall return JSON_ENCODER_OK.] */
                    result = JSON_ENCODER_OK;
                }
            }
        }
    }

    return result;
#ifdef _MSC_VER
#pragma warning(disable: 4701) /* potentially uninitialized local variable 'result' used */ /* the scanner cannot track variable "i" and link it to childCount*/
#endif
}
Ejemplo n.º 5
0
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;
}
Ejemplo n.º 6
0
BLOB_RESULT Blob_UploadBlock(
        HTTPAPIEX_HANDLE httpApiExHandle,
        const char* relativePath,
        BUFFER_HANDLE requestContent,
        unsigned int blockID,
        STRING_HANDLE blockIDList,
        unsigned int* httpStatus,
        BUFFER_HANDLE httpResponse)
{
    BLOB_RESULT result;

    if (requestContent == NULL ||
        blockIDList == NULL ||
        relativePath == NULL ||
        httpApiExHandle == NULL ||
        httpStatus == NULL ||
        httpResponse == NULL)
    {
        LogError("invalid argument detected requestContent=%p blockIDList=%p relativePath=%p httpApiExHandle=%p httpStatus=%p httpResponse=%p", requestContent, blockIDList, relativePath, httpApiExHandle, httpStatus, httpResponse);
        result = BLOB_ERROR;
    }
    else
    {
        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_UploadMultipleBlocksFromSasUri shall fail and return BLOB_ERROR ]*/
            LogError("failed to sprintf");
            result = BLOB_ERROR;
        }
        else
        {
            STRING_HANDLE blockIdString = Azure_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_UploadMultipleBlocksFromSasUri shall fail and return BLOB_ERROR ]*/
                LogError("unable to Azure_Base64_Encode_Bytes");
                result = BLOB_ERROR;
            }
            else
            {
                /*add the blockId base64 encoded to the XML*/
                if (!(
                    (STRING_concat(blockIDList, "<Latest>") == 0) &&
                    (STRING_concat_with_STRING(blockIDList, blockIdString) == 0) &&
                    (STRING_concat(blockIDList, "</Latest>") == 0)
                    ))
                {
                    /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_ERROR ]*/
                    LogError("unable to STRING_concat");
                    result = BLOB_ERROR;
                }
                else
                {
                    /*Codes_SRS_BLOB_02_022: [ Blob_UploadMultipleBlocksFromSasUri 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_UploadMultipleBlocksFromSasUri shall fail and return BLOB_ERROR ]*/
                        LogError("unable to STRING_construct");
                        result = BLOB_ERROR;
                    }
                    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_UploadMultipleBlocksFromSasUri shall fail and return BLOB_ERROR ]*/
                            LogError("unable to STRING concatenate");
                            result = BLOB_ERROR;
                        }
                        else
                        {
                            /*Codes_SRS_BLOB_02_024: [ Blob_UploadMultipleBlocksFromSasUri 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_UploadMultipleBlocksFromSasUri shall fail and return BLOB_HTTP_ERROR. ]*/
                                LogError("unable to HTTPAPIEX_ExecuteRequest");
                                result = BLOB_HTTP_ERROR;
                            }
                            else if (*httpStatus >= 300)
                            {
                                /*Codes_SRS_BLOB_02_026: [ Otherwise, if HTTP response code is >=300 then Blob_UploadMultipleBlocksFromSasUri shall succeed and return BLOB_OK. ]*/
                                LogError("HTTP status from storage does not indicate success (%d)", (int)*httpStatus);
                                result = BLOB_OK;
                            }
                            else
                            {
                                /*Codes_SRS_BLOB_02_027: [ Otherwise Blob_UploadMultipleBlocksFromSasUri shall continue execution. ]*/
                                result = BLOB_OK;
                            }
                        }
                        STRING_delete(newRelativePath);
                    }
                }
                STRING_delete(blockIdString);
            }
        }
    }
    return result;
}
Ejemplo n.º 7
0
BLOB_RESULT Blob_UploadMultipleBlocksFromSasUri(const char* SASURI, IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_CALLBACK_EX getDataCallbackEx, void* context, unsigned int* httpStatus, BUFFER_HANDLE httpResponse, const char* certificates, HTTP_PROXY_OPTIONS *proxyOptions)
{
    BLOB_RESULT result;
    /*Codes_SRS_BLOB_02_001: [ If SASURI is NULL then Blob_UploadMultipleBlocksFromSasUri 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 getDataCallbackEx is NULL then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_INVALID_ARG. ]*/
        if (getDataCallbackEx == NULL)
        {
            LogError("IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_CALLBACK_EX getDataCallbackEx is NULL");
            result = BLOB_INVALID_ARG;
        }
        /*the below define avoid a "condition always false" on some compilers*/
        else
        {
            /*Codes_SRS_BLOB_02_017: [ Blob_UploadMultipleBlocksFromSasUri 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_UploadMultipleBlocksFromSasUri 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_UploadMultipleBlocksFromSasUri 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_UploadMultipleBlocksFromSasUri shall fail and return BLOB_ERROR ]*/
                        LogError("oom - out of memory");
                        result = BLOB_ERROR;
                    }
                    else
                    {
                        HTTPAPIEX_HANDLE httpApiExHandle;
                        (void)memcpy(hostname, hostnameBegin, hostnameSize);
                        hostname[hostnameSize] = '\0';

                        /*Codes_SRS_BLOB_02_018: [ Blob_UploadMultipleBlocksFromSasUri 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_UploadMultipleBlocksFromSasUri shall fail and return BLOB_ERROR. ]*/
                            LogError("unable to create a HTTPAPIEX_HANDLE");
                            result = BLOB_ERROR;
                        }
                        else
                        {
                            if ((certificates != NULL)&& (HTTPAPIEX_SetOption(httpApiExHandle, "TrustedCerts", certificates) == HTTPAPIEX_ERROR))
                            {
                                LogError("failure in setting trusted certificates");
                                result = BLOB_ERROR;
                            }
                            else if ((proxyOptions != NULL && proxyOptions->host_address != NULL) && HTTPAPIEX_SetOption(httpApiExHandle, OPTION_HTTP_PROXY, proxyOptions) == HTTPAPIEX_ERROR)
                            {
                                LogError("failure in setting proxy options");
                                result = BLOB_ERROR;
                            }
                            else
                            {
                                /*Codes_SRS_BLOB_02_019: [ Blob_UploadMultipleBlocksFromSasUri 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*/

                                /*Codes_SRS_BLOB_02_028: [ Blob_UploadMultipleBlocksFromSasUri shall construct an XML string with the following content: ]*/
                                STRING_HANDLE blockIDList = STRING_construct("<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<BlockList>"); /*the XML "build as we go"*/
                                if (blockIDList == NULL)
                                {
                                    /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_ERROR ]*/
                                    LogError("failed to STRING_construct");
                                    result = BLOB_HTTP_ERROR;
                                }
                                else
                                {
                                    /*Codes_SRS_BLOB_02_021: [ For every block returned by `getDataCallbackEx` the following operations shall happen: ]*/
                                    unsigned int blockID = 0; /* incremented for each new block */
                                    unsigned int isError = 0; /* set to 1 if a block upload fails or if getDataCallbackEx returns incorrect blocks to upload */
                                    unsigned int uploadOneMoreBlock = 1; /* set to 1 while getDataCallbackEx returns correct blocks to upload */
                                    unsigned char const * source; /* data set by getDataCallbackEx */
                                    size_t size; /* source size set by getDataCallbackEx */
                                    IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_RESULT getDataReturnValue;

                                    do
                                    {
                                        getDataReturnValue = getDataCallbackEx(FILE_UPLOAD_OK, &source, &size, context);
                                        if (getDataReturnValue == IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_ABORT)
                                        {
                                            /*Codes_SRS_BLOB_99_004: [ If `getDataCallbackEx` returns `IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_RESULT_ABORT`, then `Blob_UploadMultipleBlocksFromSasUri` shall exit the loop and return `BLOB_ABORTED`. ]*/
                                            LogInfo("Upload to blob has been aborted by the user");
                                            uploadOneMoreBlock = 0;
                                            result = BLOB_ABORTED;
                                        }
                                        else if (source == NULL || size == 0)
                                        {
                                            /*Codes_SRS_BLOB_99_002: [ If the size of the block returned by `getDataCallbackEx` is 0 or if the data is NULL, then `Blob_UploadMultipleBlocksFromSasUri` shall exit the loop. ]*/
                                            uploadOneMoreBlock = 0;
                                            result = BLOB_OK;
                                        }
                                        else
                                        {
                                            if (size > BLOCK_SIZE)
                                            {
                                                /*Codes_SRS_BLOB_99_001: [ If the size of the block returned by `getDataCallbackEx` is bigger than 4MB, then `Blob_UploadMultipleBlocksFromSasUri` shall fail and return `BLOB_INVALID_ARG`. ]*/
                                                LogError("tried to upload block of size %lu, max allowed size is %d", (unsigned long)size, BLOCK_SIZE);
                                                result = BLOB_INVALID_ARG;
                                                isError = 1;
                                            }
                                            else if (blockID >= MAX_BLOCK_COUNT)
                                            {
                                                /*Codes_SRS_BLOB_99_003: [ If `getDataCallbackEx` returns more than 50000 blocks, then `Blob_UploadMultipleBlocksFromSasUri` shall fail and return `BLOB_INVALID_ARG`. ]*/
                                                LogError("unable to upload more than %lu blocks in one blob", (unsigned long)MAX_BLOCK_COUNT);
                                                result = BLOB_INVALID_ARG;
                                                isError = 1;
                                            }
                                            else
                                            {
                                                /*Codes_SRS_BLOB_02_023: [ Blob_UploadMultipleBlocksFromSasUri shall create a BUFFER_HANDLE from source and size parameters. ]*/
                                                BUFFER_HANDLE requestContent = BUFFER_create(source, size);
                                                if (requestContent == NULL)
                                                {
                                                    /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_ERROR ]*/
                                                    LogError("unable to BUFFER_create");
                                                    result = BLOB_ERROR;
                                                    isError = 1;
                                                }
                                                else
                                                {
                                                    result = Blob_UploadBlock(
                                                            httpApiExHandle,
                                                            relativePath,
                                                            requestContent,
                                                            blockID,
                                                            blockIDList,
                                                            httpStatus,
                                                            httpResponse);

                                                    BUFFER_delete(requestContent);
                                                }

                                                /*Codes_SRS_BLOB_02_026: [ Otherwise, if HTTP response code is >=300 then Blob_UploadMultipleBlocksFromSasUri shall succeed and return BLOB_OK. ]*/
                                                if (result != BLOB_OK || *httpStatus >= 300)
                                                {
                                                    LogError("unable to Blob_UploadBlock. Returned value=%d, httpStatus=%u", result, (unsigned int)*httpStatus);
                                                    isError = 1;
                                                }
                                            }
                                            blockID++;
                                        }
                                    }
                                    while(uploadOneMoreBlock && !isError);

                                    if (isError || result != BLOB_OK)
                                    {
                                        /*do nothing, it will be reported "as is"*/
                                    }
                                    else
                                    {
                                        /*complete the XML*/
                                        if (STRING_concat(blockIDList, "</BlockList>") != 0)
                                        {
                                            /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_ERROR ]*/
                                            LogError("failed to STRING_concat");
                                            result = BLOB_ERROR;
                                        }
                                        else
                                        {
                                            /*Codes_SRS_BLOB_02_029: [Blob_UploadMultipleBlocksFromSasUri 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_UploadMultipleBlocksFromSasUri 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_UploadMultipleBlocksFromSasUri shall fail and return BLOB_ERROR ]*/
                                                    LogError("failed to STRING_concat");
                                                    result = BLOB_ERROR;
                                                }
                                                else
                                                {
                                                    /*Codes_SRS_BLOB_02_030: [ Blob_UploadMultipleBlocksFromSasUri 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(blockIDList);
                                                    BUFFER_HANDLE blockIDListAsBuffer = BUFFER_create((const unsigned char*)s, strlen(s));
                                                    if (blockIDListAsBuffer == NULL)
                                                    {
                                                        /*Codes_SRS_BLOB_02_033: [ If any previous operation that doesn't have an explicit failure description fails then Blob_UploadMultipleBlocksFromSasUri 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,
                                                            blockIDListAsBuffer,
                                                            httpStatus,
                                                            NULL,
                                                            httpResponse
                                                        ) != HTTPAPIEX_OK)
                                                        {
                                                            /*Codes_SRS_BLOB_02_031: [ If HTTPAPIEX_ExecuteRequest fails then Blob_UploadMultipleBlocksFromSasUri shall fail and return BLOB_HTTP_ERROR. ]*/
                                                            LogError("unable to HTTPAPIEX_ExecuteRequest");
                                                            result = BLOB_HTTP_ERROR;
                                                        }
                                                        else
                                                        {
                                                            /*Codes_SRS_BLOB_02_032: [ Otherwise, Blob_UploadMultipleBlocksFromSasUri shall succeed and return BLOB_OK. ]*/
                                                            result = BLOB_OK;
                                                        }
                                                        BUFFER_delete(blockIDListAsBuffer);
                                                    }
                                                }
                                                STRING_delete(newRelativePath);
                                            }
                                        }
                                    }
                                    STRING_delete(blockIDList);
                                }

                            }
                            HTTPAPIEX_Destroy(httpApiExHandle);
                        }
                        free(hostname);
                    }
                }
            }
        }
    }
    return result;
}
Ejemplo n.º 8
0
STRING_HANDLE SASToken_Create(STRING_HANDLE key, STRING_HANDLE scope, STRING_HANDLE keyName, size_t expiry)
{
    STRING_HANDLE result = NULL;
    char tokenExpirationTime[32] = { 0 };

    /*Codes_SRS_SASTOKEN_06_001: [If key is NULL then SASToken_Create shall return NULL.]*/
    /*Codes_SRS_SASTOKEN_06_003: [If scope is NULL then SASToken_Create shall return NULL.]*/
    /*Codes_SRS_SASTOKEN_06_007: [If keyName is NULL then SASToken_Create shall return NULL.]*/
    if ((key == NULL) ||
        (scope == NULL) ||
        (keyName == NULL))
    {
        LogError("Invalid Parameter to SASToken_Create. handle key: %p, handle scope: %p, handle keyName: %p\r\n", key, scope, keyName);
    }
    else
    {
        BUFFER_HANDLE decodedKey;
        /*Codes_SRS_SASTOKEN_06_029: [The key parameter is decoded from base64.]*/
        if ((decodedKey = Base64_Decoder(STRING_c_str(key))) == NULL)
        {
            /*Codes_SRS_SASTOKEN_06_030: [If there is an error in the decoding then SASToken_Create shall return NULL.]*/
            LogError("Unable to decode the key for generating the SAS.\r\n");
        }
        else
        {
            /*Codes_SRS_SASTOKEN_06_026: [If the conversion to string form fails for any reason then SASToken_Create shall return NULL.]*/
            if (size_tToString(tokenExpirationTime, sizeof(tokenExpirationTime), expiry) != 0)
            {
                LogError("For some reason converting seconds to a string failed.  No SAS can be generated.\r\n");
            }
            else
            {
                STRING_HANDLE toBeHashed = NULL;
                BUFFER_HANDLE hash = NULL;
                if (((hash = BUFFER_new()) == NULL) ||
                    ((toBeHashed = STRING_new()) == NULL) ||
                    ((result = STRING_new()) == NULL))
                {
                    LogError("Unable to allocate memory to prepare SAS token.\r\n")
                }
                else
                {
                    /*Codes_SRS_SASTOKEN_06_009: [The scope is the basis for creating a STRING_HANDLE.]*/
                    /*Codes_SRS_SASTOKEN_06_010: [A "\n" is appended to that string.]*/
                    /*Codes_SRS_SASTOKEN_06_011: [tokenExpirationTime is appended to that string.]*/
                    if ((STRING_concat_with_STRING(toBeHashed, scope) != 0) ||
                        (STRING_concat(toBeHashed, "\n") != 0) ||
                        (STRING_concat(toBeHashed, tokenExpirationTime) != 0))
                    {
                        LogError("Unable to build the input to the HMAC to prepare SAS token.\r\n");
                        STRING_delete(result);
                        result = NULL;
                    }
                    else
                    {
                        STRING_HANDLE base64Signature = NULL;
                        STRING_HANDLE urlEncodedSignature = NULL;
                        /*Codes_SRS_SASTOKEN_06_013: [If an error is returned from the HMAC256 function then NULL is returned from SASToken_Create.]*/
                        /*Codes_SRS_SASTOKEN_06_012: [An HMAC256 hash is calculated using the decodedKey, over toBeHashed.]*/
                        /*Codes_SRS_SASTOKEN_06_014: [If there are any errors from the following operations then NULL shall be returned.]*/
                        /*Codes_SRS_SASTOKEN_06_015: [The hash is base 64 encoded.]*/
                        /*Codes_SRS_SASTOKEN_06_028: [base64Signature shall be url encoded.]*/
                        /*Codes_SRS_SASTOKEN_06_016: [The string "SharedAccessSignature sr=" is the first part of the result of SASToken_Create.]*/
                        /*Codes_SRS_SASTOKEN_06_017: [The scope parameter is appended to result.]*/
                        /*Codes_SRS_SASTOKEN_06_018: [The string "&sig=" is appended to result.]*/
                        /*Codes_SRS_SASTOKEN_06_019: [The string urlEncodedSignature shall be appended to result.]*/
                        /*Codes_SRS_SASTOKEN_06_020: [The string "&se=" shall be appended to result.]*/
                        /*Codes_SRS_SASTOKEN_06_021: [tokenExpirationTime is appended to result.]*/
                        /*Codes_SRS_SASTOKEN_06_022: [The string "&skn=" is appended to result.]*/
                        /*Codes_SRS_SASTOKEN_06_023: [The argument keyName is appended to result.]*/
                        if ((HMACSHA256_ComputeHash(BUFFER_u_char(decodedKey), BUFFER_length(decodedKey), (const unsigned char*)STRING_c_str(toBeHashed), STRING_length(toBeHashed), hash) != HMACSHA256_OK) ||
                            ((base64Signature = Base64_Encode(hash)) == NULL) ||
                            ((urlEncodedSignature = URL_Encode(base64Signature)) == NULL) ||
                            (STRING_copy(result, "SharedAccessSignature sr=") != 0) ||
                            (STRING_concat_with_STRING(result, scope) != 0) ||
                            (STRING_concat(result, "&sig=") != 0) ||
                            (STRING_concat_with_STRING(result, urlEncodedSignature) != 0) ||
                            (STRING_concat(result, "&se=") != 0) ||
                            (STRING_concat(result, tokenExpirationTime) != 0) ||
                            (STRING_concat(result, "&skn=") != 0) ||
                            (STRING_concat_with_STRING(result, keyName) != 0))
                        {
                            LogError("Unable to build the SAS token.\r\n");
                            STRING_delete(result);
                            result = NULL;
                        }
                        else
                        {
                            /* everything OK */
                        }
                        STRING_delete(base64Signature);
                        STRING_delete(urlEncodedSignature);
                    }
                }
                STRING_delete(toBeHashed);
                BUFFER_delete(hash);
            }
            BUFFER_delete(decodedKey);
        }
    }

    return result;
}