static HTTPStatus_t addHeader()

in source/core_http_client.c [1325:1416]


static HTTPStatus_t addHeader( HTTPRequestHeaders_t * pRequestHeaders,
                               const char * pField,
                               size_t fieldLen,
                               const char * pValue,
                               size_t valueLen )
{
    HTTPStatus_t returnStatus = HTTPSuccess;
    char * pBufferCur = NULL;
    size_t toAddLen = 0U;
    size_t backtrackHeaderLen = 0U;

    assert( pRequestHeaders != NULL );
    assert( pRequestHeaders->pBuffer != NULL );
    assert( pField != NULL );
    assert( pValue != NULL );
    assert( fieldLen != 0U );
    assert( valueLen != 0U );

    pBufferCur = ( char * ) ( pRequestHeaders->pBuffer + pRequestHeaders->headersLen );
    backtrackHeaderLen = pRequestHeaders->headersLen;

    /* Backtrack before trailing "\r\n" (HTTP header end) if it's already written.
     * Note that this method also writes trailing "\r\n" before returning.
     * The first condition prevents reading before start of the header. */
    if( ( HTTP_HEADER_END_INDICATOR_LEN <= pRequestHeaders->headersLen ) &&
        ( strncmp( ( char * ) pBufferCur - HTTP_HEADER_END_INDICATOR_LEN,
                   HTTP_HEADER_END_INDICATOR, HTTP_HEADER_END_INDICATOR_LEN ) == 0 ) )
    {
        backtrackHeaderLen -= HTTP_HEADER_LINE_SEPARATOR_LEN;
        pBufferCur -= HTTP_HEADER_LINE_SEPARATOR_LEN;
    }

    /* Check if there is enough space in buffer for additional header. */
    toAddLen = fieldLen + HTTP_HEADER_FIELD_SEPARATOR_LEN + valueLen +
               HTTP_HEADER_LINE_SEPARATOR_LEN +
               HTTP_HEADER_LINE_SEPARATOR_LEN;

    /* If we have enough room for the new header line, then write it to the
     * header buffer. */
    if( ( backtrackHeaderLen + toAddLen ) <= pRequestHeaders->bufferLen )
    {
        /* Write "<Field>: <Value> \r\n" to the headers buffer. */

        /* Copy the header name into the buffer. */
        if( httpHeaderStrncpy( pBufferCur, pField, fieldLen, HTTP_HEADER_STRNCPY_IS_FIELD ) == NULL )
        {
            returnStatus = HTTPSecurityAlertInvalidCharacter;
        }

        if( returnStatus == HTTPSuccess )
        {
            pBufferCur += fieldLen;

            /* Copy the field separator, ": ", into the buffer. */
            ( void ) strncpy( pBufferCur,
                              HTTP_HEADER_FIELD_SEPARATOR,
                              HTTP_HEADER_FIELD_SEPARATOR_LEN );

            pBufferCur += HTTP_HEADER_FIELD_SEPARATOR_LEN;

            /* Copy the header value into the buffer. */
            if( httpHeaderStrncpy( pBufferCur, pValue, valueLen, HTTP_HEADER_STRNCPY_IS_VALUE ) == NULL )
            {
                returnStatus = HTTPSecurityAlertInvalidCharacter;
            }
        }

        if( returnStatus == HTTPSuccess )
        {
            pBufferCur += valueLen;

            /* Copy the header end indicator, "\r\n\r\n" into the buffer. */
            ( void ) strncpy( pBufferCur,
                              HTTP_HEADER_END_INDICATOR,
                              HTTP_HEADER_END_INDICATOR_LEN );

            /* Update the headers length value only when everything is successful. */
            pRequestHeaders->headersLen = backtrackHeaderLen + toAddLen;
        }
    }
    else
    {
        LogError( ( "Unable to add header in buffer: "
                    "Buffer has insufficient memory: "
                    "RequiredBytes=%lu, RemainingBufferSize=%lu",
                    ( unsigned long ) toAddLen,
                    ( unsigned long ) ( pRequestHeaders->bufferLen - pRequestHeaders->headersLen ) ) );
        returnStatus = HTTPInsufficientMemory;
    }

    return returnStatus;
}