in source/core_http_client.c [2384:2496]
static HTTPStatus_t findHeaderInResponse( const uint8_t * pBuffer,
size_t bufferLen,
const char * pField,
size_t fieldLen,
const char ** pValueLoc,
size_t * pValueLen )
{
HTTPStatus_t returnStatus = HTTPSuccess;
http_parser parser = { 0 };
http_parser_settings parserSettings = { 0 };
findHeaderContext_t context = { 0 };
size_t numOfBytesParsed = 0U;
context.pField = pField;
context.fieldLen = fieldLen;
context.pValueLoc = pValueLoc;
context.pValueLen = pValueLen;
context.fieldFound = 0U;
context.valueFound = 0U;
/* Disable unused variable warning. This variable is used only in logging. */
( void ) numOfBytesParsed;
http_parser_init( &parser, HTTP_RESPONSE );
/* Set the context for the parser. */
parser.data = &context;
/* The intention here to define callbacks just for searching the headers. We will
* need to create a private context in httpParser->data that has the field and
* value to update and pass back. */
http_parser_settings_init( &parserSettings );
parserSettings.on_header_field = findHeaderFieldParserCallback;
parserSettings.on_header_value = findHeaderValueParserCallback;
parserSettings.on_headers_complete = findHeaderOnHeaderCompleteCallback;
/* Start parsing for the header! */
numOfBytesParsed = http_parser_execute( &parser,
&parserSettings,
( const char * ) pBuffer,
bufferLen );
LogDebug( ( "Parsed response for header search: NumBytesParsed=%lu",
( unsigned long ) numOfBytesParsed ) );
if( context.fieldFound == 0U )
{
/* If header field is not found, then both the flags should be zero. */
assert( context.valueFound == 0U );
/* Header is not present in buffer. */
LogWarn( ( "Header not found in response buffer: RequestedHeader=%.*s",
( int ) fieldLen,
pField ) );
returnStatus = HTTPHeaderNotFound;
}
else if( context.valueFound == 0U )
{
/* The response buffer is invalid as only the header field was found
* in the "<field>: <value>\r\n" format of an HTTP header. */
LogError( ( "Unable to find header value in response: "
"Response data is invalid: "
"RequestedHeader=%.*s, ParserError=%s",
( int ) fieldLen,
pField,
http_errno_description( HTTP_PARSER_ERRNO( &( parser ) ) ) ) );
returnStatus = HTTPInvalidResponse;
}
else
{
/* Header is found. */
assert( ( context.fieldFound == 1U ) && ( context.valueFound == 1U ) );
LogDebug( ( "Found requested header in response: "
"HeaderName=%.*s, HeaderValue=%.*s",
( int ) fieldLen,
pField,
( int ) ( *pValueLen ),
*pValueLoc ) );
returnStatus = HTTPSuccess;
}
/* If the header field-value pair is found in response, then the return
* value of "on_header_value" callback (related to the header value) should
* cause the http_parser.http_errno to be "CB_header_value". */
if( ( returnStatus == HTTPSuccess ) &&
( parser.http_errno != ( unsigned int ) HPE_CB_header_value ) )
{
LogError( ( "Header found in response but http-parser returned error: "
"ParserError=%s",
http_errno_description( HTTP_PARSER_ERRNO( &( parser ) ) ) ) );
returnStatus = HTTPParserInternalError;
}
/* If header was not found, then the "on_header_complete" callback is
* expected to be called which should cause the http_parser.http_errno to be
* "OK" */
else if( ( returnStatus == HTTPHeaderNotFound ) &&
( parser.http_errno != ( unsigned int ) ( HPE_OK ) ) )
{
LogError( ( "Header not found in response: http-parser returned error: "
"ParserError=%s",
http_errno_description( HTTP_PARSER_ERRNO( &( parser ) ) ) ) );
returnStatus = HTTPInvalidResponse;
}
else
{
/* Empty else for MISRA 15.7 compliance. */
}
return returnStatus;
}