static SigV4Status_t writeCanonicalQueryParameters()

in source/sigv4.c [1999:2073]


    static SigV4Status_t writeCanonicalQueryParameters( CanonicalContext_t * pCanonicalRequest,
                                                        size_t numberOfParameters,
                                                        const bool doubleEncodeEqualsInParmsValues )
    {
        SigV4Status_t returnStatus = SigV4Success;
        size_t uxBufIndex;
        size_t encodedLen = 0U, remainingLen = 0U, paramsIndex = 0U;

        assert( pCanonicalRequest != NULL );
        assert( pCanonicalRequest->pQueryLoc != NULL );

        uxBufIndex = pCanonicalRequest->uxCursorIndex;
        remainingLen = pCanonicalRequest->bufRemaining;

        for( paramsIndex = 0U; paramsIndex < numberOfParameters; paramsIndex++ )
        {
            assert( pCanonicalRequest->pQueryLoc[ paramsIndex ].key.pData != NULL );
            assert( pCanonicalRequest->pQueryLoc[ paramsIndex ].key.dataLen > 0U );

            encodedLen = remainingLen;
            returnStatus = SigV4_EncodeURI( pCanonicalRequest->pQueryLoc[ paramsIndex ].key.pData,
                                            pCanonicalRequest->pQueryLoc[ paramsIndex ].key.dataLen,
                                            ( char * ) &( pCanonicalRequest->pBufProcessing[ uxBufIndex ] ),
                                            &encodedLen,
                                            true /* Encode slash (/) */,
                                            false /* Do not double encode '='. */ );

            if( returnStatus == SigV4Success )
            {
                uxBufIndex = uxBufIndex + encodedLen;
                remainingLen -= encodedLen;

                assert( pCanonicalRequest->pQueryLoc[ paramsIndex ].value.pData != NULL );
                returnStatus = writeValueInCanonicalizedQueryString( ( char * ) &( pCanonicalRequest->pBufProcessing[ uxBufIndex ] ),
                                                                     remainingLen,
                                                                     pCanonicalRequest->pQueryLoc[ paramsIndex ].value.pData,
                                                                     pCanonicalRequest->pQueryLoc[ paramsIndex ].value.dataLen,
                                                                     &encodedLen,
                                                                     doubleEncodeEqualsInParmsValues );
                uxBufIndex = uxBufIndex + encodedLen;
                remainingLen -= encodedLen;
            }

            /* If there is a succeeding query parameter, add the '&' separator in the canonical query. */
            if( ( returnStatus == SigV4Success ) && ( ( paramsIndex + 1U ) != numberOfParameters ) )
            {
                /* Before adding the '&' for the next query parameter, check that there is
                 * space in the buffer. */
                if( remainingLen > 0U )
                {
                    ( ( char * ) ( pCanonicalRequest->pBufProcessing ) )[ uxBufIndex ] = '&';
                    uxBufIndex++;
                    remainingLen--;
                }

                /* There is at least another query parameter entry to encode
                 * but no space in the buffer. */
                else
                {
                    returnStatus = SigV4InsufficientMemory;
                    LOG_INSUFFICIENT_MEMORY_ERROR( "write query parameter separator, '&'", 1U );
                    break;
                }
            }
        }

        /* Update the context state if canonical query generation was successful. */
        if( returnStatus == SigV4Success )
        {
            pCanonicalRequest->uxCursorIndex = uxBufIndex;
            pCanonicalRequest->bufRemaining = remainingLen;
        }

        return returnStatus;
    }