From 0e67b12011e846d9b941429cd8366dad744e3cdc Mon Sep 17 00:00:00 2001 From: Tony Josi Date: Tue, 18 Jul 2023 15:04:26 +0530 Subject: [PATCH] Handle upgrade header (#159) * handle upgrade header, update unit tests * update review comments * fix review comments --- source/core_http_client.c | 11 ++++++-- test/unit-test/core_http_send_utest.c | 39 +++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/source/core_http_client.c b/source/core_http_client.c index 63836b53..666e1f43 100644 --- a/source/core_http_client.c +++ b/source/core_http_client.c @@ -1050,6 +1050,7 @@ static HTTPStatus_t processLlhttpError( const llhttp_t * pHttpParser ) switch( llhttp_get_errno( pHttpParser ) ) { case HPE_OK: + case HPE_PAUSED_UPGRADE: /* There were no errors. */ break; @@ -1158,6 +1159,7 @@ static HTTPStatus_t parseHttpResponse( HTTPParsingContext_t * pParsingContext, { HTTPStatus_t returnStatus; const char * parsingStartLoc = NULL; + llhttp_errno_t eReturn; assert( pParsingContext != NULL ); assert( pResponse != NULL ); @@ -1202,8 +1204,13 @@ static HTTPStatus_t parseHttpResponse( HTTPParsingContext_t * pParsingContext, /* This will begin the parsing. Each of the callbacks set in * parserSettings will be invoked as parts of the HTTP response are - * reached. The return code is parsed in #processLlhttpError so is not needed. */ - ( void ) llhttp_execute( &( pParsingContext->llhttpParser ), parsingStartLoc, parseLen ); + * reached. The return code is parsed in #processLlhttpError. */ + eReturn = llhttp_execute( &( pParsingContext->llhttpParser ), parsingStartLoc, parseLen ); + + if( eReturn == HPE_PAUSED_UPGRADE ) + { + llhttp_resume_after_upgrade( &( pParsingContext->llhttpParser ) ); + } /* The next location to parse will always be after what has already * been parsed. */ diff --git a/test/unit-test/core_http_send_utest.c b/test/unit-test/core_http_send_utest.c index 4e5174f6..28197e9c 100644 --- a/test/unit-test/core_http_send_utest.c +++ b/test/unit-test/core_http_send_utest.c @@ -561,6 +561,25 @@ static llhttp_errno_t llhttp_execute_whole_response( llhttp_t * pParser, return HPE_OK; } +/* Mocked llhttp_execute callback that expects upgrade header in HTTP response. */ +static llhttp_errno_t llhttp_execute_paused_upgrade( llhttp_t * pParser, + const char * pData, + size_t len, + int cmock_num_calls ) +{ + ( void ) cmock_num_calls; + llhttp_errno_t eReturn = HPE_OK; + + if( httpParserExecuteCallCount == 0 ) + { + eReturn = HPE_PAUSED_UPGRADE; + } + + llhttp_execute_whole_response( pParser, pData, len, 0 ); + + return eReturn; +} + /* Mocked llhttp_execute callback that will be called the first time on the * response message up to the middle of the first header field, then the second * time on the response message from the middle of the first header field to the @@ -1374,6 +1393,26 @@ void test_HTTPClient_Send_less_bytes_request_body( void ) /*-----------------------------------------------------------*/ +/* Test upgrade header in HTTP response. */ +void test_HTTPClient_Send_paused_upgrade( void ) +{ + HTTPStatus_t returnStatus = HTTPSuccess; + + llhttp_execute_Stub( llhttp_execute_paused_upgrade ); + llhttp_resume_after_upgrade_ExpectAnyArgs(); + + returnStatus = HTTPClient_Send( &transportInterface, + &requestHeaders, + NULL, + 0, + &response, + 0 ); + + TEST_ASSERT_EQUAL( HTTPSuccess, returnStatus ); +} + +/*-----------------------------------------------------------*/ + /* Test when a network error is returned when receiving the response. */ void test_HTTPClient_Send_network_error_response( void ) {