in source/sigv4.c [1610:1703]
static SigV4Status_t parseHeaderKeyValueEntries( const char * pHeaders,
size_t headersDataLen,
uint32_t flags,
size_t * headerCount,
CanonicalContext_t * pCanonicalRequest )
{
size_t index = 0, noOfHeaders;
const char * pKeyOrValStartLoc;
const char * pCurrLoc;
bool keyFlag = true;
SigV4Status_t sigV4Status = SigV4Success;
ptrdiff_t dataLen = 0;
assert( pHeaders != NULL );
assert( headersDataLen > 0 );
assert( pCanonicalRequest != NULL );
assert( headerCount != NULL );
noOfHeaders = *headerCount;
pKeyOrValStartLoc = pHeaders;
pCurrLoc = pHeaders;
for( index = 0; index < headersDataLen; index++ )
{
if( noOfHeaders == SIGV4_MAX_HTTP_HEADER_COUNT )
{
sigV4Status = SigV4MaxHeaderPairCountExceeded;
break;
}
/* Look for key part of an header field entry. */
else if( ( keyFlag ) && ( pHeaders[ index ] == ':' ) )
{
dataLen = pCurrLoc - pKeyOrValStartLoc;
pCanonicalRequest->pHeadersLoc[ noOfHeaders ].key.pData = pKeyOrValStartLoc;
pCanonicalRequest->pHeadersLoc[ noOfHeaders ].key.dataLen = ( size_t ) dataLen;
pKeyOrValStartLoc = &( pCurrLoc[ 1 ] );
keyFlag = false;
}
/* Look for header value part of a header field entry for both canonicalized and non-canonicalized forms. */
/* Non-canonicalized headers will have header values ending with "\r\n". */
else if( ( !keyFlag ) && !FLAG_IS_SET( flags, SIGV4_HTTP_HEADERS_ARE_CANONICAL_FLAG ) && ( ( index + 1U ) < headersDataLen ) &&
( 0 == strncmp( pCurrLoc, HTTP_REQUEST_LINE_ENDING, HTTP_REQUEST_LINE_ENDING_LEN ) ) )
{
dataLen = pCurrLoc - pKeyOrValStartLoc;
pCanonicalRequest->pHeadersLoc[ noOfHeaders ].value.pData = pKeyOrValStartLoc;
pCanonicalRequest->pHeadersLoc[ noOfHeaders ].value.dataLen = ( size_t ) dataLen;
/* Storing location of hashed request payload */
storeHashedPayloadLocation( noOfHeaders, SIGV4_HTTP_X_AMZ_CONTENT_SHA256_HEADER, SIGV4_HTTP_X_AMZ_CONTENT_SHA256_HEADER_LENGTH, pCanonicalRequest );
/* Set starting location of the next header key string after the "\r\n". */
pKeyOrValStartLoc = &( pCurrLoc[ 2 ] );
keyFlag = true;
noOfHeaders++;
}
/* Canonicalized headers will have header values ending just with "\n". */
else if( ( !keyFlag ) && FLAG_IS_SET( flags, SIGV4_HTTP_HEADERS_ARE_CANONICAL_FLAG ) && ( pHeaders[ index ] == '\n' ) )
{
dataLen = pCurrLoc - pKeyOrValStartLoc;
pCanonicalRequest->pHeadersLoc[ noOfHeaders ].value.pData = pKeyOrValStartLoc;
pCanonicalRequest->pHeadersLoc[ noOfHeaders ].value.dataLen = ( size_t ) dataLen;
/* Storing location of hashed request payload */
storeHashedPayloadLocation( noOfHeaders, SIGV4_HTTP_X_AMZ_CONTENT_SHA256_HEADER, SIGV4_HTTP_X_AMZ_CONTENT_SHA256_HEADER_LENGTH, pCanonicalRequest );
/* Set starting location of the next header key string after the "\n". */
pKeyOrValStartLoc = &( pCurrLoc[ 1 ] );
keyFlag = true;
noOfHeaders++;
}
else
{
/* Empty else. */
}
pCurrLoc++;
}
/* Ensure each key has its corresponding value. */
assert( keyFlag == true );
/* If no header was found OR header value was not found for a header key,
* that represents incorrect HTTP headers data passed by the application. */
if( ( noOfHeaders == 0U ) || ( keyFlag == false ) )
{
sigV4Status = SigV4InvalidHttpHeaders;
}
else
{
*headerCount = noOfHeaders;
}
return sigV4Status;
}