Skip to content

Commit

Permalink
lib: s/http_parser/llhttp/
Browse files Browse the repository at this point in the history
The NodeJS project replaced http_parser with llhttp, which is safer, faster,
and easier to maintain than its predecessor.  The license is MIT for both
http_parser and llhttp.  This commit makes the switch for this project, but
depends on a small patch [1] to add the RTSP+RAOP verbs and allow the RTSP
protocol type, & will hopefully be pulled upstream.

Generated code based on llhttp v2.1.3 + patch.

[1] nodejs/llhttp#66
  • Loading branch information
pallas committed Oct 6, 2020
1 parent 23f12cf commit 8d1025a
Show file tree
Hide file tree
Showing 10 changed files with 15,187 additions and 3,049 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ set (RENDERER_FLAGS "")
add_subdirectory(lib/curve25519)
add_subdirectory(lib/ed25519)
add_subdirectory(lib/playfair)
add_subdirectory(lib/llhttp)
add_subdirectory(lib)
add_subdirectory(renderers)

Expand Down
3 changes: 2 additions & 1 deletion lib/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.4.1)
include_directories( curve25519 ed25519 playfair )
include_directories( curve25519 ed25519 playfair llhttp )

aux_source_directory(. play_src)
set(DIR_SRCS ${play_src})
Expand All @@ -16,6 +16,7 @@ target_link_libraries( airplay
curve25519
ed25519
playfair
llhttp
${LIBPLIST} )

if( UNIX AND NOT APPLE )
Expand Down
2,577 changes: 0 additions & 2,577 deletions lib/http_parser.c

This file was deleted.

455 changes: 0 additions & 455 deletions lib/http_parser.h

This file was deleted.

33 changes: 17 additions & 16 deletions lib/http_request.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@
#include <assert.h>

#include "http_request.h"
#include "http_parser.h"
#include "llhttp/llhttp.h"

struct http_request_s {
http_parser parser;
http_parser_settings parser_settings;
llhttp_t parser;
llhttp_settings_t parser_settings;

const char *method;
char *url;
Expand All @@ -37,7 +37,7 @@ struct http_request_s {
};

static int
on_url(http_parser *parser, const char *at, size_t length)
on_url(llhttp_t *parser, const char *at, size_t length)
{
http_request_t *request = parser->data;
int urllen = request->url ? strlen(request->url) : 0;
Expand All @@ -51,7 +51,7 @@ on_url(http_parser *parser, const char *at, size_t length)
}

static int
on_header_field(http_parser *parser, const char *at, size_t length)
on_header_field(llhttp_t *parser, const char *at, size_t length)
{
http_request_t *request = parser->data;

Expand Down Expand Up @@ -86,7 +86,7 @@ on_header_field(http_parser *parser, const char *at, size_t length)
}

static int
on_header_value(http_parser *parser, const char *at, size_t length)
on_header_value(llhttp_t *parser, const char *at, size_t length)
{
http_request_t *request = parser->data;

Expand All @@ -111,7 +111,7 @@ on_header_value(http_parser *parser, const char *at, size_t length)
}

static int
on_body(http_parser *parser, const char *at, size_t length)
on_body(llhttp_t *parser, const char *at, size_t length)
{
http_request_t *request = parser->data;

Expand All @@ -124,11 +124,11 @@ on_body(http_parser *parser, const char *at, size_t length)
}

static int
on_message_complete(http_parser *parser)
on_message_complete(llhttp_t *parser)
{
http_request_t *request = parser->data;

request->method = http_method_str(request->parser.method);
request->method = llhttp_method_name(request->parser.method);
request->complete = 1;
return 0;
}
Expand All @@ -142,15 +142,17 @@ http_request_init(void)
if (!request) {
return NULL;
}
http_parser_init(&request->parser, HTTP_REQUEST);
request->parser.data = request;

llhttp_settings_init(&request->parser_settings);
request->parser_settings.on_url = &on_url;
request->parser_settings.on_header_field = &on_header_field;
request->parser_settings.on_header_value = &on_header_value;
request->parser_settings.on_body = &on_body;
request->parser_settings.on_message_complete = &on_message_complete;

llhttp_init(&request->parser, HTTP_REQUEST, &request->parser_settings);
request->parser.data = request;

return request;
}

Expand All @@ -177,8 +179,7 @@ http_request_add_data(http_request_t *request, const char *data, int datalen)

assert(request);

ret = http_parser_execute(&request->parser,
&request->parser_settings,
ret = llhttp_execute(&request->parser,
data, datalen);
return ret;
}
Expand All @@ -194,21 +195,21 @@ int
http_request_has_error(http_request_t *request)
{
assert(request);
return (HTTP_PARSER_ERRNO(&request->parser) != HPE_OK);
return (llhttp_get_errno(&request->parser) != HPE_OK);
}

const char *
http_request_get_error_name(http_request_t *request)
{
assert(request);
return http_errno_name(HTTP_PARSER_ERRNO(&request->parser));
return llhttp_errno_name(llhttp_get_errno(&request->parser));
}

const char *
http_request_get_error_description(http_request_t *request)
{
assert(request);
return http_errno_description(HTTP_PARSER_ERRNO(&request->parser));
return llhttp_get_error_reason(&request->parser);
}

const char *
Expand Down
7 changes: 7 additions & 0 deletions lib/llhttp/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
cmake_minimum_required(VERSION 3.4.1)
aux_source_directory(. llhttp_src)
set(DIR_SRCS ${llhttp_src})
include_directories(.)
add_library( llhttp
STATIC
${DIR_SRCS})
224 changes: 224 additions & 0 deletions lib/llhttp/api.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,224 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "llhttp.h"

