Skip to content

Commit

Permalink
Fix issue introduced in http-parser -> llhttp conversion
Browse files Browse the repository at this point in the history
http_parser_execute() returns the number of parsed bytes, while
llhttp_execute() returns an error code.

Signed-off-by: Sergio Correia <[email protected]>
  • Loading branch information
sergio-correia committed Feb 12, 2024
1 parent 4b7656b commit 819970c
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 6 deletions.
6 changes: 2 additions & 4 deletions src/http.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,9 @@ typedef llhttp_status_t http_status_t;
typedef llhttp_settings_t http_settings_t;
typedef llhttp_t http_parser_t;
#define tang_http_parser_init(parser, settings) llhttp_init(parser, HTTP_REQUEST, settings)
#define tang_http_parser_execute(parser, settings, req, rcvd) llhttp_execute(parser, req, rcvd)
#define tang_http_parser_errno(parser) parser.error
#define tang_http_errno_description(parser, errno) llhttp_get_error_reason(parser)

#define tang_http_parser_resume(parser) llhttp_resume(parser)
#else
/* Legacy http-parser. */
#include <http_parser.h>
Expand All @@ -44,10 +43,9 @@ typedef http_parser_settings http_settings_t;
typedef struct http_parser http_parser_t;

#define tang_http_parser_init(parser, settings) http_parser_init(parser, HTTP_REQUEST)
#define tang_http_parser_execute(parser, settings, req, rcvd) http_parser_execute(parser, settings, req, rcvd)
#define tang_http_parser_errno(parser) parser.http_errno
#define tang_http_errno_description(parser, errno) http_errno_description(errno)

#define tang_http_parser_resume(parser) http_parser_pause(parser, 0)
#endif /* USE_LLHTTP */

struct http_dispatch {
Expand Down
48 changes: 46 additions & 2 deletions src/tangd.c
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,44 @@ static struct http_dispatch s_dispatch[] = {

#define DEFAULT_PORT 9090

static size_t
tang_http_parser_execute(http_parser_t *parser, const char* data, size_t len)
{
#ifdef USE_LLHTTP
llhttp_errno_t error;
size_t parsed_len;

/*
* Unlike http_parser, which returns the number of parsed
* bytes in the _execute() call, llhttp returns an error
* code.
*/

if (data == NULL || len == 0) {
error = llhttp_finish(parser);
} else {
error = llhttp_execute(parser, data, len);
}

parsed_len = len;
/*
* Adjust number of parsed bytes in case of error.
*/
if (error != HPE_OK) {
parsed_len = llhttp_get_error_pos(parser) - data;

/* This isn't a real pause, just a way to stop parsing early. */
if (error == HPE_PAUSED_UPGRADE) {
llhttp_resume_after_upgrade(parser);
}
}

return parsed_len;
#else
return http_parser_execute(parser, &http_settings, data, len);
#endif
}

static int
process_request(const char *jwkdir, int in_fileno)
{
Expand Down Expand Up @@ -229,8 +267,14 @@ process_request(const char *jwkdir, int in_fileno)

rcvd += r;

r = tang_http_parser_execute(&parser, &http_settings, req, rcvd);
if (tang_http_parser_errno(parser) != 0) {
r = tang_http_parser_execute(&parser, req, rcvd);
switch (tang_http_parser_errno(parser)) {
case HPE_OK:
break;
case HPE_PAUSED:
tang_http_parser_resume(&parser);
break;
default:
fprintf(stderr, "HTTP Parsing Error: %s\n",
tang_http_errno_description(&parser, tang_http_parser_errno(parser)));
return EXIT_SUCCESS;
Expand Down

0 comments on commit 819970c

Please sign in to comment.