From 390227473e1d99ff066764524e9764c3732ea3d4 Mon Sep 17 00:00:00 2001
From: Muneeb Ahmed <54290492+muneebahmed10@users.noreply.github.com>
Date: Mon, 24 Jan 2022 21:39:40 -0700
Subject: [PATCH 1/4] Replace http-parser with llhttp (#126)
* Add llhttp submodule
* Replace http-parser with llhttp in source
* Fix CI checks
* Fix unit tests 100% coverage
* Rename functions
* Disable strict mode
* Remove http-parser submodule
---
.github/memory_statistics_config.json | 14 +-
.github/workflows/ci.yml | 2 +-
.gitmodules | 6 +-
README.md | 2 +-
docs/doxygen/include/size_table.md | 20 +-
docs/doxygen/pages.dox | 8 +-
httpFilePaths.cmake | 6 +-
lexicon.txt | 7 +-
manifest.yml | 6 +-
source/core_http_client.c | 261 ++++++++++------------
source/dependency/3rdparty/http_parser | 1 -
source/dependency/3rdparty/llhttp | 1 +
source/include/core_http_client.h | 2 +-
source/include/core_http_client_private.h | 59 +++--
test/CMakeLists.txt | 16 +-
test/http_parser_build.cmake | 19 --
test/llhttp_build.cmake | 21 ++
test/unit-test/CMakeLists.txt | 6 +-
test/unit-test/core_http_send_utest.c | 215 ++++++++++--------
test/unit-test/core_http_utest.c | 170 +++++++-------
tools/cmock/project.yml | 2 +
21 files changed, 454 insertions(+), 390 deletions(-)
delete mode 160000 source/dependency/3rdparty/http_parser
create mode 160000 source/dependency/3rdparty/llhttp
delete mode 100644 test/http_parser_build.cmake
create mode 100644 test/llhttp_build.cmake
diff --git a/.github/memory_statistics_config.json b/.github/memory_statistics_config.json
index b6ff1be2..8374f109 100644
--- a/.github/memory_statistics_config.json
+++ b/.github/memory_statistics_config.json
@@ -3,14 +3,22 @@
"src": [
"source/core_http_client.c",
{
- "file": "source/dependency/3rdparty/http_parser/http_parser.c",
- "tag": "http-parser"
+ "file": "source/dependency/3rdparty/llhttp/src/api.c",
+ "tag": "llhttp"
+ },
+ {
+ "file": "source/dependency/3rdparty/llhttp/src/http.c",
+ "tag": "llhttp"
+ },
+ {
+ "file": "source/dependency/3rdparty/llhttp/src/llhttp.c",
+ "tag": "llhttp"
}
],
"include": [
"source/include",
"source/interface",
- "source/dependency/3rdparty/http_parser"
+ "source/dependency/3rdparty/llhttp/include"
],
"compiler_flags": [
"HTTP_DO_NOT_USE_CUSTOM_CONFIG"
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 0bf97d5a..2c38010a 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -4,7 +4,7 @@ on:
push:
branches: ["**"]
pull_request:
- branches: [main]
+ branches: ["**"]
workflow_dispatch:
jobs:
diff --git a/.gitmodules b/.gitmodules
index 0eae6012..b49c2727 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -10,6 +10,6 @@
path = test/cbmc/litani
url = https://github.com/awslabs/aws-build-accumulator
update = none
-[submodule "source/dependency/3rdparty/http_parser"]
- path = source/dependency/3rdparty/http_parser
- url = https://github.com/nodejs/http-parser.git
+[submodule "source/dependency/3rdparty/llhttp"]
+ path = source/dependency/3rdparty/llhttp
+ url = https://github.com/nodejs/llhttp.git
diff --git a/README.md b/README.md
index efd78bae..c47d5f12 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
This repository contains a C language HTTP client library designed for embedded
platforms. It has no dependencies on any additional libraries other than the
-standard C library, [http-parser](https://github.com/nodejs/http-parser), and
+standard C library, [llhttp](https://github.com/nodejs/llhttp), and
a customer-implemented transport interface. This library is distributed under
the [MIT Open Source License](LICENSE).
diff --git a/docs/doxygen/include/size_table.md b/docs/doxygen/include/size_table.md
index 41bc6338..fed45453 100644
--- a/docs/doxygen/include/size_table.md
+++ b/docs/doxygen/include/size_table.md
@@ -10,16 +10,26 @@
core_http_client.c |
3.2K |
+ 2.5K |
+
+
+ api.c (llhttp) |
2.6K |
+ 2.0K |
+
+
+ http.c (llhttp) |
+ 0.3K |
+ 0.3K |
- http_parser.c (http-parser) |
- 15.7K |
- 13.0K |
+ llhttp.c (llhttp) |
+ 17.9K |
+ 15.9K |
Total estimates |
- 18.9K |
- 15.6K |
+ 24.0K |
+ 20.7K |
diff --git a/docs/doxygen/pages.dox b/docs/doxygen/pages.dox
index 7c65ef21..4c225127 100644
--- a/docs/doxygen/pages.dox
+++ b/docs/doxygen/pages.dox
@@ -7,7 +7,7 @@ This HTTP Client library implements a subset of the HTTP/1.1 protocol. Features
of this library include:
- Fully synchronous API, to allow applications to completely manage their concurrency and multi-threading.
- Operations on user supplied buffers, so that applications have complete control of their memory allocation strategy.
-- Integration with [http-parser](https://github.com/nodejs/http-parser) to handle chunked encoding.
+- Integration with [llhttp](https://github.com/nodejs/llhttp) to handle chunked encoding.
Feature of HTTP/1.1 not supported in this library:
- Streaming uploads and downloads. Range requests for partial content responses are highly encouraged with this API.
@@ -110,7 +110,7 @@ If the request has a body it is passed as a parameter to @ref HTTPClient_Send.
As soon as the response is received from the network it is parsed. The final
parsed response is represented by the @ref HTTPResponse_t returned from
@ref HTTPClient_Send. Parsing the HTTP response is done using
-[http-parser](https://github.com/nodejs/http-parser). http-parser invokes
+[llhttp](https://github.com/nodejs/llhttp). llhttp invokes
callbacks for each section in the HTTP response it finds. Using these callbacks
the HTTP client library sets the members of @ref HTTPResponse_t to return from
@ref HTTPClient_Send. The overall flow of @ref HTTPClient_Send is
@@ -125,14 +125,14 @@ can be read from the headers found in @ref HTTPResponse_t.pHeaders. The function
@ref HTTPClient_ReadHeader reads the headers from an @ref HTTPResponse_t.
@ref HTTPClient_ReadHeader will re-parse the response in
@ref HTTPResponse_t.pBuffer, looking for the header field of interest.
-Re-parsing involves using http-parser to look at each character starting from
+Re-parsing involves using llhttp to look at each character starting from
the beginning of @ref HTTPResponse_t.pBuffer until the header field of interest
is found.
If the user application wants to avoid re-parsing @ref HTTPResponse_t.pBuffer,
then the user application may register a callback in
@ref HTTPResponse_t.pHeaderParsingCallback. When the HTTP response message is
-first received from the network, in @ref HTTPClient_Send, http-parser is invoked
+first received from the network, in @ref HTTPClient_Send, llhttp is invoked
to parse the response. This first parsing in @ref HTTPClient_Send will invoke
@ref HTTPResponse_t.pHeaderParsingCallback for each header that is found
in response. Please see the sequence diagram below for an illustration of when
diff --git a/httpFilePaths.cmake b/httpFilePaths.cmake
index 0ef3479a..38418f96 100644
--- a/httpFilePaths.cmake
+++ b/httpFilePaths.cmake
@@ -8,10 +8,12 @@
# HTTP library source files.
set( HTTP_SOURCES
${CMAKE_CURRENT_LIST_DIR}/source/core_http_client.c
- ${CMAKE_CURRENT_LIST_DIR}/source/dependency/3rdparty/http_parser/http_parser.c )
+ ${CMAKE_CURRENT_LIST_DIR}/source/dependency/3rdparty/llhttp/src/api.c
+ ${CMAKE_CURRENT_LIST_DIR}/source/dependency/3rdparty/llhttp/src/llhttp.c
+ ${CMAKE_CURRENT_LIST_DIR}/source/dependency/3rdparty/llhttp/src/http.c )
# HTTP library public include directories.
set( HTTP_INCLUDE_PUBLIC_DIRS
${CMAKE_CURRENT_LIST_DIR}/source/include
${CMAKE_CURRENT_LIST_DIR}/source/interface
- ${CMAKE_CURRENT_LIST_DIR}/source/dependency/3rdparty/http_parser )
+ ${CMAKE_CURRENT_LIST_DIR}/source/dependency/3rdparty/llhttp/include )
diff --git a/lexicon.txt b/lexicon.txt
index e2add5f5..89b9bbfe 100644
--- a/lexicon.txt
+++ b/lexicon.txt
@@ -25,6 +25,7 @@ chk
chunked
colspan
com
+cond
config
configpagestyle
const
@@ -42,6 +43,7 @@ defgroup
doesn
doxygen
endcode
+endcond
endif
enums
eof
@@ -122,6 +124,9 @@ lastheadervaluelen
latin
len
linux
+llhttp
+llhttpparser
+llhttpsettings
logdebug
logerror
loginfo
@@ -201,7 +206,7 @@ prequestbodybuf
prequestheaders
prequestinfo
presponse
-processhttpparsererror
+processllhttperror
ptransport
ptransportinterface
pvalue
diff --git a/manifest.yml b/manifest.yml
index 6926c99f..b4720c7a 100644
--- a/manifest.yml
+++ b/manifest.yml
@@ -3,9 +3,9 @@ version: "v2.1.0"
description: |
"Client implementation of the HTTP/1.1 specification for embedded devices.\n"
dependencies:
- - name : "http-parser"
- version: "v2.9.4"
+ - name : "llhttp"
+ version: "release/v6.0.5"
repository:
type: "git"
- url: "https://github.com/nodejs/http-parser"
+ url: "https://github.com/nodejs/llhttp"
license: "MIT"
diff --git a/source/core_http_client.c b/source/core_http_client.c
index 2dd3a228..492bd519 100644
--- a/source/core_http_client.c
+++ b/source/core_http_client.c
@@ -289,10 +289,10 @@ static HTTPStatus_t findHeaderInResponse( const uint8_t * pBuffer,
* buffer.
* @param[in] fieldLen The length of the header field.
*
- * @return Returns #HTTP_PARSER_CONTINUE_PARSING to indicate continuation with
+ * @return Returns #LLHTTP_CONTINUE_PARSING to indicate continuation with
* parsing.
*/
-static int findHeaderFieldParserCallback( http_parser * pHttpParser,
+static int findHeaderFieldParserCallback( llhttp_t * pHttpParser,
const char * pFieldLoc,
size_t fieldLen );
@@ -307,10 +307,10 @@ static int findHeaderFieldParserCallback( http_parser * pHttpParser,
* buffer.
* @param[in] valueLen The length of the header value.
*
- * @return Returns #HTTP_PARSER_STOP_PARSING, if the header field/value pair are
- * found, otherwise #HTTP_PARSER_CONTINUE_PARSING is returned.
+ * @return Returns #LLHTTP_STOP_PARSING, if the header field/value pair are
+ * found, otherwise #LLHTTP_CONTINUE_PARSING is returned.
*/
-static int findHeaderValueParserCallback( http_parser * pHttpParser,
+static int findHeaderValueParserCallback( llhttp_t * pHttpParser,
const char * pValueLoc,
size_t valueLen );
@@ -324,10 +324,10 @@ static int findHeaderValueParserCallback( http_parser * pHttpParser,
*
* @param[in] pHttpParser Parsing object containing state and callback context.
*
- * @return Returns #HTTP_PARSER_STOP_PARSING for the parser to halt further
+ * @return Returns #LLHTTP_STOP_PARSING_NO_HEADER for the parser to halt further
* execution, as all headers have been parsed in the response.
*/
-static int findHeaderOnHeaderCompleteCallback( http_parser * pHttpParser );
+static int findHeaderOnHeaderCompleteCallback( llhttp_t * pHttpParser );
/**
@@ -354,14 +354,14 @@ static void initializeParsingContextForFirstResponse( HTTPParsingContext_t * pPa
* @return One of the following:
* - #HTTPSuccess
* - #HTTPInvalidParameter
- * - Please see #processHttpParserError for parsing errors returned.
+ * - Please see #processLlhttpError for parsing errors returned.
*/
static HTTPStatus_t parseHttpResponse( HTTPParsingContext_t * pParsingContext,
HTTPResponse_t * pResponse,
size_t parseLen );
/**
- * @brief Callback invoked during http_parser_execute() to indicate the start of
+ * @brief Callback invoked during llhttp_execute() to indicate the start of
* the HTTP response message.
*
* This callback is invoked when an "H" in the "HTTP/1.1" that starts a response
@@ -369,12 +369,12 @@ static HTTPStatus_t parseHttpResponse( HTTPParsingContext_t * pParsingContext,
*
* @param[in] pHttpParser Parsing object containing state and callback context.
*
- * @return #HTTP_PARSER_CONTINUE_PARSING to continue parsing.
+ * @return #LLHTTP_CONTINUE_PARSING to continue parsing.
*/
-static int httpParserOnMessageBeginCallback( http_parser * pHttpParser );
+static int httpParserOnMessageBeginCallback( llhttp_t * pHttpParser );
/**
- * @brief Callback invoked during http_parser_execute() when the HTTP response
+ * @brief Callback invoked during llhttp_execute() when the HTTP response
* status-code and its associated reason-phrase are found.
*
* @param[in] pHttpParser Parsing object containing state and callback context.
@@ -382,14 +382,14 @@ static int httpParserOnMessageBeginCallback( http_parser * pHttpParser );
* response message buffer.
* @param[in] length Length of the HTTP response status code string.
*
- * @return #HTTP_PARSER_CONTINUE_PARSING to continue parsing.
+ * @return #LLHTTP_CONTINUE_PARSING to continue parsing.
*/
-static int httpParserOnStatusCallback( http_parser * pHttpParser,
+static int httpParserOnStatusCallback( llhttp_t * pHttpParser,
const char * pLoc,
size_t length );
/**
- * @brief Callback invoked during http_parser_execute() when an HTTP response
+ * @brief Callback invoked during llhttp_execute() when an HTTP response
* header field is found.
*
* If only part of the header field was found, then parsing of the next part of
@@ -400,14 +400,14 @@ static int httpParserOnStatusCallback( http_parser * pHttpParser,
* message buffer.
* @param[in] length Length of the header field.
*
- * @return #HTTP_PARSER_CONTINUE_PARSING to continue parsing.
+ * @return #LLHTTP_CONTINUE_PARSING to continue parsing.
*/
-static int httpParserOnHeaderFieldCallback( http_parser * pHttpParser,
+static int httpParserOnHeaderFieldCallback( llhttp_t * pHttpParser,
const char * pLoc,
size_t length );
/**
- * @brief Callback invoked during http_parser_execute() when an HTTP response
+ * @brief Callback invoked during llhttp_execute() when an HTTP response
* header value is found.
*
* This header value corresponds to the header field that was found in the
@@ -420,14 +420,14 @@ static int httpParserOnHeaderFieldCallback( http_parser * pHttpParser,
* @param[in] pLoc Location of the header value in the response message buffer.
* @param[in] length Length of the header value.
*
- * @return #HTTP_PARSER_CONTINUE_PARSING to continue parsing.
+ * @return #LLHTTP_CONTINUE_PARSING to continue parsing.
*/
-static int httpParserOnHeaderValueCallback( http_parser * pHttpParser,
+static int httpParserOnHeaderValueCallback( llhttp_t * pHttpParser,
const char * pLoc,
size_t length );
/**
- * @brief Callback invoked during http_parser_execute() when the end of the
+ * @brief Callback invoked during llhttp_execute() when the end of the
* headers are found.
*
* The end of the headers is signaled in a HTTP response message by another
@@ -435,13 +435,13 @@ static int httpParserOnHeaderValueCallback( http_parser * pHttpParser,
*
* @param[in] pHttpParser Parsing object containing state and callback context.
*
- * @return #HTTP_PARSER_CONTINUE_PARSING to continue parsing.
- * #HTTP_PARSER_STOP_PARSING is returned if the response is for a HEAD request.
+ * @return #LLHTTP_CONTINUE_PARSING to continue parsing.
+ * #LLHTTP_STOP_PARSING_NO_BODY is returned if the response is for a HEAD request.
*/
-static int httpParserOnHeadersCompleteCallback( http_parser * pHttpParser );
+static int httpParserOnHeadersCompleteCallback( llhttp_t * pHttpParser );
/**
- * @brief Callback invoked during http_parser_execute() when the HTTP response
+ * @brief Callback invoked during llhttp_execute() when the HTTP response
* body is found.
*
* If only part of the response body was found, then parsing of the next part of
@@ -480,14 +480,14 @@ static int httpParserOnHeadersCompleteCallback( http_parser * pHttpParser );
* @param[in] length - The length of the body found.
*
* @return Zero to continue parsing. All other return values will stop parsing
- * and http_parser_execute() will return with status HPE_CB_body.
+ * and llhttp_execute() will return with the same value.
*/
-static int httpParserOnBodyCallback( http_parser * pHttpParser,
+static int httpParserOnBodyCallback( llhttp_t * pHttpParser,
const char * pLoc,
size_t length );
/**
- * @brief Callback invoked during http_parser_execute() to indicate the the
+ * @brief Callback invoked during llhttp_execute() to indicate the the
* completion of an HTTP response message.
*
* When there is no response body, the end of the response message is when the
@@ -495,20 +495,20 @@ static int httpParserOnBodyCallback( http_parser * pHttpParser,
*
* When there is response body, the end of the response message is when the
* full "Content-Length" value is parsed following the end of the headers. If
- * there is no Content-Length header, then http_parser_execute() expects a
+ * there is no Content-Length header, then llhttp_execute() expects a
* zero length-ed parsing data to indicate the end of the response.
*
* For a "Transfer-Encoding: chunked" type of response message, the complete
* response message is signaled by a terminating chunk header with length zero.
*
- * See https://github.com/nodejs/http-parser for more information.
+ * See https://github.com/nodejs/llhttp for more information.
*
* @param[in] pHttpParser Parsing object containing state and callback context.
*
* @return Zero to continue parsing. All other return values will stop parsing
- * and http_parser_execute() will return with status HPE_CB_message_complete.
+ * and llhttp_execute() will return with the same value.
*/
-static int httpParserOnMessageCompleteCallback( http_parser * pHttpParser );
+static int httpParserOnMessageCompleteCallback( llhttp_t * pHttpParser );
/**
* @brief When a complete header is found the HTTP response header count
@@ -527,14 +527,13 @@ static void processCompleteHeader( HTTPParsingContext_t * pParsingContext );
/**
* @brief When parsing is complete an error could be indicated in
- * pHttpParser->http_errno. This function translates that error into a library
+ * pHttpParser->error. This function translates that error into a library
* specific error code.
*
* @param[in] pHttpParser Third-party HTTP parsing context.
*
* @return One of the following:
* - #HTTPSuccess
- * - #HTTPSecurityAlertResponseHeadersSizeLimitExceeded
* - #HTTPSecurityAlertExtraneousResponseData
* - #HTTPSecurityAlertInvalidChunkHeader
* - #HTTPSecurityAlertInvalidProtocolVersion
@@ -543,7 +542,7 @@ static void processCompleteHeader( HTTPParsingContext_t * pParsingContext );
* - #HTTPSecurityAlertInvalidContentLength
* - #HTTPParserInternalError
*/
-static HTTPStatus_t processHttpParserError( const http_parser * pHttpParser );
+static HTTPStatus_t processLlhttpError( const llhttp_t * pHttpParser );
/**
* @brief Compares at most the first n bytes of str1 and str2 without case sensitivity
@@ -638,7 +637,7 @@ static void processCompleteHeader( HTTPParsingContext_t * pParsingContext )
/*-----------------------------------------------------------*/
-static int httpParserOnMessageBeginCallback( http_parser * pHttpParser )
+static int httpParserOnMessageBeginCallback( llhttp_t * pHttpParser )
{
HTTPParsingContext_t * pParsingContext = NULL;
@@ -652,12 +651,12 @@ static int httpParserOnMessageBeginCallback( http_parser * pHttpParser )
LogDebug( ( "Response parsing: Found the start of the response message." ) );
- return HTTP_PARSER_CONTINUE_PARSING;
+ return LLHTTP_CONTINUE_PARSING;
}
/*-----------------------------------------------------------*/
-static int httpParserOnStatusCallback( http_parser * pHttpParser,
+static int httpParserOnStatusCallback( llhttp_t * pHttpParser,
const char * pLoc,
size_t length )
{
@@ -683,7 +682,7 @@ static int httpParserOnStatusCallback( http_parser * pHttpParser,
pParsingContext->pLastHeaderValue = NULL;
pParsingContext->lastHeaderValueLen = 0U;
- /* httpParserOnStatusCallback() is reached because http_parser_execute() has
+ /* httpParserOnStatusCallback() is reached because llhttp_execute() has
* successfully read the HTTP response status code. */
pResponse->statusCode = ( uint16_t ) ( pHttpParser->status_code );
@@ -693,12 +692,12 @@ static int httpParserOnStatusCallback( http_parser * pHttpParser,
( int ) length,
pLoc ) );
- return HTTP_PARSER_CONTINUE_PARSING;
+ return LLHTTP_CONTINUE_PARSING;
}
/*-----------------------------------------------------------*/
-static int httpParserOnHeaderFieldCallback( http_parser * pHttpParser,
+static int httpParserOnHeaderFieldCallback( llhttp_t * pHttpParser,
const char * pLoc,
size_t length )
{
@@ -731,7 +730,7 @@ static int httpParserOnHeaderFieldCallback( http_parser * pHttpParser,
processCompleteHeader( pParsingContext );
/* If httpParserOnHeaderFieldCallback() is invoked in succession, then the
- * last time http_parser_execute() was called only part of the header field
+ * last time llhttp_execute() was called only part of the header field
* was parsed. The indication of successive invocations is a non-NULL
* pParsingContext->pLastHeaderField. */
if( pParsingContext->pLastHeaderField == NULL )
@@ -750,12 +749,12 @@ static int httpParserOnHeaderFieldCallback( http_parser * pHttpParser,
( int ) length,
pLoc ) );
- return HTTP_PARSER_CONTINUE_PARSING;
+ return LLHTTP_CONTINUE_PARSING;
}
/*-----------------------------------------------------------*/
-static int httpParserOnHeaderValueCallback( http_parser * pHttpParser,
+static int httpParserOnHeaderValueCallback( llhttp_t * pHttpParser,
const char * pLoc,
size_t length )
{
@@ -771,7 +770,7 @@ static int httpParserOnHeaderValueCallback( http_parser * pHttpParser,
pParsingContext->pBufferCur = pLoc + length;
/* If httpParserOnHeaderValueCallback() is invoked in succession, then the
- * last time http_parser_execute() was called only part of the header field
+ * last time llhttp_execute() was called only part of the header field
* was parsed. The indication of successive invocations is a non-NULL
* pParsingContext->pLastHeaderField. */
if( pParsingContext->pLastHeaderValue == NULL )
@@ -786,8 +785,7 @@ static int httpParserOnHeaderValueCallback( http_parser * pHttpParser,
/* Given that httpParserOnHeaderFieldCallback() is ALWAYS invoked before
* httpParserOnHeaderValueCallback() is invoked, then the last header field
- * should never be NULL. This would indicate a bug in the http-parser
- * library. */
+ * should never be NULL. This would indicate a bug in the llhttp library. */
assert( pParsingContext->pLastHeaderField != NULL );
LogDebug( ( "Response parsing: Found a header value: "
@@ -795,14 +793,14 @@ static int httpParserOnHeaderValueCallback( http_parser * pHttpParser,
( int ) length,
pLoc ) );
- return HTTP_PARSER_CONTINUE_PARSING;
+ return LLHTTP_CONTINUE_PARSING;
}
/*-----------------------------------------------------------*/
-static int httpParserOnHeadersCompleteCallback( http_parser * pHttpParser )
+static int httpParserOnHeadersCompleteCallback( llhttp_t * pHttpParser )
{
- int shouldContinueParse = HTTP_PARSER_CONTINUE_PARSING;
+ int shouldContinueParse = LLHTTP_CONTINUE_PARSING;
HTTPParsingContext_t * pParsingContext = NULL;
HTTPResponse_t * pResponse = NULL;
@@ -866,14 +864,14 @@ static int httpParserOnHeadersCompleteCallback( http_parser * pHttpParser )
pResponse->respFlags |= HTTP_RESPONSE_CONNECTION_KEEP_ALIVE_FLAG;
}
- /* http_parser_execute() requires that callback implementations must
+ /* llhttp_execute() requires that callback implementations must
* indicate that parsing stops on headers complete, if response is to a HEAD
* request. A HEAD response will contain Content-Length, but no body. If
* the parser is not stopped here, then it will try to keep parsing past the
* end of the headers up to the Content-Length found. */
if( pParsingContext->isHeadResponse == 1U )
{
- shouldContinueParse = HTTP_PARSER_STOP_PARSING;
+ shouldContinueParse = LLHTTP_STOP_PARSING_NO_BODY;
}
/* If headers are present in the response, then
@@ -890,11 +888,11 @@ static int httpParserOnHeadersCompleteCallback( http_parser * pHttpParser )
/*-----------------------------------------------------------*/
-static int httpParserOnBodyCallback( http_parser * pHttpParser,
+static int httpParserOnBodyCallback( llhttp_t * pHttpParser,
const char * pLoc,
size_t length )
{
- int shouldContinueParse = HTTP_PARSER_CONTINUE_PARSING;
+ int shouldContinueParse = LLHTTP_CONTINUE_PARSING;
HTTPParsingContext_t * pParsingContext = NULL;
HTTPResponse_t * pResponse = NULL;
char * pNextWriteLoc = NULL;
@@ -967,7 +965,7 @@ static int httpParserOnBodyCallback( http_parser * pHttpParser,
/*-----------------------------------------------------------*/
-static int httpParserOnMessageCompleteCallback( http_parser * pHttpParser )
+static int httpParserOnMessageCompleteCallback( llhttp_t * pHttpParser )
{
HTTPParsingContext_t * pParsingContext = NULL;
@@ -981,7 +979,7 @@ static int httpParserOnMessageCompleteCallback( http_parser * pHttpParser )
LogDebug( ( "Response parsing: Response message complete." ) );
- return HTTP_PARSER_CONTINUE_PARSING;
+ return LLHTTP_CONTINUE_PARSING;
}
/*-----------------------------------------------------------*/
@@ -993,11 +991,21 @@ static void initializeParsingContextForFirstResponse( HTTPParsingContext_t * pPa
assert( pRequestHeaders != NULL );
assert( pRequestHeaders->headersLen >= HTTP_MINIMUM_REQUEST_LINE_LENGTH );
+ /* Initialize the callbacks that llhttp_execute will invoke. */
+ llhttp_settings_init( &( pParsingContext->llhttpSettings ) );
+ pParsingContext->llhttpSettings.on_message_begin = httpParserOnMessageBeginCallback;
+ pParsingContext->llhttpSettings.on_status = httpParserOnStatusCallback;
+ pParsingContext->llhttpSettings.on_header_field = httpParserOnHeaderFieldCallback;
+ pParsingContext->llhttpSettings.on_header_value = httpParserOnHeaderValueCallback;
+ pParsingContext->llhttpSettings.on_headers_complete = httpParserOnHeadersCompleteCallback;
+ pParsingContext->llhttpSettings.on_body = httpParserOnBodyCallback;
+ pParsingContext->llhttpSettings.on_message_complete = httpParserOnMessageCompleteCallback;
+
/* Initialize the third-party HTTP parser to parse responses. */
- http_parser_init( &( pParsingContext->httpParser ), HTTP_RESPONSE );
+ llhttp_init( &( pParsingContext->llhttpParser ), HTTP_RESPONSE, &( pParsingContext->llhttpSettings ) );
/* The parser will return an error if this header size limit is exceeded. */
- http_parser_set_max_header_size( HTTP_MAX_RESPONSE_HEADERS_SIZE_BYTES );
+ /*http_parser_set_max_header_size( HTTP_MAX_RESPONSE_HEADERS_SIZE_BYTES ); */
/* No response has been parsed yet. */
pParsingContext->state = HTTP_PARSING_NONE;
@@ -1019,13 +1027,16 @@ static void initializeParsingContextForFirstResponse( HTTPParsingContext_t * pPa
/*-----------------------------------------------------------*/
-static HTTPStatus_t processHttpParserError( const http_parser * pHttpParser )
+static HTTPStatus_t processLlhttpError( const llhttp_t * pHttpParser )
{
HTTPStatus_t returnStatus = HTTPSuccess;
assert( pHttpParser != NULL );
- switch( ( enum http_errno ) ( pHttpParser->http_errno ) )
+ /* llhttp_get_err_pos() may be used to get exact error locations, which was
+ * not possible with the previous http-parser. */
+
+ switch( llhttp_get_errno( pHttpParser ) )
{
case HPE_OK:
/* There were no errors. */
@@ -1038,12 +1049,7 @@ static HTTPStatus_t processHttpParserError( const http_parser * pHttpParser )
* This case is already handled by checking HTTPParsingContext_t.state. */
break;
- case HPE_HEADER_OVERFLOW:
- LogError( ( "Response parsing error: Header byte limit "
- "exceeded: HeaderByteLimit=%u",
- HTTP_MAX_RESPONSE_HEADERS_SIZE_BYTES ) );
- returnStatus = HTTPSecurityAlertResponseHeadersSizeLimitExceeded;
- break;
+ /* No header overflow in llhttp since no header size was set. */
case HPE_CLOSED_CONNECTION:
LogError( ( "Response parsing error: Data received past complete "
@@ -1066,6 +1072,7 @@ static HTTPStatus_t processHttpParserError( const http_parser * pHttpParser )
* character and location. */
LogError( ( "Response parsing error: Invalid character found in "
"HTTP protocol version." ) );
+
returnStatus = HTTPSecurityAlertInvalidProtocolVersion;
break;
@@ -1118,15 +1125,16 @@ static HTTPStatus_t processHttpParserError( const http_parser * pHttpParser )
/* All other error cases cannot be triggered and indicate an error in the
* third-party parsing library if found. */
default:
- LogError( ( "Error in third-party http-parser library." ) );
+ LogError( ( "Error in third-party llhttp library: %s", llhttp_errno_name( llhttp_get_errno( pHttpParser ) ) ) );
returnStatus = HTTPParserInternalError;
break;
}
- /* Errors with CB_ prepending are manual returns of non-zero in the
+ /* Errors with HPE_CB_ prepending are manual returns of non-zero in the
* response parsing callback. */
- LogDebug( ( "http-parser errno description: %s",
- http_errno_description( HTTP_PARSER_ERRNO( pHttpParser ) ) ) );
+ LogDebug( ( "llhttp errno description: %s %s",
+ llhttp_errno_name( llhttp_get_errno( pHttpParser ) ),
+ llhttp_get_error_reason( pHttpParser ) ) );
return returnStatus;
}
@@ -1138,12 +1146,8 @@ static HTTPStatus_t parseHttpResponse( HTTPParsingContext_t * pParsingContext,
size_t parseLen )
{
HTTPStatus_t returnStatus;
- http_parser_settings parserSettings = { 0 };
- size_t bytesParsed = 0U;
const char * parsingStartLoc = NULL;
-
- /* Disable unused variable warning. */
- ( void ) bytesParsed;
+ llhttp_errno_t parserStatus;
assert( pParsingContext != NULL );
assert( pResponse != NULL );
@@ -1177,19 +1181,9 @@ static HTTPStatus_t parseHttpResponse( HTTPParsingContext_t * pParsingContext,
assert( pParsingContext->pResponse == pResponse );
}
- /* Initialize the callbacks that http_parser_execute will invoke. */
- http_parser_settings_init( &parserSettings );
- parserSettings.on_message_begin = httpParserOnMessageBeginCallback;
- parserSettings.on_status = httpParserOnStatusCallback;
- parserSettings.on_header_field = httpParserOnHeaderFieldCallback;
- parserSettings.on_header_value = httpParserOnHeaderValueCallback;
- parserSettings.on_headers_complete = httpParserOnHeadersCompleteCallback;
- parserSettings.on_body = httpParserOnBodyCallback;
- parserSettings.on_message_complete = httpParserOnMessageCompleteCallback;
-
/* Setting this allows the parsing context and response to be carried to
- * each of the callbacks that http_parser_execute() will invoke. */
- pParsingContext->httpParser.data = pParsingContext;
+ * each of the callbacks that llhttp_execute() will invoke. */
+ pParsingContext->llhttpParser.data = pParsingContext;
/* Save the starting response buffer location to parse. This is needed to
* ensure that we move the next location to parse to exactly how many
@@ -1199,21 +1193,12 @@ 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. */
- bytesParsed = http_parser_execute( &( pParsingContext->httpParser ),
- &parserSettings,
- parsingStartLoc,
- parseLen );
+ parserStatus = llhttp_execute( &( pParsingContext->llhttpParser ), parsingStartLoc, parseLen );
/* The next location to parse will always be after what has already
* been parsed. */
- pParsingContext->pBufferCur = parsingStartLoc + bytesParsed;
-
- LogDebug( ( "Parsed HTTP Response buffer: BytesParsed=%lu, "
- "ExpectedBytesParsed=%lu",
- ( unsigned long ) bytesParsed,
- ( unsigned long ) parseLen ) );
-
- returnStatus = processHttpParserError( &( pParsingContext->httpParser ) );
+ pParsingContext->pBufferCur = parsingStartLoc + parseLen;
+ returnStatus = processLlhttpError( &( pParsingContext->llhttpParser ) );
return returnStatus;
}
@@ -2254,7 +2239,7 @@ HTTPStatus_t HTTPClient_Send( const TransportInterface_t * pTransport,
/*-----------------------------------------------------------*/
-static int findHeaderFieldParserCallback( http_parser * pHttpParser,
+static int findHeaderFieldParserCallback( llhttp_t * pHttpParser,
const char * pFieldLoc,
size_t fieldLen )
{
@@ -2291,16 +2276,16 @@ static int findHeaderFieldParserCallback( http_parser * pHttpParser,
/* Empty else for MISRA 15.7 compliance. */
}
- return HTTP_PARSER_CONTINUE_PARSING;
+ return LLHTTP_CONTINUE_PARSING;
}
/*-----------------------------------------------------------*/
-static int findHeaderValueParserCallback( http_parser * pHttpParser,
+static int findHeaderValueParserCallback( llhttp_t * pHttpParser,
const char * pValueLoc,
size_t valueLen )
{
- int retCode = HTTP_PARSER_CONTINUE_PARSING;
+ int retCode = LLHTTP_CONTINUE_PARSING;
findHeaderContext_t * pContext = NULL;
assert( pHttpParser != NULL );
@@ -2343,7 +2328,7 @@ static int findHeaderValueParserCallback( http_parser * pHttpParser,
/* As we have found the value associated with the header, we don't need
* to parse the response any further. */
- retCode = HTTP_PARSER_STOP_PARSING;
+ retCode = LLHTTP_STOP_PARSING;
}
else
{
@@ -2355,7 +2340,7 @@ static int findHeaderValueParserCallback( http_parser * pHttpParser,
/*-----------------------------------------------------------*/
-static int findHeaderOnHeaderCompleteCallback( http_parser * pHttpParser )
+static int findHeaderOnHeaderCompleteCallback( llhttp_t * pHttpParser )
{
findHeaderContext_t * pContext = NULL;
@@ -2375,8 +2360,14 @@ static int findHeaderOnHeaderCompleteCallback( http_parser * pHttpParser )
( int ) ( pContext->fieldLen ),
pContext->pField ) );
- /* No further parsing is required; thus, indicate the parser to stop parsing. */
- return HTTP_PARSER_STOP_PARSING;
+ /* No further parsing is required; thus, indicate the parser to stop parsing.
+ * The documentation for on_headers_complete states that this function can
+ * return 1 to indicate the response has no body, or -1 to indicate error.
+ * Returning 1 causes llhttp_execute() to exit with success, while -1
+ * causes it to return the HPE_CB_HEADERS_COMPLETE error code (in strict
+ * mode) or success (in non-strict mode). We are fine with the success
+ * return value, as llhttp_execute will not be invoked again in the same call.*/
+ return LLHTTP_STOP_PARSING_NO_HEADER;
}
/*-----------------------------------------------------------*/
@@ -2389,8 +2380,9 @@ static HTTPStatus_t findHeaderInResponse( const uint8_t * pBuffer,
size_t * pValueLen )
{
HTTPStatus_t returnStatus = HTTPSuccess;
- http_parser parser = { 0 };
- http_parser_settings parserSettings = { 0 };
+ llhttp_t parser = { 0 };
+ llhttp_settings_t parserSettings = { 0 };
+ llhttp_errno_t parserErrno;
findHeaderContext_t context = { 0 };
size_t numOfBytesParsed = 0U;
@@ -2401,30 +2393,20 @@ static HTTPStatus_t findHeaderInResponse( const uint8_t * pBuffer,
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
+ * need to create a private context in llhttp->data that has the field and
* value to update and pass back. */
- http_parser_settings_init( &parserSettings );
+ llhttp_settings_init( &( parserSettings ) );
parserSettings.on_header_field = findHeaderFieldParserCallback;
parserSettings.on_header_value = findHeaderValueParserCallback;
parserSettings.on_headers_complete = findHeaderOnHeaderCompleteCallback;
+ llhttp_init( &parser, HTTP_RESPONSE, &parserSettings );
- /* Start parsing for the header! */
- numOfBytesParsed = http_parser_execute( &parser,
- &parserSettings,
- ( const char * ) pBuffer,
- bufferLen );
+ /* Set the context for the parser. */
+ parser.data = &context;
- LogDebug( ( "Parsed response for header search: NumBytesParsed=%lu",
- ( unsigned long ) numOfBytesParsed ) );
+ /* Start parsing for the header! */
+ parserErrno = llhttp_execute( &parser, ( const char * ) pBuffer, bufferLen );
if( context.fieldFound == 0U )
{
@@ -2444,10 +2426,11 @@ static HTTPStatus_t findHeaderInResponse( const uint8_t * pBuffer,
* in the ": \r\n" format of an HTTP header. */
LogError( ( "Unable to find header value in response: "
"Response data is invalid: "
- "RequestedHeader=%.*s, ParserError=%s",
+ "RequestedHeader=%.*s, ParserError=%s %s",
( int ) fieldLen,
pField,
- http_errno_description( HTTP_PARSER_ERRNO( &( parser ) ) ) ) );
+ llhttp_errno_name( parserErrno ),
+ llhttp_get_error_reason( &parser ) ) );
returnStatus = HTTPInvalidResponse;
}
else
@@ -2466,25 +2449,27 @@ static HTTPStatus_t findHeaderInResponse( const uint8_t * pBuffer,
/* 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". */
+ * cause the llhttp.error to be "USER". */
if( ( returnStatus == HTTPSuccess ) &&
- ( parser.http_errno != ( unsigned int ) HPE_CB_header_value ) )
+ ( parserErrno != HPE_USER ) )
{
- LogError( ( "Header found in response but http-parser returned error: "
- "ParserError=%s",
- http_errno_description( HTTP_PARSER_ERRNO( &( parser ) ) ) ) );
+ LogError( ( "Header found in response but llhttp returned error: "
+ "ParserError=%s %s",
+ llhttp_errno_name( parserErrno ),
+ llhttp_get_error_reason( &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
+ * expected to be called which should cause the llhttp.error to be
* "OK" */
else if( ( returnStatus == HTTPHeaderNotFound ) &&
- ( parser.http_errno != ( unsigned int ) ( HPE_OK ) ) )
+ ( parserErrno != HPE_OK ) )
{
- LogError( ( "Header not found in response: http-parser returned error: "
- "ParserError=%s",
- http_errno_description( HTTP_PARSER_ERRNO( &( parser ) ) ) ) );
+ LogError( ( "Header not found in response: llhttp returned error: "
+ "ParserError=%s %s",
+ llhttp_errno_name( parserErrno ),
+ llhttp_get_error_reason( &parser ) ) );
returnStatus = HTTPInvalidResponse;
}
else
diff --git a/source/dependency/3rdparty/http_parser b/source/dependency/3rdparty/http_parser
deleted file mode 160000
index ec8b5ee6..00000000
--- a/source/dependency/3rdparty/http_parser
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit ec8b5ee63f0e51191ea43bb0c6eac7bfbff3141d
diff --git a/source/dependency/3rdparty/llhttp b/source/dependency/3rdparty/llhttp
new file mode 160000
index 00000000..a4aa7a70
--- /dev/null
+++ b/source/dependency/3rdparty/llhttp
@@ -0,0 +1 @@
+Subproject commit a4aa7a70e8b9a67f378b53264c61bb044a224366
diff --git a/source/include/core_http_client.h b/source/include/core_http_client.h
index 0f589a5b..2f005715 100644
--- a/source/include/core_http_client.h
+++ b/source/include/core_http_client.h
@@ -228,7 +228,7 @@ typedef enum HTTPStatus
* #HTTP_MAX_RESPONSE_HEADERS_SIZE_BYTES.
*
* Functions that may return this value:
- * - #HTTPClient_Send
+ * - None
*/
HTTPSecurityAlertResponseHeadersSizeLimitExceeded,
diff --git a/source/include/core_http_client_private.h b/source/include/core_http_client_private.h
index a0af6f9a..fc2ac28b 100644
--- a/source/include/core_http_client_private.h
+++ b/source/include/core_http_client_private.h
@@ -28,8 +28,17 @@
#ifndef CORE_HTTP_CLIENT_PRIVATE_H_
#define CORE_HTTP_CLIENT_PRIVATE_H_
-/* Third-party http-parser include. */
-#include "http_parser.h"
+/**
+ * @cond DOXYGEN_IGNORE
+ * http-parser defaults this to 1, llhttp to 0.
+ */
+#ifndef LLHTTP_STRICT_MODE
+ #define LLHTTP_STRICT_MODE 0
+#endif
+/** @endcond */
+
+/* Third-party llhttp include. */
+#include "llhttp.h"
/* *INDENT-OFF* */
#ifdef __cplusplus
@@ -150,16 +159,31 @@
1U /* Dash character '-' */ + MAX_INT32_NO_OF_DECIMAL_DIGITS )
/**
- * @brief Return value for the http-parser registered callback to signal halting
+ * @brief Return value for llhttp registered callback to signal
+ * continuation of HTTP response parsing. Equal to HPE_OK.
+ */
+#define LLHTTP_CONTINUE_PARSING 0
+
+/**
+ * @brief Return value for llhttp registered callback to signal halting
* further execution.
*/
-#define HTTP_PARSER_STOP_PARSING 1
+#define LLHTTP_STOP_PARSING HPE_USER
/**
- * @brief Return value for http_parser registered callback to signal
- * continuation of HTTP response parsing.
+ * @brief Return value for llhttp_t.on_headers_complete to signal
+ * that the HTTP response has no body and to halt further execution.
*/
-#define HTTP_PARSER_CONTINUE_PARSING 0
+#define LLHTTP_STOP_PARSING_NO_BODY 1
+
+/**
+ * @brief Return value for llhttp_t.on_headers_complete to signal
+ * halting further execution. This is the same return value that
+ * indicates the HTTP response has no body, but unlike the -1 error
+ * code, gives consistent return values for llhttp_execute in both
+ * strict and non-strict modes.
+ */
+#define LLHTTP_STOP_PARSING_NO_HEADER 1
/**
* @brief The minimum request-line in the headers has a possible one character
@@ -261,16 +285,17 @@ typedef struct findHeaderContext
*/
typedef struct HTTPParsingContext
{
- http_parser httpParser; /**< Third-party http-parser context. */
- HTTPParsingState_t state; /**< The current state of the HTTP response parsed. */
- HTTPResponse_t * pResponse; /**< HTTP response associated with this parsing context. */
- uint8_t isHeadResponse; /**< HTTP response is for a HEAD request. */
-
- const char * pBufferCur; /**< The current location of the parser in the response buffer. */
- const char * pLastHeaderField; /**< Holds the last part of the header field parsed. */
- size_t lastHeaderFieldLen; /**< The length of the last header field parsed. */
- const char * pLastHeaderValue; /**< Holds the last part of the header value parsed. */
- size_t lastHeaderValueLen; /**< The length of the last value field parsed. */
+ llhttp_t llhttpParser; /**< Third-party llhttp context. */
+ llhttp_settings_t llhttpSettings; /**< Third-party parser settings. */
+ HTTPParsingState_t state; /**< The current state of the HTTP response parsed. */
+ HTTPResponse_t * pResponse; /**< HTTP response associated with this parsing context. */
+ uint8_t isHeadResponse; /**< HTTP response is for a HEAD request. */
+
+ const char * pBufferCur; /**< The current location of the parser in the response buffer. */
+ const char * pLastHeaderField; /**< Holds the last part of the header field parsed. */
+ size_t lastHeaderFieldLen; /**< The length of the last header field parsed. */
+ const char * pLastHeaderValue; /**< Holds the last part of the header value parsed. */
+ size_t lastHeaderValueLen; /**< The length of the last value field parsed. */
} HTTPParsingContext_t;
/* *INDENT-OFF* */
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 767b9363..d92a942e 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -47,18 +47,18 @@ target_include_directories( coverity_analysis PUBLIC ${HTTP_INCLUDE_PUBLIC_DIRS}
# ===================== Clone needed third-party libraries ======================
-# Define an http-paser resource path.
-set( HTTP_PARSER_DIR ${MODULE_ROOT_DIR}/source/dependency/3rdparty/http_parser CACHE INTERNAL "http-parser library source directory." )
+# Define an llhttp paser resource path.
+set( LLHTTP_DIR ${MODULE_ROOT_DIR}/source/dependency/3rdparty/llhttp CACHE INTERNAL "llhttp library source directory." )
-include( http_parser_build.cmake )
+include( llhttp_build.cmake )
-# Check if the http_parser source directory exists.
-if( NOT EXISTS ${HTTP_PARSER_DIR}/http_parser.c )
- # Attempt to clone http_parser.
+# Check if the llhttp_source directory exists.
+if( NOT EXISTS ${LLHTTP_DIR}/src/llhttp.c )
+ # Attempt to clone llhttp.
if( ${BUILD_CLONE_SUBMODULES} )
- clone_http_parser()
+ clone_llhttp()
else()
- message( FATAL_ERROR "The required submodule http_parser does not exist. Either clone it manually, or set BUILD_CLONE_SUBMODULES to 1 to automatically clone it during build." )
+ message( FATAL_ERROR "The required submodule llhttp does not exist. Either clone it manually, or set BUILD_CLONE_SUBMODULES to 1 to automatically clone it during build." )
endif()
endif()
diff --git a/test/http_parser_build.cmake b/test/http_parser_build.cmake
deleted file mode 100644
index a5dd5609..00000000
--- a/test/http_parser_build.cmake
+++ /dev/null
@@ -1,19 +0,0 @@
-macro( clone_http_parser )
- find_package( Git REQUIRED )
- message( "Cloning submodule http_parser." )
- execute_process( COMMAND ${GIT_EXECUTABLE} submodule update --init --recursive ${HTTP_PARSER_DIR}
- WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
- RESULT_VARIABLE HTTP_PARSER_CLONE_RESULT )
-
- if( NOT ${HTTP_PARSER_CLONE_RESULT} STREQUAL "0" )
- message( FATAL_ERROR "Failed to clone http_parser submodule." )
- endif()
-endmacro()
-
-# http_parser library target.
-add_library( http_parser
- ${HTTP_PARSER_DIR}/http_parser.c )
-
-# http_parser public include path.
-target_include_directories( http_parser PUBLIC
- ${HTTP_PARSER_DIR} )
diff --git a/test/llhttp_build.cmake b/test/llhttp_build.cmake
new file mode 100644
index 00000000..3f04d0e4
--- /dev/null
+++ b/test/llhttp_build.cmake
@@ -0,0 +1,21 @@
+macro( clone_llhttp )
+ find_package( Git REQUIRED )
+ message( "Cloning submodule llhttp." )
+ execute_process( COMMAND ${GIT_EXECUTABLE} submodule update --init --recursive ${LLHTTP_DIR}
+ WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
+ RESULT_VARIABLE LLHTTP_CLONE_RESULT )
+
+ if( NOT ${LLHTTP_CLONE_RESULT} STREQUAL "0" )
+ message( FATAL_ERROR "Failed to clone llhttp submodule." )
+ endif()
+endmacro()
+
+# llhttp library target.
+add_library( llhttp
+ ${LLHTTP_DIR}/src/api.c
+ ${LLHTTP_DIR}/src/http.c
+ ${LLHTTP_DIR}/src/llhttp.c )
+
+# llhttp public include path.
+target_include_directories( llhttp PUBLIC
+ ${LLHTTP_DIR}/include )
diff --git a/test/unit-test/CMakeLists.txt b/test/unit-test/CMakeLists.txt
index 838b891b..bf0baf5a 100644
--- a/test/unit-test/CMakeLists.txt
+++ b/test/unit-test/CMakeLists.txt
@@ -8,11 +8,11 @@ set(project_name "core_http")
# list the files to mock here
list(APPEND mock_list
- ${HTTP_PARSER_DIR}/http_parser.h
+ ${LLHTTP_DIR}/include/llhttp.h
)
# list the directories your mocks need
list(APPEND mock_include_list
- ${HTTP_PARSER_DIR}
+ ${LLHTTP_DIR}/include
)
#list the definitions of your mocks to control what to be included
list(APPEND mock_define_list
@@ -41,7 +41,7 @@ list(APPEND test_include_directories
# ============================= (end edit) ===================================
-set(mock_name "http_parser_mock")
+set(mock_name "llhttp_mock")
set(real_name "${project_name}_real")
create_mock_list(${mock_name}
diff --git a/test/unit-test/core_http_send_utest.c b/test/unit-test/core_http_send_utest.c
index 84e1e0bc..4ae0ae78 100644
--- a/test/unit-test/core_http_send_utest.c
+++ b/test/unit-test/core_http_send_utest.c
@@ -31,7 +31,7 @@
/* Private includes for internal macros. */
#include "core_http_client_private.h"
-#include "mock_http_parser.h"
+#include "mock_llhttp.h"
/* Template HTTP request for a HEAD request. */
#define HTTP_TEST_REQUEST_HEAD_HEADERS \
@@ -217,12 +217,12 @@ static uint8_t recvCurrentCall = 0;
/* The test sets this variable to indicate which call count count of transport
* receive to return zero from. */
static uint8_t recvTimeoutCall = 0;
-/* The count of times a mocked http_parser_execute callback has been invoked. */
+/* The count of times a mocked llhttp_execute callback has been invoked. */
static uint8_t httpParserExecuteCallCount;
-/* The error to set to the parsing context when the http_parser_execute_error
+/* The error to set to the parsing context when the llhttp_execute_error
* callback is invoked. */
-static enum http_errno httpParsingErrno;
+static enum llhttp_errno httpParsingErrno;
/* Response shared among the tests. */
static HTTPResponse_t response = { 0 };
@@ -387,26 +387,47 @@ static int32_t transportRecvNetworkError( NetworkContext_t * pNetworkContext,
return -1;
}
-/* Mocked http_parser_execute callback that sets the internal http_errno. */
-static size_t http_parser_execute_error( http_parser * pParser,
- const http_parser_settings * pSettings,
- const char * pData,
- size_t len,
- int cmock_num_calls )
+/* llhttp_init callback that sets the parser settings field. */
+static void llhttp_init_setup( llhttp_t * parser,
+ enum llhttp_type type,
+ const llhttp_settings_t * settings,
+ int cmock_num_calls )
+{
+ ( void ) cmock_num_calls;
+
+ parser->type = type;
+ /* Remove const qualifier. llhttp does this too. */
+ parser->settings = ( llhttp_settings_t * ) settings;
+ parser->error = HPE_OK;
+}
+
+/* llhttp_get_errno callback that returns the errno value. */
+llhttp_errno_t llhttp_get_errno_cb( const llhttp_t * parser,
+ int cmock_num_calls )
+{
+ ( void ) cmock_num_calls;
+
+ return parser->error;
+}
+
+/* Mocked llhttp_execute callback that sets the internal errno. */
+static llhttp_errno_t llhttp_execute_error( llhttp_t * pParser,
+ const char * pData,
+ size_t len,
+ int cmock_num_calls )
{
- ( void ) pSettings;
( void ) pData;
( void ) len;
( void ) cmock_num_calls;
- pParser->http_errno = httpParsingErrno;
- return 0;
+ pParser->error = httpParsingErrno;
+ return httpParsingErrno;
}
/* Mock helper that parses the status line starting from pNext. */
static void helper_parse_status_line( const char ** pNext,
- http_parser * pParser,
- const http_parser_settings * pSettings )
+ llhttp_t * pParser,
+ const llhttp_settings_t * pSettings )
{
const char * pReasonPhraseStart = NULL;
size_t reasonPhraseStartLen = 0;
@@ -432,8 +453,8 @@ static void helper_parse_status_line( const char ** pNext,
/* Mock helper that parses all of the headers starting from pNext. */
static void helper_parse_headers( const char ** pNext,
- http_parser * pParser,
- const http_parser_settings * pSettings )
+ llhttp_t * pParser,
+ const llhttp_settings_t * pSettings )
{
const char * pHeaderFieldStart = NULL;
size_t headerFieldLen = 0;
@@ -461,8 +482,8 @@ static void helper_parse_headers( const char ** pNext,
/* Mock helper that parses the end of the headers starting from pNext. pNext
* will point to the start of the body after this is finished. */
static void helper_parse_headers_finish( const char ** pNext,
- http_parser * pParser,
- const http_parser_settings * pSettings,
+ llhttp_t * pParser,
+ const llhttp_settings_t * pSettings,
uint8_t * isHeadResponse )
{
uint8_t isHeadResponseReturned = 0;
@@ -491,8 +512,8 @@ static void helper_parse_headers_finish( const char ** pNext,
/* Mock helper that parses the response body starting from pNext. */
static void helper_parse_body( const char ** pNext,
- http_parser * pParser,
- const http_parser_settings * pSettings,
+ llhttp_t * pParser,
+ const llhttp_settings_t * pSettings,
uint8_t isHeadResponse,
const char * pData,
size_t len )
@@ -513,17 +534,17 @@ static void helper_parse_body( const char ** pNext,
}
}
-/* Mocked http_parser_execute callback that expects a whole response to be in
+/* Mocked llhttp_execute callback that expects a whole response to be in
* the given data to parse. */
-static size_t http_parser_execute_whole_response( http_parser * pParser,
- const http_parser_settings * pSettings,
- const char * pData,
- size_t len,
- int cmock_num_calls )
+static llhttp_errno_t llhttp_execute_whole_response( llhttp_t * pParser,
+ const char * pData,
+ size_t len,
+ int cmock_num_calls )
{
( void ) cmock_num_calls;
const char * pNext = pData;
uint8_t isHeadResponse = 0;
+ llhttp_settings_t * pSettings = ( llhttp_settings_t * ) pParser->settings;
pSettings->on_message_begin( pParser );
@@ -535,24 +556,24 @@ static size_t http_parser_execute_whole_response( http_parser * pParser,
pSettings->on_message_complete( pParser );
httpParserExecuteCallCount++;
- return len;
+ return HPE_OK;
}
-/* Mocked http_parser_execute callback that will be called the first time on the
+/* 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
* end. */
-static size_t http_parser_execute_partial_header_field( http_parser * pParser,
- const http_parser_settings * pSettings,
- const char * pData,
- size_t len,
- int cmock_num_calls )
+static llhttp_errno_t llhttp_execute_partial_header_field( llhttp_t * pParser,
+ const char * pData,
+ size_t len,
+ int cmock_num_calls )
{
( void ) cmock_num_calls;
const char * pNext = pData;
uint8_t isHeadResponse = 0;
const char * pHeaderFieldStart = NULL;
size_t headerFieldLen = 0;
+ llhttp_settings_t * pSettings = ( llhttp_settings_t * ) pParser->settings;
if( httpParserExecuteCallCount == 0 )
{
@@ -567,12 +588,12 @@ static size_t http_parser_execute_partial_header_field( http_parser * pParser,
}
else
{
- /* For testing of invoking http_parser_execute() with a parsing length
+ /* For testing of invoking llhttp_execute() with a parsing length
* of zero, when data had been previously parsed. */
if( len == 0 )
{
- pParser->http_errno = HPE_INVALID_EOF_STATE;
- return 0;
+ pParser->error = HPE_INVALID_EOF_STATE;
+ return HPE_INVALID_EOF_STATE;
}
helper_parse_headers( &pNext, pParser, pSettings );
@@ -582,18 +603,17 @@ static size_t http_parser_execute_partial_header_field( http_parser * pParser,
}
httpParserExecuteCallCount++;
- return len;
+ return HPE_OK;
}
-/* Mocked http_parser_execute callback that will be called the first time on the
+/* Mocked llhttp_execute callback that will be called the first time on the
* response message up to the middle of the first header value, then the second
* time on the response message from the middle of the first header value to the
* end. */
-static size_t http_parser_execute_partial_header_value( http_parser * pParser,
- const http_parser_settings * pSettings,
- const char * pData,
- size_t len,
- int cmock_num_calls )
+static llhttp_errno_t llhttp_execute_partial_header_value( llhttp_t * pParser,
+ const char * pData,
+ size_t len,
+ int cmock_num_calls )
{
( void ) cmock_num_calls;
@@ -603,6 +623,7 @@ static size_t http_parser_execute_partial_header_value( http_parser * pParser,
size_t headerFieldLen = 0;
const char * pHeaderValueStart = NULL;
size_t headerValueLen = 0;
+ llhttp_settings_t * pSettings = ( llhttp_settings_t * ) pParser->settings;
if( httpParserExecuteCallCount == 0 )
{
@@ -625,7 +646,7 @@ static size_t http_parser_execute_partial_header_value( http_parser * pParser,
}
else
{
- /* In this second call to http_parser_execute mock, pData now starts
+ /* In this second call to llhttp_execute mock, pData now starts
* at the partial header value. */
pHeaderValueStart = pNext;
pNext = strstr( pNext, HTTP_HEADER_LINE_SEPARATOR );
@@ -642,21 +663,21 @@ static size_t http_parser_execute_partial_header_value( http_parser * pParser,
}
httpParserExecuteCallCount++;
- return len;
+ return HPE_OK;
}
-/* Mocked http_parser_execute callback that will be called the first time on the
+/* Mocked llhttp_execute callback that will be called the first time on the
* response message up to the middle of the body, then the second time on the
* response message from the middle of the body to the end. */
-static size_t http_parser_execute_partial_body( http_parser * pParser,
- const http_parser_settings * pSettings,
- const char * pData,
- size_t len,
- int cmock_num_calls )
+static llhttp_errno_t llhttp_execute_partial_body( llhttp_t * pParser,
+ const char * pData,
+ size_t len,
+ int cmock_num_calls )
{
( void ) cmock_num_calls;
const char * pNext = pData;
+ llhttp_settings_t * pSettings = ( llhttp_settings_t * ) pParser->settings;
if( httpParserExecuteCallCount == 0 )
{
@@ -676,16 +697,15 @@ static size_t http_parser_execute_partial_body( http_parser * pParser,
}
httpParserExecuteCallCount++;
- return len;
+ return HPE_OK;
}
-/* Mocked http_parser_execute callback that will be on a response of type
+/* Mocked llhttp_execute callback that will be on a response of type
* transfer-encoding chunked. */
-static size_t http_parser_execute_chunked_body( http_parser * pParser,
- const http_parser_settings * pSettings,
- const char * pData,
- size_t len,
- int cmock_num_calls )
+static llhttp_errno_t llhttp_execute_chunked_body( llhttp_t * pParser,
+ const char * pData,
+ size_t len,
+ int cmock_num_calls )
{
( void ) cmock_num_calls;
@@ -694,6 +714,7 @@ static size_t http_parser_execute_chunked_body( http_parser * pParser,
const char * pBody = NULL;
size_t bodyLen = 0;
const char * pChunkHeader = NULL;
+ llhttp_settings_t * pSettings = ( llhttp_settings_t * ) pParser->settings;
pSettings->on_message_begin( pParser );
@@ -725,7 +746,7 @@ static size_t http_parser_execute_chunked_body( http_parser * pParser,
pSettings->on_message_complete( pParser );
httpParserExecuteCallCount++;
- return len;
+ return HPE_OK;
}
/* ============================ UNITY FIXTURES ============================== */
@@ -765,10 +786,12 @@ void setUp( void )
response.pHeaderParsingCallback = &headerParsingCallback;
/* Ignore third-party init functions that return void. */
- http_parser_init_Ignore();
- http_parser_settings_init_Ignore();
- http_parser_set_max_header_size_Ignore();
- http_errno_description_IgnoreAndReturn( "Dummy unit test print." );
+ llhttp_init_Ignore();
+ llhttp_init_Stub( llhttp_init_setup );
+ llhttp_get_errno_Stub( llhttp_get_errno_cb );
+ llhttp_settings_init_Ignore();
+ llhttp_errno_name_IgnoreAndReturn( "Dummy" );
+ llhttp_get_error_reason_IgnoreAndReturn( "Dummy unit test print." );
}
/* ======================== Testing HTTPClient_Send ========================= */
@@ -779,7 +802,7 @@ void test_HTTPClient_Send_HEAD_request_parse_whole_response( void )
{
HTTPStatus_t returnStatus = HTTPSuccess;
- http_parser_execute_Stub( http_parser_execute_whole_response );
+ llhttp_execute_Stub( llhttp_execute_whole_response );
returnStatus = HTTPClient_Send( &transportInterface,
&requestHeaders,
@@ -808,7 +831,7 @@ void test_HTTPClient_Send_PUT_request_parse_whole_response( void )
{
HTTPStatus_t returnStatus = HTTPSuccess;
- http_parser_execute_Stub( http_parser_execute_whole_response );
+ llhttp_execute_Stub( llhttp_execute_whole_response );
checkContentLength = 1;
memcpy( requestHeaders.pBuffer,
@@ -847,7 +870,7 @@ void test_HTTPClient_Send_GET_request_parse_whole_response( void )
{
HTTPStatus_t returnStatus = HTTPSuccess;
- http_parser_execute_Stub( http_parser_execute_whole_response );
+ llhttp_execute_Stub( llhttp_execute_whole_response );
memcpy( requestHeaders.pBuffer,
HTTP_TEST_REQUEST_GET_HEADERS,
@@ -883,7 +906,7 @@ void test_HTTPClient_Send_no_response_headers( void )
{
HTTPStatus_t returnStatus = HTTPSuccess;
- http_parser_execute_Stub( http_parser_execute_whole_response );
+ llhttp_execute_Stub( llhttp_execute_whole_response );
pNetworkData = ( uint8_t * ) HTTP_TEST_RESPONSE_NO_HEADERS;
networkDataLen = HTTP_TEST_RESPONSE_NO_HEADERS_LENGTH;
@@ -916,7 +939,7 @@ void test_HTTPClient_Send_parse_partial_header_field( void )
{
HTTPStatus_t returnStatus = HTTPSuccess;
- http_parser_execute_Stub( http_parser_execute_partial_header_field );
+ llhttp_execute_Stub( llhttp_execute_partial_header_field );
firstPartBytes = HTTP_TEST_RESPONSE_HEAD_PARTIAL_HEADER_FIELD_LENGTH;
returnStatus = HTTPClient_Send( &transportInterface,
@@ -947,7 +970,7 @@ void test_HTTPClient_Send_parse_partial_header_value( void )
{
HTTPStatus_t returnStatus = HTTPSuccess;
- http_parser_execute_Stub( http_parser_execute_partial_header_value );
+ llhttp_execute_Stub( llhttp_execute_partial_header_value );
firstPartBytes = HTTP_TEST_RESPONSE_HEAD_PARTIAL_HEADER_VALUE_LENGTH;
returnStatus = HTTPClient_Send( &transportInterface,
@@ -978,7 +1001,7 @@ void test_HTTPClient_Send_parse_partial_body( void )
{
HTTPStatus_t returnStatus = HTTPSuccess;
- http_parser_execute_Stub( http_parser_execute_partial_body );
+ llhttp_execute_Stub( llhttp_execute_partial_body );
memcpy( requestHeaders.pBuffer,
HTTP_TEST_REQUEST_GET_HEADERS,
@@ -1013,7 +1036,7 @@ void test_HTTPClient_Send_parse_chunked_body( void )
{
HTTPStatus_t returnStatus = HTTPSuccess;
- http_parser_execute_Stub( http_parser_execute_chunked_body );
+ llhttp_execute_Stub( llhttp_execute_chunked_body );
memcpy( requestHeaders.pBuffer,
HTTP_TEST_REQUEST_PUT_HEADERS,
@@ -1048,7 +1071,7 @@ void test_HTTPClient_Send_timeout_recv_immediate( void )
{
HTTPStatus_t returnStatus = HTTPSuccess;
- http_parser_execute_ExpectAnyArgsAndReturn( 0 );
+ llhttp_execute_ExpectAnyArgsAndReturn( HPE_OK );
/* Return a zero on the first call. */
recvTimeoutCall = 1;
@@ -1069,8 +1092,9 @@ void test_HTTPClient_Send_timeout_partial_response( void )
{
HTTPStatus_t returnStatus = HTTPSuccess;
- http_parser_execute_Stub( http_parser_execute_partial_header_field );
- http_errno_description_IgnoreAndReturn( "Dummy unit test print." );
+ llhttp_execute_Stub( llhttp_execute_partial_header_field );
+ llhttp_errno_name_IgnoreAndReturn( "Dummy" );
+ llhttp_get_error_reason_IgnoreAndReturn( "Dummy unit test print." );
firstPartBytes = HTTP_TEST_RESPONSE_HEAD_PARTIAL_HEADER_VALUE_LENGTH;
/* Return a zero on the second transport receive call. */
@@ -1093,8 +1117,9 @@ void test_HTTPClient_Send_timeout_recv_retry( void )
{
HTTPStatus_t returnStatus = HTTPSuccess;
- http_parser_execute_Stub( http_parser_execute_whole_response );
- http_errno_description_IgnoreAndReturn( "Dummy unit test print." );
+ llhttp_execute_Stub( llhttp_execute_whole_response );
+ llhttp_errno_name_IgnoreAndReturn( "Dummy" );
+ llhttp_get_error_reason_IgnoreAndReturn( "Dummy unit test print." );
/* Set the optional time keeping function to retry the receive when zero
* data is read from the network. */
@@ -1123,8 +1148,9 @@ void test_HTTPClient_Send_response_larger_than_buffer( void )
{
HTTPStatus_t returnStatus = HTTPSuccess;
- http_parser_execute_Stub( http_parser_execute_partial_body );
- http_errno_description_IgnoreAndReturn( "Dummy unit test print." );
+ llhttp_execute_Stub( llhttp_execute_partial_body );
+ llhttp_errno_name_IgnoreAndReturn( "Dummy" );
+ llhttp_get_error_reason_IgnoreAndReturn( "Dummy unit test print." );
requestHeaders.pBuffer = ( uint8_t * ) ( HTTP_TEST_REQUEST_GET_HEADERS );
requestHeaders.bufferLen = HTTP_TEST_REQUEST_GET_HEADERS_LENGTH;
@@ -1218,7 +1244,7 @@ void test_HTTPClient_Send_timeout_send_retry( void )
{
HTTPStatus_t returnStatus = HTTPSuccess;
- http_parser_execute_Stub( http_parser_execute_whole_response );
+ llhttp_execute_Stub( llhttp_execute_whole_response );
response.getTime = getTestTime;
/* An zero is returned from the transport send on the first call. */
@@ -1241,7 +1267,7 @@ void test_HTTPClient_Send_timeout_send_retry_fail( void )
{
HTTPStatus_t returnStatus = HTTPSuccess;
- http_parser_execute_Stub( http_parser_execute_whole_response );
+ llhttp_execute_Stub( llhttp_execute_whole_response );
/* By default a HEAD request is ready to be sent. */
transportInterface.send = transportSendSuccess;
@@ -1269,7 +1295,7 @@ void test_HTTPClient_Send_less_bytes_request_headers( void )
{
HTTPStatus_t returnStatus = HTTPSuccess;
- http_parser_execute_Stub( http_parser_execute_whole_response );
+ llhttp_execute_Stub( llhttp_execute_whole_response );
transportInterface.send = transportSendSuccess;
/* Send the data partially in the first call to the transport send. */
@@ -1309,7 +1335,7 @@ void test_HTTPClient_Send_less_bytes_request_body( void )
{
HTTPStatus_t returnStatus = HTTPSuccess;
- http_parser_execute_Stub( http_parser_execute_whole_response );
+ llhttp_execute_Stub( llhttp_execute_whole_response );
transportInterface.send = transportSendSuccess;
@@ -1351,7 +1377,7 @@ void test_HTTPClient_Send_network_error_response( void )
{
HTTPStatus_t returnStatus = HTTPSuccess;
- http_parser_init_Ignore();
+ llhttp_init_Ignore();
transportInterface.recv = transportRecvNetworkError;
returnStatus = HTTPClient_Send( &transportInterface,
@@ -1594,19 +1620,11 @@ void test_HTTPClient_Send_parsing_errors( void )
{
HTTPStatus_t returnStatus = HTTPSuccess;
- http_parser_init_Ignore();
- http_parser_settings_init_Ignore();
- http_parser_execute_Stub( http_parser_execute_error );
- http_errno_description_IgnoreAndReturn( "Dummy unit test print." );
-
- httpParsingErrno = HPE_HEADER_OVERFLOW;
- returnStatus = HTTPClient_Send( &transportInterface,
- &requestHeaders,
- NULL,
- 0,
- &response,
- 0 );
- TEST_ASSERT_EQUAL( HTTPSecurityAlertResponseHeadersSizeLimitExceeded, returnStatus );
+ llhttp_init_Ignore();
+ llhttp_settings_init_Ignore();
+ llhttp_execute_Stub( llhttp_execute_error );
+ llhttp_errno_name_IgnoreAndReturn( "Dummy" );
+ llhttp_get_error_reason_IgnoreAndReturn( "Dummy unit test print." );
httpParsingErrno = HPE_INVALID_CHUNK_SIZE;
returnStatus = HTTPClient_Send( &transportInterface,
@@ -1698,7 +1716,8 @@ void test_HTTPClient_Send_parsing_errors( void )
0 );
TEST_ASSERT_EQUAL( HTTPSecurityAlertInvalidContentLength, returnStatus );
- httpParsingErrno = HPE_UNKNOWN;
+ /* Use -1 to indicate an unknown error. */
+ httpParsingErrno = -1;
returnStatus = HTTPClient_Send( &transportInterface,
&requestHeaders,
NULL,
diff --git a/test/unit-test/core_http_utest.c b/test/unit-test/core_http_utest.c
index fc928327..781f6820 100644
--- a/test/unit-test/core_http_utest.c
+++ b/test/unit-test/core_http_utest.c
@@ -30,8 +30,8 @@
/* Private includes for internal macros. */
#include "core_http_client_private.h"
-/* Include mock implementation of http-parser dependency. */
-#include "mock_http_parser.h"
+/* Include mock implementation of llhttp dependency. */
+#include "mock_llhttp.h"
/* Default size for request buffer. */
#define HTTP_TEST_BUFFER_SIZE ( 100 )
@@ -175,8 +175,8 @@ static const size_t otherHeaderFieldInRespLoc = 98;
static const size_t otherHeaderFieldInRespLen = sizeof( "header_not_in_buffer" ) - 1U;
static const size_t headerValInRespLoc = 58;
static const size_t headerValInRespLen = sizeof( "test-value1" ) - 1U;
-static http_parser * pCapturedParser = NULL;
-static http_parser_settings * pCapturedSettings = NULL;
+static llhttp_t * pCapturedParser = NULL;
+static llhttp_settings_t * pCapturedSettings = NULL;
static const char * pExpectedBuffer = NULL;
static size_t expectedBufferSize = 0U;
static uint8_t invokeHeaderFieldCallback = 0U;
@@ -192,12 +192,13 @@ static unsigned int parserErrNo = 0;
/* ============================ Helper Functions ============================== */
/**
- * @brief Callback that is passed to the mock of http_parse_init function
+ * @brief Callback that is passed to the mock of llhttp_init function
* to set test expectations on input arguments sent by the HTTP API function under
* test.
*/
-void parserInitExpectationCb( http_parser * parser,
- enum http_parser_type type,
+void parserInitExpectationCb( llhttp_t * parser,
+ enum llhttp_type type,
+ const llhttp_settings_t * settings,
int cmock_num_calls )
{
/* Disable unused parameter warning. */
@@ -205,16 +206,19 @@ void parserInitExpectationCb( http_parser * parser,
TEST_ASSERT_NOT_NULL( parser );
pCapturedParser = parser;
+ TEST_ASSERT_EQUAL( pCapturedSettings, settings );
+ /* Set the settings member expected by calls to llhttp_execute(). */
+ parser->settings = ( llhttp_settings_t * ) settings;
TEST_ASSERT_EQUAL( HTTP_RESPONSE, type );
}
/**
- * @brief Callback that is passed to the mock of http_parse_settings_init function
+ * @brief Callback that is passed to the mock of llhttp_settings_init function
* to set test expectations on input arguments sent by the HTTP API function under
* test.
*/
-void parserSettingsInitExpectationCb( http_parser_settings * settings,
+void parserSettingsInitExpectationCb( llhttp_settings_t * settings,
int cmock_num_calls )
{
/* Disable unused parameter warning. */
@@ -225,53 +229,51 @@ void parserSettingsInitExpectationCb( http_parser_settings * settings,
}
/**
- * @brief Callback that is passed to the mock of http_parse_execute() function
+ * @brief Callback that is passed to the mock of llhttp_execute() function
* to set test expectations on input arguments, and inject behavior of invoking
- * http-parser callbacks depending on test-case specific configuration of the
+ * llhttp callbacks depending on test-case specific configuration of the
* function.
*/
-size_t parserExecuteExpectationsCb( http_parser * parser,
- const http_parser_settings * settings,
- const char * data,
- size_t len,
- int cmock_num_calls )
+llhttp_errno_t parserExecuteExpectationsCb( llhttp_t * parser,
+ const char * data,
+ size_t len,
+ int cmock_num_calls )
{
/* Disable unused parameter warning. */
( void ) cmock_num_calls;
- TEST_ASSERT_NOT_NULL( settings );
TEST_ASSERT_EQUAL( pCapturedParser, parser );
TEST_ASSERT_NOT_NULL( parser );
- TEST_ASSERT_EQUAL( pCapturedSettings, settings );
+ TEST_ASSERT_EQUAL( pCapturedSettings, parser->settings );
TEST_ASSERT_EQUAL( expectedBufferSize, len );
TEST_ASSERT_EQUAL( pExpectedBuffer, data );
if( invokeHeaderFieldCallback == 1U )
{
- TEST_ASSERT_EQUAL( HTTP_PARSER_CONTINUE_PARSING,
- settings->on_header_field( parser,
- pFieldLocToReturn,
- fieldLenToReturn ) );
+ TEST_ASSERT_EQUAL( LLHTTP_CONTINUE_PARSING,
+ ( ( llhttp_settings_t * ) ( parser->settings ) )->on_header_field( parser,
+ pFieldLocToReturn,
+ fieldLenToReturn ) );
}
if( invokeHeaderValueCallback == 1U )
{
TEST_ASSERT_EQUAL( expectedValCbRetVal,
- settings->on_header_value( parser,
- pValueLocToReturn,
- valueLenToReturn ) );
+ ( ( llhttp_settings_t * ) ( parser->settings ) )->on_header_value( parser,
+ pValueLocToReturn,
+ valueLenToReturn ) );
}
if( invokeHeaderCompleteCallback == 1U )
{
- TEST_ASSERT_EQUAL( HTTP_PARSER_STOP_PARSING,
- settings->on_headers_complete( parser ) );
+ TEST_ASSERT_EQUAL( LLHTTP_STOP_PARSING_NO_HEADER,
+ ( ( llhttp_settings_t * ) ( parser->settings ) )->on_headers_complete( parser ) );
}
/* Set the error value in the parser. */
- parser->http_errno = parserErrNo;
- return len;
+ parser->error = parserErrNo;
+ return parserErrNo;
}
/**
@@ -347,13 +349,14 @@ void setUp()
testResponse.pBuffer = ( uint8_t * ) &pTestResponse[ 0 ];
testResponse.bufferLen = strlen( pTestResponse );
- /* Configure the http_parser mocks with their callbacks. */
- http_parser_init_AddCallback( parserInitExpectationCb );
- http_parser_settings_init_AddCallback( parserSettingsInitExpectationCb );
- http_parser_execute_AddCallback( parserExecuteExpectationsCb );
+ /* Configure the llhttp mocks with their callbacks. */
+ llhttp_settings_init_AddCallback( parserSettingsInitExpectationCb );
+ llhttp_init_AddCallback( parserInitExpectationCb );
+ llhttp_execute_AddCallback( parserExecuteExpectationsCb );
- /* Ignore the calls to http_errno_description. */
- http_errno_description_IgnoreAndReturn( "Mocked HTTP Parser Status" );
+ /* Ignore the calls to llhttp_get_error_reason. */
+ llhttp_errno_name_IgnoreAndReturn( "Mocked HTTP Parser Status" );
+ llhttp_get_error_reason_IgnoreAndReturn( "Mocked HTTP Parser Status" );
}
/* Called after each test method. */
@@ -1299,21 +1302,21 @@ void test_Http_ReadHeader_Invalid_Params( void )
*/
void test_Http_ReadHeader_Header_Not_In_Response( void )
{
- /* Add expectations for http_parser dependencies. */
- http_parser_init_ExpectAnyArgs();
- http_parser_settings_init_ExpectAnyArgs();
+ /* Add expectations for llhttp dependencies. */
+ llhttp_settings_init_ExpectAnyArgs();
+ llhttp_init_ExpectAnyArgs();
- /* Configure the http_parser_execute mock. */
+ /* Configure the llhttp_execute mock. */
invokeHeaderFieldCallback = 1U;
invokeHeaderValueCallback = 1U;
pFieldLocToReturn = &pTestResponse[ headerFieldInRespLoc ];
fieldLenToReturn = headerFieldInRespLen;
pValueLocToReturn = &pTestResponse[ headerValInRespLoc ];
valueLenToReturn = headerValInRespLen;
- expectedValCbRetVal = HTTP_PARSER_CONTINUE_PARSING;
+ expectedValCbRetVal = LLHTTP_CONTINUE_PARSING;
invokeHeaderCompleteCallback = 1U;
parserErrNo = HPE_OK;
- http_parser_execute_ExpectAnyArgsAndReturn( strlen( pTestResponse ) );
+ llhttp_execute_ExpectAnyArgsAndReturn( HPE_OK );
/* Call the function under test. */
testResponse.bufferLen = strlen( pTestResponse );
@@ -1328,25 +1331,25 @@ void test_Http_ReadHeader_Header_Not_In_Response( void )
* Doing this allows us to take the branch where the actual contents
* of the fields are compared rather than just the length. */
setUp();
- /* Add expectations for http_parser dependencies. */
- http_parser_init_ExpectAnyArgs();
- http_parser_settings_init_ExpectAnyArgs();
+ /* Add expectations for llhttp dependencies. */
+ llhttp_settings_init_ExpectAnyArgs();
+ llhttp_init_ExpectAnyArgs();
/* Ensure that the header field does NOT match what we're searching. */
TEST_ASSERT_EQUAL( otherHeaderFieldInRespLen, HEADER_NOT_IN_BUFFER_LEN );
TEST_ASSERT_TRUE( memcmp( &pTestResponse[ otherHeaderFieldInRespLoc ],
HEADER_NOT_IN_BUFFER,
HEADER_NOT_IN_BUFFER_LEN ) != 0 );
- /* Configure the http_parser_execute mock. */
+ /* Configure the llhttp_execute mock. */
invokeHeaderFieldCallback = 1U;
invokeHeaderValueCallback = 1U;
pFieldLocToReturn = &pTestResponse[ otherHeaderFieldInRespLoc ];
fieldLenToReturn = otherHeaderFieldInRespLen;
pValueLocToReturn = &pTestResponse[ headerValInRespLoc ];
valueLenToReturn = headerValInRespLen;
- expectedValCbRetVal = HTTP_PARSER_CONTINUE_PARSING;
+ expectedValCbRetVal = LLHTTP_CONTINUE_PARSING;
invokeHeaderCompleteCallback = 1U;
parserErrNo = HPE_OK;
- http_parser_execute_ExpectAnyArgsAndReturn( strlen( pTestResponse ) );
+ llhttp_execute_ExpectAnyArgsAndReturn( HPE_OK );
/* Call the function under test. */
testResponse.bufferLen = strlen( pTestResponse );
@@ -1369,17 +1372,17 @@ void test_Http_ReadHeader_Invalid_Response_Only_Header_Field_Found()
"test-header0: test-value0\r\n"
"test-header1:";
- /* Add expectations for http_parser init dependencies. */
- http_parser_init_ExpectAnyArgs();
- http_parser_settings_init_ExpectAnyArgs();
+ /* Add expectations for llhttp init dependencies. */
+ llhttp_settings_init_ExpectAnyArgs();
+ llhttp_init_ExpectAnyArgs();
- /* Configure the http_parser_execute mock. */
+ /* Configure the llhttp_execute mock. */
pExpectedBuffer = pResponseWithoutValue;
expectedBufferSize = strlen( pResponseWithoutValue );
invokeHeaderFieldCallback = 1U;
pFieldLocToReturn = &pTestResponse[ headerFieldInRespLoc ];
fieldLenToReturn = headerFieldInRespLen;
- http_parser_execute_ExpectAnyArgsAndReturn( strlen( pResponseWithoutValue ) );
+ llhttp_execute_ExpectAnyArgsAndReturn( HPE_OK );
/* Call the function under test. */
testResponse.pBuffer = ( uint8_t * ) &pResponseWithoutValue[ 0 ];
@@ -1405,15 +1408,16 @@ void test_Http_ReadHeader_Invalid_Response_No_Headers_Complete_Ending()
tearDown();
- /* Add expectations for http_parser init dependencies. */
- http_parser_init_ExpectAnyArgs();
- http_parser_settings_init_ExpectAnyArgs();
+ /* Add expectations for llhttp init dependencies. */
+ llhttp_settings_init_ExpectAnyArgs();
+ llhttp_init_ExpectAnyArgs();
- /* Configure the http_parser_execute mock. */
+ /* Configure the llhttp_execute mock. */
pExpectedBuffer = &pResponseWithoutHeaders[ 0 ];
expectedBufferSize = strlen( pResponseWithoutHeaders );
- parserErrNo = HPE_UNKNOWN;
- http_parser_execute_ExpectAnyArgsAndReturn( strlen( pResponseWithoutHeaders ) );
+ /* Use -1 for an unknown error. */
+ parserErrNo = -1;
+ llhttp_execute_ExpectAnyArgsAndReturn( -1 );
/* Call the function under test. */
testResponse.pBuffer = ( uint8_t * ) &pResponseWithoutHeaders[ 0 ];
testResponse.bufferLen = strlen( pResponseWithoutHeaders );
@@ -1426,26 +1430,26 @@ void test_Http_ReadHeader_Invalid_Response_No_Headers_Complete_Ending()
}
/**
- * @brief Test when the header is present in response but http_parser_execute()
- * does not set the expected errno value (of "CB_header_value")
+ * @brief Test when the header is present in response but llhttp_execute()
+ * does not set the expected errno value (of "HPE_USER")
* due to an internal error.
*/
void test_Http_ReadHeader_With_HttpParser_Internal_Error()
{
- /* Add expectations for http_parser init dependencies. */
- http_parser_init_ExpectAnyArgs();
- http_parser_settings_init_ExpectAnyArgs();
+ /* Add expectations for llhttp init dependencies. */
+ llhttp_settings_init_ExpectAnyArgs();
+ llhttp_init_ExpectAnyArgs();
- /* Configure the http_parser_execute mock. */
+ /* Configure the llhttp_execute mock. */
invokeHeaderFieldCallback = 1U;
invokeHeaderValueCallback = 1U;
pFieldLocToReturn = &pTestResponse[ headerFieldInRespLoc ];
fieldLenToReturn = headerFieldInRespLen;
pValueLocToReturn = &pTestResponse[ headerValInRespLoc ];
valueLenToReturn = headerValInRespLen;
- expectedValCbRetVal = HTTP_PARSER_STOP_PARSING;
- parserErrNo = HPE_CB_chunk_complete;
- http_parser_execute_ExpectAnyArgsAndReturn( strlen( pTestResponse ) );
+ expectedValCbRetVal = LLHTTP_STOP_PARSING;
+ parserErrNo = HPE_CB_CHUNK_COMPLETE;
+ llhttp_execute_ExpectAnyArgsAndReturn( HPE_CB_CHUNK_COMPLETE );
/* Call the function under test. */
retCode = HTTPClient_ReadHeader( &testResponse,
@@ -1461,20 +1465,21 @@ void test_Http_ReadHeader_With_HttpParser_Internal_Error()
*/
void test_Http_ReadHeader_Happy_Path()
{
- /* Add expectations for http_parser init dependencies. */
- http_parser_init_ExpectAnyArgs();
- http_parser_settings_init_ExpectAnyArgs();
+ /* Add expectations for llhttp init dependencies. */
+ llhttp_settings_init_ExpectAnyArgs();
+ llhttp_init_ExpectAnyArgs();
- /* Configure the http_parser_execute mock. */
- expectedValCbRetVal = HTTP_PARSER_STOP_PARSING;
+ /* Configure the llhttp_execute mock. */
+ expectedValCbRetVal = LLHTTP_STOP_PARSING;
pFieldLocToReturn = &pTestResponse[ headerFieldInRespLoc ];
fieldLenToReturn = headerFieldInRespLen;
pValueLocToReturn = &pTestResponse[ headerValInRespLoc ];
valueLenToReturn = headerValInRespLen;
invokeHeaderFieldCallback = 1U;
invokeHeaderValueCallback = 1U;
- parserErrNo = HPE_CB_header_value;
- http_parser_execute_ExpectAnyArgsAndReturn( strlen( pTestResponse ) );
+ /* Use HPE_USER to indicate the header value callback returns an error. */
+ parserErrNo = HPE_USER;
+ llhttp_execute_ExpectAnyArgsAndReturn( HPE_USER );
/* Call the function under test. */
retCode = HTTPClient_ReadHeader( &testResponse,
@@ -1493,22 +1498,23 @@ void test_Http_ReadHeader_Happy_Path()
*/
void test_Http_ReadHeader_EmptyHeaderValue()
{
- /* Add expectations for http_parser init dependencies. */
- http_parser_init_ExpectAnyArgs();
- http_parser_settings_init_ExpectAnyArgs();
+ /* Add expectations for llhttp init dependencies. */
+ llhttp_settings_init_ExpectAnyArgs();
+ llhttp_init_ExpectAnyArgs();
- /* Configure the http_parser_execute mock. */
- expectedValCbRetVal = HTTP_PARSER_STOP_PARSING;
+ /* Configure the llhttp_execute mock. */
+ expectedValCbRetVal = LLHTTP_STOP_PARSING;
pFieldLocToReturn = &pTestResponseEmptyValue[ headerFieldInRespLoc ];
fieldLenToReturn = headerFieldInRespLen;
/* Add two characters past the empty value to point to the next field. */
pValueLocToReturn = &pTestResponseEmptyValue[ headerValInRespLoc + HTTP_HEADER_LINE_SEPARATOR_LEN ];
- /* http-parser will pass in a value of zero for an empty value. */
+ /* llhttp will pass in a value of zero for an empty value. */
valueLenToReturn = 0U;
invokeHeaderFieldCallback = 1U;
invokeHeaderValueCallback = 1U;
- parserErrNo = HPE_CB_header_value;
- http_parser_execute_ExpectAnyArgsAndReturn( strlen( pTestResponse ) );
+ /* Use HPE_USER to indicate the header value callback returns an error. */
+ parserErrNo = HPE_USER;
+ llhttp_execute_ExpectAnyArgsAndReturn( HPE_USER );
/* Call the function under test. */
retCode = HTTPClient_ReadHeader( &testResponse,
diff --git a/tools/cmock/project.yml b/tools/cmock/project.yml
index 8a90416b..1c01520f 100644
--- a/tools/cmock/project.yml
+++ b/tools/cmock/project.yml
@@ -24,3 +24,5 @@
:treat_externs: :exclude # Now the extern-ed functions will be mocked.
:weak: __attribute__((weak))
:treat_externs: :include
+ :strippables:
+ - LLHTTP_EXPORT
From 1c94cde28b29b9c9d5bae1988237342429ba1954 Mon Sep 17 00:00:00 2001
From: Muneeb Ahmed <54290492+muneebahmed10@users.noreply.github.com>
Date: Tue, 1 Feb 2022 18:57:08 -0700
Subject: [PATCH 2/4] Update CBMC proofs for llhttp (#127)
* Update CBMC proofs
* Update execute mocks
* Rename stub file
* Return error fields from stubs
---
test/cbmc/include/http_cbmc_state.h | 18 ++++++-------
.../proofs/HTTPClient_ReadHeader/Makefile | 7 +++--
test/cbmc/proofs/HTTPClient_Send/Makefile | 7 +++--
test/cbmc/proofs/Makefile-project-defines | 2 +-
.../findHeaderFieldParserCallback_harness.c | 6 ++---
...ndHeaderOnHeaderCompleteCallback_harness.c | 6 ++---
.../findHeaderValueParserCallback_harness.c | 6 ++---
.../httpParserOnBodyCallback_harness.c | 6 ++---
.../httpParserOnHeaderFieldCallback_harness.c | 6 ++---
.../httpParserOnHeaderValueCallback_harness.c | 6 ++---
...pParserOnHeadersCompleteCallback_harness.c | 6 ++---
...httpParserOnMessageBeginCallback_harness.c | 6 ++---
...pParserOnMessageCompleteCallback_harness.c | 6 ++---
.../httpParserOnStatusCallback_harness.c | 6 ++---
test/cbmc/sources/http_cbmc_state.c | 8 +++---
...=> HTTPClient_ReadHeader_llhttp_execute.c} | 27 +++++++++----------
...ute.c => HTTPClient_Send_llhttp_execute.c} | 26 +++++++++---------
17 files changed, 75 insertions(+), 80 deletions(-)
rename test/cbmc/stubs/{HTTPClient_ReadHeader_http_parser_execute.c => HTTPClient_ReadHeader_llhttp_execute.c} (76%)
rename test/cbmc/stubs/{HTTPClient_Send_http_parser_execute.c => HTTPClient_Send_llhttp_execute.c} (78%)
diff --git a/test/cbmc/include/http_cbmc_state.h b/test/cbmc/include/http_cbmc_state.h
index 2c80a21a..453e97d5 100644
--- a/test/cbmc/include/http_cbmc_state.h
+++ b/test/cbmc/include/http_cbmc_state.h
@@ -33,7 +33,7 @@
#include "core_http_client.h"
#include "core_http_client_private.h"
-#include "http_parser.h"
+#include "llhttp.h"
#include "transport_interface_stubs.h"
struct NetworkContext
@@ -132,14 +132,14 @@ TransportInterface_t * allocateTransportInterface( TransportInterface_t * pTrans
bool isValidTransportInterface( TransportInterface_t * pTransportInterface );
/**
- * @brief Allocate an #http_parser object that is valid in the context of the
+ * @brief Allocate an #llhttp_t object that is valid in the context of the
* HTTPClient_Send() function.
*
- * @param[in] pHttpParser #http_parser object to allocate.
+ * @param[in] pHttpParser #llhttp_t object to allocate.
*
- * @return NULL or pointer to allocated #http_parser object.
+ * @return NULL or pointer to allocated #llhttp_t object.
*/
-http_parser * allocateHttpSendParser( http_parser * pHttpParser );
+llhttp_t * allocateHttpSendParser( llhttp_t * pHttpParser );
/**
* @brief Allocate an #HTTPParsingContext_t object.
@@ -160,14 +160,14 @@ HTTPParsingContext_t * allocateHttpSendParsingContext( HTTPParsingContext_t * pH
bool isValidHttpSendParsingContext( const HTTPParsingContext_t * pHttpParsingContext );
/**
- * @brief Allocate an #http_parser object that is valid in the context of the
+ * @brief Allocate an #llhttp_t object that is valid in the context of the
* HTTPClient_ReadHeader() function.
*
- * @param[in] pHttpParser #http_parser object to allocate.
+ * @param[in] pHttpParser #llhttp_t object to allocate.
*
- * @return NULL or pointer to allocated #http_parser object.
+ * @return NULL or pointer to allocated #llhttp_t object.
*/
-http_parser * allocateHttpReadHeaderParser( http_parser * pHttpParser );
+llhttp_t * allocateHttpReadHeaderParser( llhttp_t * pHttpParser );
/**
* @brief Allocate an #findHeaderContext_t object.
diff --git a/test/cbmc/proofs/HTTPClient_ReadHeader/Makefile b/test/cbmc/proofs/HTTPClient_ReadHeader/Makefile
index f1caf8f2..f96dbc4e 100644
--- a/test/cbmc/proofs/HTTPClient_ReadHeader/Makefile
+++ b/test/cbmc/proofs/HTTPClient_ReadHeader/Makefile
@@ -32,15 +32,14 @@ REMOVE_FUNCTION_BODY += __CPROVER_file_local_core_http_client_c_findHeaderValueP
REMOVE_FUNCTION_BODY += __CPROVER_file_local_core_http_client_c_findHeaderOnHeaderCompleteCallback
# Remove any unused functions for http parser
-REMOVE_FUNCTION_BODY += http_parser_init
-REMOVE_FUNCTION_BODY += http_parser_set_max_header_size
-REMOVE_FUNCTION_BODY += http_parser_settings_init
+REMOVE_FUNCTION_BODY += llhttp_init
+REMOVE_FUNCTION_BODY += llhttp_settings_init
UNWINDSET +=
PROOF_SOURCES += $(PROOFDIR)/$(HARNESS_FILE).c
PROOF_SOURCES += $(SRCDIR)/test/cbmc/sources/http_cbmc_state.c
-PROOF_SOURCES += $(SRCDIR)/test/cbmc/stubs/HTTPClient_ReadHeader_http_parser_execute.c
+PROOF_SOURCES += $(SRCDIR)/test/cbmc/stubs/HTTPClient_ReadHeader_llhttp_execute.c
PROJECT_SOURCES += $(SRCDIR)/source/core_http_client.c
diff --git a/test/cbmc/proofs/HTTPClient_Send/Makefile b/test/cbmc/proofs/HTTPClient_Send/Makefile
index fdeb4daf..49273bde 100644
--- a/test/cbmc/proofs/HTTPClient_Send/Makefile
+++ b/test/cbmc/proofs/HTTPClient_Send/Makefile
@@ -42,9 +42,8 @@ REMOVE_FUNCTION_BODY += __CPROVER_file_local_core_http_client_c_httpParserOnMess
REMOVE_FUNCTION_BODY += __CPROVER_file_local_core_http_client_c_httpParserOnMessageCompleteCallback
# Remove any unused functions for http parser
-REMOVE_FUNCTION_BODY += http_parser_init
-REMOVE_FUNCTION_BODY += http_parser_set_max_header_size
-REMOVE_FUNCTION_BODY += http_parser_settings_init
+REMOVE_FUNCTION_BODY += llhttp_init
+REMOVE_FUNCTION_BODY += llhttp_settings_init
# These functions are removed and replace with stubs that check that the
# destination parameter is writeable and that the source parameter is readable.
@@ -67,7 +66,7 @@ UNWINDSET += strncmp.0:5
PROOF_SOURCES += $(PROOFDIR)/$(HARNESS_FILE).c
PROOF_SOURCES += $(SRCDIR)/test/cbmc/sources/http_cbmc_state.c
-PROOF_SOURCES += $(SRCDIR)/test/cbmc/stubs/HTTPClient_Send_http_parser_execute.c
+PROOF_SOURCES += $(SRCDIR)/test/cbmc/stubs/HTTPClient_Send_llhttp_execute.c
PROOF_SOURCES += $(SRCDIR)/test/cbmc/stubs/transport_interface_stubs.c
PROOF_SOURCES += $(SRCDIR)/test/cbmc/stubs/get_time_stub.c
PROOF_SOURCES += $(SRCDIR)/test/cbmc/stubs/strncpy.c
diff --git a/test/cbmc/proofs/Makefile-project-defines b/test/cbmc/proofs/Makefile-project-defines
index 075626f6..573fc61c 100644
--- a/test/cbmc/proofs/Makefile-project-defines
+++ b/test/cbmc/proofs/Makefile-project-defines
@@ -26,7 +26,7 @@ INCLUDES += -I$(SRCDIR)/test/cbmc/include
INCLUDES += -I$(SRCDIR)/source/include
INCLUDES += -I$(SRCDIR)/source/interface
INCLUDES += -I$(SRCDIR)/source
-INCLUDES += -I$(SRCDIR)/source/dependency/3rdparty/http_parser
+INCLUDES += -I$(SRCDIR)/source/dependency/3rdparty/llhttp/include
# Preprocessor definitions -D...
DEFINES += -Dhttp_EXPORTS
diff --git a/test/cbmc/proofs/findHeaderFieldParserCallback/findHeaderFieldParserCallback_harness.c b/test/cbmc/proofs/findHeaderFieldParserCallback/findHeaderFieldParserCallback_harness.c
index 344b4eb2..8c5399bb 100644
--- a/test/cbmc/proofs/findHeaderFieldParserCallback/findHeaderFieldParserCallback_harness.c
+++ b/test/cbmc/proofs/findHeaderFieldParserCallback/findHeaderFieldParserCallback_harness.c
@@ -26,17 +26,17 @@
*/
#include "http_cbmc_state.h"
-#include "http_parser.h"
+#include "llhttp.h"
#include "core_http_client.h"
-int __CPROVER_file_local_core_http_client_c_findHeaderFieldParserCallback( http_parser * pHttpParser,
+int __CPROVER_file_local_core_http_client_c_findHeaderFieldParserCallback( llhttp_t * pHttpParser,
const char * pFieldLoc,
size_t fieldLen );
void findHeaderFieldParserCallback_harness()
{
- http_parser * pHttpParser;
+ llhttp_t * pHttpParser;
HTTPResponse_t * pResponse;
findHeaderContext_t * pFindHeaderContext;
size_t fieldLen, fieldContextLen, fieldOffset, valueLen, valueOffset;
diff --git a/test/cbmc/proofs/findHeaderOnHeaderCompleteCallback/findHeaderOnHeaderCompleteCallback_harness.c b/test/cbmc/proofs/findHeaderOnHeaderCompleteCallback/findHeaderOnHeaderCompleteCallback_harness.c
index fb57bed3..f4269e9b 100644
--- a/test/cbmc/proofs/findHeaderOnHeaderCompleteCallback/findHeaderOnHeaderCompleteCallback_harness.c
+++ b/test/cbmc/proofs/findHeaderOnHeaderCompleteCallback/findHeaderOnHeaderCompleteCallback_harness.c
@@ -26,14 +26,14 @@
*/
#include "http_cbmc_state.h"
-#include "http_parser.h"
+#include "llhttp.h"
#include "core_http_client.h"
-int __CPROVER_file_local_core_http_client_c_findHeaderOnHeaderCompleteCallback( http_parser * pHttpParser );
+int __CPROVER_file_local_core_http_client_c_findHeaderOnHeaderCompleteCallback( llhttp_t * pHttpParser );
void findHeaderOnHeaderCompleteCallback_harness()
{
- http_parser * pHttpParser;
+ llhttp_t * pHttpParser;
pHttpParser = allocateHttpReadHeaderParser( NULL );
diff --git a/test/cbmc/proofs/findHeaderValueParserCallback/findHeaderValueParserCallback_harness.c b/test/cbmc/proofs/findHeaderValueParserCallback/findHeaderValueParserCallback_harness.c
index 84e211f1..5eb11812 100644
--- a/test/cbmc/proofs/findHeaderValueParserCallback/findHeaderValueParserCallback_harness.c
+++ b/test/cbmc/proofs/findHeaderValueParserCallback/findHeaderValueParserCallback_harness.c
@@ -26,16 +26,16 @@
*/
#include "http_cbmc_state.h"
-#include "http_parser.h"
+#include "llhttp.h"
#include "core_http_client.h"
-int __CPROVER_file_local_core_http_client_c_findHeaderValueParserCallback( http_parser * pHttpParser,
+int __CPROVER_file_local_core_http_client_c_findHeaderValueParserCallback( llhttp_t * pHttpParser,
const char * pValueLoc,
size_t valueLen );
void findHeaderValueParserCallback_harness()
{
- http_parser * pHttpParser;
+ llhttp_t * pHttpParser;
HTTPResponse_t * pResponse;
findHeaderContext_t * pFindHeaderContext;
size_t fieldLen, fieldOffset, valueLen, valueOffset;
diff --git a/test/cbmc/proofs/httpParserOnBodyCallback/httpParserOnBodyCallback_harness.c b/test/cbmc/proofs/httpParserOnBodyCallback/httpParserOnBodyCallback_harness.c
index 2199a100..811536ad 100644
--- a/test/cbmc/proofs/httpParserOnBodyCallback/httpParserOnBodyCallback_harness.c
+++ b/test/cbmc/proofs/httpParserOnBodyCallback/httpParserOnBodyCallback_harness.c
@@ -26,15 +26,15 @@
*/
#include "http_cbmc_state.h"
-#include "http_parser.h"
+#include "llhttp.h"
-int __CPROVER_file_local_core_http_client_c_httpParserOnBodyCallback( http_parser * pHttpParser,
+int __CPROVER_file_local_core_http_client_c_httpParserOnBodyCallback( llhttp_t * pHttpParser,
const char * pLoc,
size_t length );
void httpParserOnBodyCallback_harness()
{
- http_parser * pHttpParser;
+ llhttp_t * pHttpParser;
HTTPParsingContext_t * pParsingContext;
HTTPResponse_t * pResponse;
size_t length;
diff --git a/test/cbmc/proofs/httpParserOnHeaderFieldCallback/httpParserOnHeaderFieldCallback_harness.c b/test/cbmc/proofs/httpParserOnHeaderFieldCallback/httpParserOnHeaderFieldCallback_harness.c
index a3926c2f..df25db5a 100644
--- a/test/cbmc/proofs/httpParserOnHeaderFieldCallback/httpParserOnHeaderFieldCallback_harness.c
+++ b/test/cbmc/proofs/httpParserOnHeaderFieldCallback/httpParserOnHeaderFieldCallback_harness.c
@@ -26,16 +26,16 @@
*/
#include "http_cbmc_state.h"
-#include "http_parser.h"
+#include "llhttp.h"
#include "callback_stubs.h"
-int __CPROVER_file_local_core_http_client_c_httpParserOnHeaderFieldCallback( http_parser * pHttpParser,
+int __CPROVER_file_local_core_http_client_c_httpParserOnHeaderFieldCallback( llhttp_t * pHttpParser,
const char * pLoc,
size_t length );
void httpParserOnHeaderFieldCallback_harness()
{
- http_parser * pHttpParser;
+ llhttp_t * pHttpParser;
HTTPParsingContext_t * pParsingContext;
HTTPResponse_t * pResponse;
HTTPClient_ResponseHeaderParsingCallback_t headerParserCallback;
diff --git a/test/cbmc/proofs/httpParserOnHeaderValueCallback/httpParserOnHeaderValueCallback_harness.c b/test/cbmc/proofs/httpParserOnHeaderValueCallback/httpParserOnHeaderValueCallback_harness.c
index ede2a500..5181e8a6 100644
--- a/test/cbmc/proofs/httpParserOnHeaderValueCallback/httpParserOnHeaderValueCallback_harness.c
+++ b/test/cbmc/proofs/httpParserOnHeaderValueCallback/httpParserOnHeaderValueCallback_harness.c
@@ -26,15 +26,15 @@
*/
#include "http_cbmc_state.h"
-#include "http_parser.h"
+#include "llhttp.h"
-int __CPROVER_file_local_core_http_client_c_httpParserOnHeaderValueCallback( http_parser * pHttpParser,
+int __CPROVER_file_local_core_http_client_c_httpParserOnHeaderValueCallback( llhttp_t * pHttpParser,
const char * pLoc,
size_t length );
void httpParserOnHeaderValueCallback_harness()
{
- http_parser * pHttpParser;
+ llhttp_t * pHttpParser;
HTTPParsingContext_t * pParsingContext;
HTTPResponse_t * pResponse;
size_t length, locOffset;
diff --git a/test/cbmc/proofs/httpParserOnHeadersCompleteCallback/httpParserOnHeadersCompleteCallback_harness.c b/test/cbmc/proofs/httpParserOnHeadersCompleteCallback/httpParserOnHeadersCompleteCallback_harness.c
index 033b72f8..c27879c6 100644
--- a/test/cbmc/proofs/httpParserOnHeadersCompleteCallback/httpParserOnHeadersCompleteCallback_harness.c
+++ b/test/cbmc/proofs/httpParserOnHeadersCompleteCallback/httpParserOnHeadersCompleteCallback_harness.c
@@ -26,14 +26,14 @@
*/
#include "http_cbmc_state.h"
-#include "http_parser.h"
+#include "llhttp.h"
#include "callback_stubs.h"
-int __CPROVER_file_local_core_http_client_c_httpParserOnHeadersCompleteCallback( http_parser * pHttpParser );
+int __CPROVER_file_local_core_http_client_c_httpParserOnHeadersCompleteCallback( llhttp_t * pHttpParser );
void httpParserOnHeadersCompleteCallback_harness()
{
- http_parser * pHttpParser;
+ llhttp_t * pHttpParser;
HTTPParsingContext_t * pParsingContext;
HTTPResponse_t * pResponse;
HTTPClient_ResponseHeaderParsingCallback_t headerParserCallback;
diff --git a/test/cbmc/proofs/httpParserOnMessageBeginCallback/httpParserOnMessageBeginCallback_harness.c b/test/cbmc/proofs/httpParserOnMessageBeginCallback/httpParserOnMessageBeginCallback_harness.c
index c6623440..24853cfd 100644
--- a/test/cbmc/proofs/httpParserOnMessageBeginCallback/httpParserOnMessageBeginCallback_harness.c
+++ b/test/cbmc/proofs/httpParserOnMessageBeginCallback/httpParserOnMessageBeginCallback_harness.c
@@ -26,13 +26,13 @@
*/
#include "http_cbmc_state.h"
-#include "http_parser.h"
+#include "llhttp.h"
-int __CPROVER_file_local_core_http_client_c_httpParserOnMessageBeginCallback( http_parser * pHttpParser );
+int __CPROVER_file_local_core_http_client_c_httpParserOnMessageBeginCallback( llhttp_t * pHttpParser );
void httpParserOnMessageBeginCallback_harness()
{
- http_parser * pHttpParser;
+ llhttp_t * pHttpParser;
pHttpParser = allocateHttpSendParser( NULL );
diff --git a/test/cbmc/proofs/httpParserOnMessageCompleteCallback/httpParserOnMessageCompleteCallback_harness.c b/test/cbmc/proofs/httpParserOnMessageCompleteCallback/httpParserOnMessageCompleteCallback_harness.c
index 6c415fe5..ad7c060d 100644
--- a/test/cbmc/proofs/httpParserOnMessageCompleteCallback/httpParserOnMessageCompleteCallback_harness.c
+++ b/test/cbmc/proofs/httpParserOnMessageCompleteCallback/httpParserOnMessageCompleteCallback_harness.c
@@ -26,13 +26,13 @@
*/
#include "http_cbmc_state.h"
-#include "http_parser.h"
+#include "llhttp.h"
-int __CPROVER_file_local_core_http_client_c_httpParserOnMessageCompleteCallback( http_parser * pHttpParser );
+int __CPROVER_file_local_core_http_client_c_httpParserOnMessageCompleteCallback( llhttp_t * pHttpParser );
void httpParserOnMessageCompleteCallback_harness()
{
- http_parser * pHttpParser;
+ llhttp_t * pHttpParser;
pHttpParser = allocateHttpSendParser( NULL );
diff --git a/test/cbmc/proofs/httpParserOnStatusCallback/httpParserOnStatusCallback_harness.c b/test/cbmc/proofs/httpParserOnStatusCallback/httpParserOnStatusCallback_harness.c
index 551abf49..e1be23ee 100644
--- a/test/cbmc/proofs/httpParserOnStatusCallback/httpParserOnStatusCallback_harness.c
+++ b/test/cbmc/proofs/httpParserOnStatusCallback/httpParserOnStatusCallback_harness.c
@@ -26,16 +26,16 @@
*/
#include "http_cbmc_state.h"
-#include "http_parser.h"
+#include "llhttp.h"
#include "core_http_client.h"
-int __CPROVER_file_local_core_http_client_c_httpParserOnStatusCallback( http_parser * pHttpParser,
+int __CPROVER_file_local_core_http_client_c_httpParserOnStatusCallback( llhttp_t * pHttpParser,
const char * pLoc,
size_t length );
void httpParserOnStatusCallback_harness()
{
- http_parser * pHttpParser;
+ llhttp_t * pHttpParser;
HTTPParsingContext_t * pParsingContext;
HTTPResponse_t * pResponse;
size_t length, locOffset;
diff --git a/test/cbmc/sources/http_cbmc_state.c b/test/cbmc/sources/http_cbmc_state.c
index 224482ab..004e4284 100644
--- a/test/cbmc/sources/http_cbmc_state.c
+++ b/test/cbmc/sources/http_cbmc_state.c
@@ -200,13 +200,13 @@ bool isValidTransportInterface( TransportInterface_t * pTransportInterface )
}
}
-http_parser * allocateHttpSendParser( http_parser * pHttpParser )
+llhttp_t * allocateHttpSendParser( llhttp_t * pHttpParser )
{
HTTPParsingContext_t * pHttpParsingContext;
if( pHttpParser == NULL )
{
- pHttpParser = malloc( sizeof( http_parser ) );
+ pHttpParser = malloc( sizeof( llhttp_t ) );
__CPROVER_assume( pHttpParser != NULL );
}
@@ -251,13 +251,13 @@ bool isValidHttpSendParsingContext( const HTTPParsingContext_t * pHttpParsingCon
return isValid;
}
-http_parser * allocateHttpReadHeaderParser( http_parser * pHttpParser )
+llhttp_t * allocateHttpReadHeaderParser( llhttp_t * pHttpParser )
{
HTTPParsingContext_t * pFindHeaderContext;
if( pHttpParser == NULL )
{
- pHttpParser = malloc( sizeof( http_parser ) );
+ pHttpParser = malloc( sizeof( llhttp_t ) );
__CPROVER_assume( pHttpParser != NULL );
}
diff --git a/test/cbmc/stubs/HTTPClient_ReadHeader_http_parser_execute.c b/test/cbmc/stubs/HTTPClient_ReadHeader_llhttp_execute.c
similarity index 76%
rename from test/cbmc/stubs/HTTPClient_ReadHeader_http_parser_execute.c
rename to test/cbmc/stubs/HTTPClient_ReadHeader_llhttp_execute.c
index 2509464d..55f39e15 100644
--- a/test/cbmc/stubs/HTTPClient_ReadHeader_http_parser_execute.c
+++ b/test/cbmc/stubs/HTTPClient_ReadHeader_llhttp_execute.c
@@ -21,8 +21,8 @@
*/
/**
- * @file HTTPClient_ReadHeader_http_parser_execute.c
- * @brief A stub function for http_parser_execute for coverage of
+ * @file HTTPClient_ReadHeader_llhttp_execute.c
+ * @brief A stub function for llhttp_execute for coverage of
* #HTTPClient_ReadHeader.
*/
@@ -31,33 +31,30 @@
#include "core_http_client.h"
#include "core_http_client_private.h"
-#include "http_parser.h"
+#include "llhttp.h"
/**
* @brief Attains coverage when a variable needs to possibly contain two values.
*/
bool nondet_bool();
-size_t http_parser_execute( http_parser * parser,
- const http_parser_settings * settings,
- const char * data,
- size_t len )
+llhttp_errno_t llhttp_execute( llhttp_t * parser,
+ const char * data,
+ size_t len )
{
char * pValue;
size_t fieldLength, fieldOffset, valueLength, valueOffset;
- unsigned int http_errno;
+ int http_errno;
findHeaderContext_t * pParsingContext;
__CPROVER_assert( parser != NULL,
- "http_parser_execute parser is NULL" );
- __CPROVER_assert( settings != NULL,
- "http_parser_execute settings is NULL" );
+ "llhttp_execute parser is NULL" );
__CPROVER_assert( data != NULL,
- "http_parser_execute data is NULL" );
+ "llhttp_execute data is NULL" );
__CPROVER_assert( len < CBMC_MAX_OBJECT_SIZE,
- "http_parser_execute len >= CBMC_MAX_OBJECT_SIZE" );
+ "llhttp_execute len >= CBMC_MAX_OBJECT_SIZE" );
- parser->http_errno = http_errno;
+ parser->error = http_errno;
__CPROVER_assume( fieldLength <= len );
__CPROVER_assume( fieldOffset < fieldLength );
@@ -87,5 +84,5 @@ size_t http_parser_execute( http_parser * parser,
pParsingContext->pValueLoc = &pValue;
}
- return pParsingContext->fieldFound ? valueLength : 0;
+ return parser->error;
}
diff --git a/test/cbmc/stubs/HTTPClient_Send_http_parser_execute.c b/test/cbmc/stubs/HTTPClient_Send_llhttp_execute.c
similarity index 78%
rename from test/cbmc/stubs/HTTPClient_Send_http_parser_execute.c
rename to test/cbmc/stubs/HTTPClient_Send_llhttp_execute.c
index 183643c2..b7da58f5 100644
--- a/test/cbmc/stubs/HTTPClient_Send_http_parser_execute.c
+++ b/test/cbmc/stubs/HTTPClient_Send_llhttp_execute.c
@@ -21,8 +21,8 @@
*/
/**
- * @file HTTPClient_Send_http_parser_execute.c
- * @brief A stub function for http_parser_execute for coverage of
+ * @file HTTPClient_Send_llhttp_execute.c
+ * @brief A stub function for llhttp_execute for coverage of
* #HTTPClient_Send.
*/
@@ -31,33 +31,33 @@
#include "core_http_client.h"
#include "core_http_client_private.h"
-#include "http_parser.h"
+#include "llhttp.h"
/**
* @brief Attains coverage when a variable needs to possibly contain two values.
*/
bool nondet_bool();
-size_t http_parser_execute( http_parser * parser,
- const http_parser_settings * settings,
- const char * data,
- size_t len )
+llhttp_errno_t llhttp_execute( llhttp_t * parser,
+ const char * data,
+ size_t len )
{
size_t fieldLength, valueLength;
HTTPParsingContext_t * pParsingContext;
+ int http_errno;
__CPROVER_assert( parser != NULL,
- "http_parser_execute parser is NULL" );
- __CPROVER_assert( settings != NULL,
- "http_parser_execute settings is NULL" );
+ "llhttp_execute parser is NULL" );
__CPROVER_assert( data != NULL,
- "http_parser_execute data is NULL" );
+ "llhttp_execute data is NULL" );
__CPROVER_assert( len < CBMC_MAX_OBJECT_SIZE,
- "http_parser_execute len >= CBMC_MAX_OBJECT_SIZE" );
+ "llhttp_execute len >= CBMC_MAX_OBJECT_SIZE" );
__CPROVER_assume( fieldLength <= len );
__CPROVER_assume( valueLength <= len );
+ parser->error = http_errno;
+
pParsingContext = ( HTTPParsingContext_t * ) ( parser->data );
/* Choose whether the parser found the header */
pParsingContext->pLastHeaderField = malloc( fieldLength );
@@ -78,5 +78,5 @@ size_t http_parser_execute( http_parser * parser,
pParsingContext->lastHeaderValueLen = 0U;
}
- return pParsingContext->lastHeaderValueLen;
+ return parser->error;
}
From 0fbca6ddabe898f9191c8af1f0285b000d492caf Mon Sep 17 00:00:00 2001
From: Muneeb Ahmed <54290492+muneebahmed10@users.noreply.github.com>
Date: Thu, 17 Feb 2022 11:27:47 -0700
Subject: [PATCH 3/4] Remove unused variable (#128)
* Remove unused variable
* Void unused status code
---
source/core_http_client.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/source/core_http_client.c b/source/core_http_client.c
index 492bd519..942bc0df 100644
--- a/source/core_http_client.c
+++ b/source/core_http_client.c
@@ -1147,7 +1147,6 @@ static HTTPStatus_t parseHttpResponse( HTTPParsingContext_t * pParsingContext,
{
HTTPStatus_t returnStatus;
const char * parsingStartLoc = NULL;
- llhttp_errno_t parserStatus;
assert( pParsingContext != NULL );
assert( pResponse != NULL );
@@ -1192,8 +1191,8 @@ 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. */
- parserStatus = llhttp_execute( &( pParsingContext->llhttpParser ), parsingStartLoc, parseLen );
+ * reached. The return code is parsed in #processLlhttpError so is not needed. */
+ ( void ) llhttp_execute( &( pParsingContext->llhttpParser ), parsingStartLoc, parseLen );
/* The next location to parse will always be after what has already
* been parsed. */
@@ -2384,7 +2383,6 @@ static HTTPStatus_t findHeaderInResponse( const uint8_t * pBuffer,
llhttp_settings_t parserSettings = { 0 };
llhttp_errno_t parserErrno;
findHeaderContext_t context = { 0 };
- size_t numOfBytesParsed = 0U;
context.pField = pField;
context.fieldLen = fieldLen;
From ebee871ba92b86b1301b04215bcab0d5e6df8c9c Mon Sep 17 00:00:00 2001
From: Gaurav Aggarwal
Date: Wed, 6 Apr 2022 09:20:00 +0000
Subject: [PATCH 4/4] Address review comments
Signed-off-by: Gaurav Aggarwal
---
docs/doxygen/pages.dox | 4 ----
lexicon.txt | 1 -
source/core_http_client.c | 20 ++++++--------------
source/include/core_http_client.h | 11 -----------
source/include/core_http_config_defaults.h | 15 ---------------
test/unit-test/core_http_utest.c | 4 ----
6 files changed, 6 insertions(+), 49 deletions(-)
diff --git a/docs/doxygen/pages.dox b/docs/doxygen/pages.dox
index 4c225127..48ac9c45 100644
--- a/docs/doxygen/pages.dox
+++ b/docs/doxygen/pages.dox
@@ -161,7 +161,6 @@ then the @ref HTTP_DO_NOT_USE_CUSTOM_CONFIG macro must be defined.
@see [Configurations](@ref http_config)
The following macros can be configured for this library:
- - @ref HTTP_MAX_RESPONSE_HEADERS_SIZE_BYTES
- @ref HTTP_USER_AGENT_VALUE
- @ref HTTP_SEND_RETRY_TIMEOUT_MS
- @ref HTTP_RECV_RETRY_TIMEOUT_MS
@@ -243,9 +242,6 @@ config macros defined in core_http_config_defaults.h file.
If a custom config is provided, then HTTP_DO_NOT_USE_CUSTOM_CONFIG should not be
defined.
-@section HTTP_MAX_RESPONSE_HEADERS_SIZE_BYTES
-@copydoc HTTP_MAX_RESPONSE_HEADERS_SIZE_BYTES
-
@section HTTP_USER_AGENT_VALUE
@copydoc HTTP_USER_AGENT_VALUE
diff --git a/lexicon.txt b/lexicon.txt
index 89b9bbfe..3a308b07 100644
--- a/lexicon.txt
+++ b/lexicon.txt
@@ -104,7 +104,6 @@ httpsecurityalertinvalidcharacter
httpsecurityalertinvalidchunkheader
httpsecurityalertinvalidprotocolversion
httpsecurityalertinvalidstatuscode
-httpsecurityalertresponseheaderssizelimitexceeded
httpstatus
httpsuccess
ietf
diff --git a/source/core_http_client.c b/source/core_http_client.c
index 942bc0df..ba27499e 100644
--- a/source/core_http_client.c
+++ b/source/core_http_client.c
@@ -1004,9 +1004,6 @@ static void initializeParsingContextForFirstResponse( HTTPParsingContext_t * pPa
/* Initialize the third-party HTTP parser to parse responses. */
llhttp_init( &( pParsingContext->llhttpParser ), HTTP_RESPONSE, &( pParsingContext->llhttpSettings ) );
- /* The parser will return an error if this header size limit is exceeded. */
- /*http_parser_set_max_header_size( HTTP_MAX_RESPONSE_HEADERS_SIZE_BYTES ); */
-
/* No response has been parsed yet. */
pParsingContext->state = HTTP_PARSING_NONE;
@@ -1130,7 +1127,7 @@ static HTTPStatus_t processLlhttpError( const llhttp_t * pHttpParser )
break;
}
- /* Errors with HPE_CB_ prepending are manual returns of non-zero in the
+ /* Errors with HPE_CB_ prepended are manual returns of non-zero in the
* response parsing callback. */
LogDebug( ( "llhttp errno description: %s %s",
llhttp_errno_name( llhttp_get_errno( pHttpParser ) ),
@@ -2394,7 +2391,7 @@ static HTTPStatus_t findHeaderInResponse( const uint8_t * pBuffer,
/* The intention here to define callbacks just for searching the headers. We will
* need to create a private context in llhttp->data that has the field and
* value to update and pass back. */
- llhttp_settings_init( &( parserSettings ) );
+ llhttp_settings_init( &parserSettings );
parserSettings.on_header_field = findHeaderFieldParserCallback;
parserSettings.on_header_value = findHeaderValueParserCallback;
parserSettings.on_headers_complete = findHeaderOnHeaderCompleteCallback;
@@ -2403,7 +2400,7 @@ static HTTPStatus_t findHeaderInResponse( const uint8_t * pBuffer,
/* Set the context for the parser. */
parser.data = &context;
- /* Start parsing for the header! */
+ /* Search for the desired header. */
parserErrno = llhttp_execute( &parser, ( const char * ) pBuffer, bufferLen );
if( context.fieldFound == 0U )
@@ -2446,8 +2443,8 @@ static HTTPStatus_t findHeaderInResponse( const uint8_t * pBuffer,
}
/* 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 llhttp.error to be "USER". */
+ * value of the on_header_value callback should set the llhttp.error to
+ * HPE_USER. */
if( ( returnStatus == HTTPSuccess ) &&
( parserErrno != HPE_USER ) )
{
@@ -2459,8 +2456,7 @@ static HTTPStatus_t findHeaderInResponse( const uint8_t * pBuffer,
}
/* If header was not found, then the "on_header_complete" callback is
- * expected to be called which should cause the llhttp.error to be
- * "OK" */
+ * expected to be called which should set the llhttp.error to HPE_OK. */
else if( ( returnStatus == HTTPHeaderNotFound ) &&
( parserErrno != HPE_OK ) )
{
@@ -2575,10 +2571,6 @@ const char * HTTPClient_strerror( HTTPStatus_t status )
str = "HTTPInsufficientMemory";
break;
- case HTTPSecurityAlertResponseHeadersSizeLimitExceeded:
- str = "HTTPSecurityAlertResponseHeadersSizeLimitExceeded";
- break;
-
case HTTPSecurityAlertExtraneousResponseData:
str = "HTTPSecurityAlertExtraneousResponseData";
break;
diff --git a/source/include/core_http_client.h b/source/include/core_http_client.h
index 2f005715..6ccb05e7 100644
--- a/source/include/core_http_client.h
+++ b/source/include/core_http_client.h
@@ -223,15 +223,6 @@ typedef enum HTTPStatus
*/
HTTPInsufficientMemory,
- /**
- * @brief The server sent more headers than the configured
- * #HTTP_MAX_RESPONSE_HEADERS_SIZE_BYTES.
- *
- * Functions that may return this value:
- * - None
- */
- HTTPSecurityAlertResponseHeadersSizeLimitExceeded,
-
/**
* @brief A response contained the "Connection: close" header, but there
* was more data at the end of the complete message.
@@ -741,7 +732,6 @@ HTTPStatus_t HTTPClient_AddRangeHeader( HTTPRequestHeaders_t * pRequestHeaders,
*
* The application should close the connection with the server if any of the
* following errors are returned:
- * - #HTTPSecurityAlertResponseHeadersSizeLimitExceeded
* - #HTTPSecurityAlertExtraneousResponseData
* - #HTTPSecurityAlertInvalidChunkHeader
* - #HTTPSecurityAlertInvalidProtocolVersion
@@ -773,7 +763,6 @@ HTTPStatus_t HTTPClient_AddRangeHeader( HTTPRequestHeaders_t * pRequestHeaders,
* or extra headers could not be sent in the request.)
* - #HTTPParserInternalError (Internal parsing error.)\n\n
* Security alerts are listed below, please see #HTTPStatus_t for more information:
- * - #HTTPSecurityAlertResponseHeadersSizeLimitExceeded
* - #HTTPSecurityAlertExtraneousResponseData
* - #HTTPSecurityAlertInvalidChunkHeader
* - #HTTPSecurityAlertInvalidProtocolVersion
diff --git a/source/include/core_http_config_defaults.h b/source/include/core_http_config_defaults.h
index eb14528f..c03ce12e 100644
--- a/source/include/core_http_config_defaults.h
+++ b/source/include/core_http_config_defaults.h
@@ -41,21 +41,6 @@
#endif
/* *INDENT-ON* */
-/**
- * @brief Maximum size, in bytes, of headers allowed from the server.
- *
- * If the total size in bytes of the headers received from the server exceeds
- * this configuration, then the status code
- * #HTTPSecurityAlertResponseHeadersSizeLimitExceeded is returned from
- * #HTTPClient_Send.
- *
- * Possible values: Any positive 32 bit integer.
- * Default value: `2048`
- */
-#ifndef HTTP_MAX_RESPONSE_HEADERS_SIZE_BYTES
- #define HTTP_MAX_RESPONSE_HEADERS_SIZE_BYTES 2048U
-#endif
-
/**
* @brief The HTTP header "User-Agent" value.
*
diff --git a/test/unit-test/core_http_utest.c b/test/unit-test/core_http_utest.c
index 781f6820..d2cc932a 100644
--- a/test/unit-test/core_http_utest.c
+++ b/test/unit-test/core_http_utest.c
@@ -1559,10 +1559,6 @@ void test_HTTPClient_strerror( void )
str = HTTPClient_strerror( status );
TEST_ASSERT_EQUAL_STRING( "HTTPInsufficientMemory", str );
- status = HTTPSecurityAlertResponseHeadersSizeLimitExceeded;
- str = HTTPClient_strerror( status );
- TEST_ASSERT_EQUAL_STRING( "HTTPSecurityAlertResponseHeadersSizeLimitExceeded", str );
-
status = HTTPSecurityAlertExtraneousResponseData;
str = HTTPClient_strerror( status );
TEST_ASSERT_EQUAL_STRING( "HTTPSecurityAlertExtraneousResponseData", str );