#define CALLBACK_MAYBE(PARSER, NAME, ...) \
do { \
llhttp_settings_t* settings; \
settings = (llhttp_settings_t*) (PARSER)->settings; \
if (settings == NULL || settings->NAME == NULL) { \
err = 0; \
break; \
} \
err = settings->NAME(__VA_ARGS__); \
} while (0)

void llhttp_init(llhttp_t* parser, llhttp_type_t type,
const llhttp_settings_t* settings) {
llhttp__internal_init(parser);

parser->type = type;
parser->settings = (void*) settings;
}


llhttp_errno_t llhttp_execute(llhttp_t* parser, const char* data, size_t len) {
return llhttp__internal_execute(parser, data, data + len);
}


void llhttp_settings_init(llhttp_settings_t* settings) {
memset(settings, 0, sizeof(*settings));
}


llhttp_errno_t llhttp_finish(llhttp_t* parser) {
int err;

/* We're in an error state. Don't bother doing anything. */
if (parser->error != 0) {
return 0;
}

switch (parser->finish) {
case HTTP_FINISH_SAFE_WITH_CB:
CALLBACK_MAYBE(parser, on_message_complete, parser);
if (err != HPE_OK) return err;

/* FALLTHROUGH */
case HTTP_FINISH_SAFE:
return HPE_OK;
case HTTP_FINISH_UNSAFE:
parser->reason = "Invalid EOF state";
return HPE_INVALID_EOF_STATE;
default:
abort();
}
}


void llhttp_pause(llhttp_t* parser) {
if (parser->error != HPE_OK) {
return;
}

parser->error = HPE_PAUSED;
parser->reason = "Paused";
}


void llhttp_resume(llhttp_t* parser) {
if (parser->error != HPE_PAUSED) {
return;
}

parser->error = 0;
}


void llhttp_resume_after_upgrade(llhttp_t* parser) {
if (parser->error != HPE_PAUSED_UPGRADE) {
return;
}

parser->error = 0;
}


llhttp_errno_t llhttp_get_errno(const llhttp_t* parser) {
return parser->error;
}


const char* llhttp_get_error_reason(const llhttp_t* parser) {
return parser->reason;
}


void llhttp_set_error_reason(llhttp_t* parser, const char* reason) {
parser->reason = reason;
}


const char* llhttp_get_error_pos(const llhttp_t* parser) {
return parser->error_pos;
}


const char* llhttp_errno_name(llhttp_errno_t err) {
#define HTTP_ERRNO_GEN(CODE, NAME, _) case HPE_##NAME: return "HPE_" #NAME;
switch (err) {
HTTP_ERRNO_MAP(HTTP_ERRNO_GEN)
default: abort();
}
#undef HTTP_ERRNO_GEN
}


const char* llhttp_method_name(llhttp_method_t method) {
#define HTTP_METHOD_GEN(NUM, NAME, STRING) case HTTP_##NAME: return #STRING;
switch (method) {
HTTP_METHOD_MAP(HTTP_METHOD_GEN)
default: abort();
}
#undef HTTP_METHOD_GEN
}


void llhttp_set_lenient(llhttp_t* parser, int enabled) {
if (enabled) {
parser->flags |= F_LENIENT;
} else {
parser->flags &= ~F_LENIENT;
}
}


/* Callbacks */


int llhttp__on_message_begin(llhttp_t* s, const char* p, const char* endp) {
int err;
CALLBACK_MAYBE(s, on_message_begin, s);
return err;
}


int llhttp__on_url(llhttp_t* s, const char* p, const char* endp) {
int err;
CALLBACK_MAYBE(s, on_url, s, p, endp - p);
return err;
}


int llhttp__on_status(llhttp_t* s, const char* p, const char* endp) {
int err;
CALLBACK_MAYBE(s, on_status, s, p, endp - p);
return err;
}


int llhttp__on_header_field(llhttp_t* s, const char* p, const char* endp) {
int err;
CALLBACK_MAYBE(s, on_header_field, s, p, endp - p);
return err;
}


int llhttp__on_header_value(llhttp_t* s, const char* p, const char* endp) {
int err;
CALLBACK_MAYBE(s, on_header_value, s, p, endp - p);
return err;
}


int llhttp__on_headers_complete(llhttp_t* s, const char* p, const char* endp) {
int err;
CALLBACK_MAYBE(s, on_headers_complete, s);
return err;
}


int llhttp__on_message_complete(llhttp_t* s, const char* p, const char* endp) {
int err;
CALLBACK_MAYBE(s, on_message_complete, s);
return err;
}


int llhttp__on_body(llhttp_t* s, const char* p, const char* endp) {
int err;
CALLBACK_MAYBE(s, on_body, s, p, endp - p);
return err;
}


int llhttp__on_chunk_header(llhttp_t* s, const char* p, const char* endp) {
int err;
CALLBACK_MAYBE(s, on_chunk_header, s);
return err;
}


int llhttp__on_chunk_complete(llhttp_t* s, const char* p, const char* endp) {
int err;
CALLBACK_MAYBE(s, on_chunk_complete, s);
return err;
}


/* Private */


void llhttp__debug(llhttp_t* s, const char* p, const char* endp,
const char* msg) {
if (p == endp) {
fprintf(stderr, "p=%p type=%d flags=%02x next=null debug=%s\n", s, s->type,
s->flags, msg);
} else {
fprintf(stderr, "p=%p type=%d flags=%02x next=%02x debug=%s\n", s,
s->type, s->flags, *p, msg);
}
}
Loading

0 comments on commit 8d1025a

Please sign in to comment.