Skip to content

Commit 63b5de2

Browse files
Swap http-parse to llhttp (#56)
Replaces the underlying HTTP parser with llhttp as http-parser is no longer actively maintained. However we still have http-parser to power our URL parsing function at the moment. Co-authored-by: Fantix King <[email protected]>
1 parent 9340d32 commit 63b5de2

File tree

13 files changed

+409
-292
lines changed

13 files changed

+409
-292
lines changed

.github/workflows/tests.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,14 @@ jobs:
4141
__version__\s*=\s*(?:['"])([[:PEP440:]])(?:['"])
4242
4343
- name: Set up Python ${{ matrix.python-version }}
44-
uses: actions/setup-python@v1
44+
uses: actions/setup-python@v2
4545
if: steps.release.outputs.version == 0
4646
with:
4747
python-version: ${{ matrix.python-version }}
4848

4949
- name: Test
5050
if: steps.release.outputs.version == 0
5151
run: |
52+
pip install wheel
5253
pip install -e .[test]
5354
python setup.py test

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,5 @@ __pycache__/
2929
/.pytest_cache
3030
/.mypy_cache
3131
/.vscode
32+
.eggs
33+
.venv

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
11
[submodule "vendor/http-parser"]
22
path = vendor/http-parser
33
url = https://github.com/nodejs/http-parser.git
4+
[submodule "vendor/llhttp"]
5+
path = vendor/llhttp
6+
url = https://github.com/nodejs/llhttp.git

Makefile

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,16 @@ release: compile test
1313
python3 setup.py sdist upload
1414

1515

16-
test:
17-
python3 setup.py test
16+
test: compile
17+
python3 -m unittest -v
1818

1919
clean:
2020
find $(ROOT)/httptools/parser -name '*.c' | xargs rm -f
2121
find $(ROOT)/httptools/parser -name '*.html' | xargs rm -f
2222

23-
distclean:
23+
distclean: clean
2424
git --git-dir="$(ROOT)/vendor/http-parser/.git" clean -dfx
25-
find $(ROOT)/httptools/parser -name '*.c' | xargs rm -f
26-
find $(ROOT)/httptools/parser -name '*.html' | xargs rm -f
25+
git --git-dir="$(ROOT)/vendor/llhttp/.git" clean -dfx
2726

2827

2928
testinstalled:

README.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,11 @@ The package is available on PyPI: `pip install httptools`.
88
# APIs
99

1010
httptools contains two classes `httptools.HttpRequestParser`,
11-
`httptools.HttpResponseParser` and a function for parsing URLs
12-
`httptools.parse_url`. See unittests for examples.
11+
`httptools.HttpResponseParser` (fulfilled through
12+
[llhttp](https://github.com/nodejs/llhttp)) and a function for
13+
parsing URLs `httptools.parse_url` (through
14+
[http-parse](https://github.com/nodejs/http-parser) for now).
15+
See unittests for examples.
1316

1417

1518
```python

httptools/parser/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from .parser import * # NoQA
22
from .errors import * # NoQA
3+
from .url_parser import * # NoQA
34

4-
__all__ = parser.__all__ + errors.__all__ # NoQA
5+
__all__ = parser.__all__ + errors.__all__ + url_parser.__all__ # NoQA

httptools/parser/cparser.pxd

Lines changed: 136 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -1,139 +1,156 @@
1-
from libc.stdint cimport uint16_t, uint32_t, uint64_t
1+
from libc.stdint cimport int32_t, uint8_t, uint16_t, uint64_t
22

33

4-
cdef extern from "../../vendor/http-parser/http_parser.h":
5-
ctypedef int (*http_data_cb) (http_parser*,
4+
cdef extern from "llhttp.h":
5+
struct llhttp__internal_s:
6+
int32_t _index
7+
void *_span_pos0
8+
void *_span_cb0
9+
int32_t error
10+
const char *reason
11+
const char *error_pos
12+
void *data
13+
void *_current
14+
uint64_t content_length
15+
uint8_t type
16+
uint8_t method
17+
uint8_t http_major
18+
uint8_t http_minor
19+
uint8_t header_state
20+
uint16_t flags
21+
uint8_t upgrade
22+
uint16_t status_code
23+
uint8_t finish
24+
void *settings
25+
ctypedef llhttp__internal_s llhttp__internal_t
26+
ctypedef llhttp__internal_t llhttp_t
27+
28+
ctypedef int (*llhttp_data_cb) (llhttp_t*,
629
const char *at,
730
size_t length) except -1
831

9-
ctypedef int (*http_cb) (http_parser*) except -1
10-
11-
struct http_parser:
12-
unsigned int type
13-
unsigned int flags
14-
unsigned int state
15-
unsigned int header_state
16-
unsigned int index
17-
18-
uint32_t nread
19-
uint64_t content_length
20-
21-
unsigned short http_major
22-
unsigned short http_minor
23-
unsigned int status_code
24-
unsigned int method
25-
unsigned int http_errno
26-
27-
unsigned int upgrade
28-
29-
void *data
30-
31-
struct http_parser_settings:
32-
http_cb on_message_begin
33-
http_data_cb on_url
34-
http_data_cb on_status
35-
http_data_cb on_header_field
36-
http_data_cb on_header_value
37-
http_cb on_headers_complete
38-
http_data_cb on_body
39-
http_cb on_message_complete
40-
http_cb on_chunk_header
41-
http_cb on_chunk_complete
42-
43-
enum http_parser_type:
32+
ctypedef int (*llhttp_cb) (llhttp_t*) except -1
33+
34+
struct llhttp_settings_s:
35+
llhttp_cb on_message_begin
36+
llhttp_data_cb on_url
37+
llhttp_data_cb on_status
38+
llhttp_data_cb on_header_field
39+
llhttp_data_cb on_header_value
40+
llhttp_cb on_headers_complete
41+
llhttp_data_cb on_body
42+
llhttp_cb on_message_complete
43+
llhttp_cb on_chunk_header
44+
llhttp_cb on_chunk_complete
45+
ctypedef llhttp_settings_s llhttp_settings_t
46+
47+
enum llhttp_type:
48+
HTTP_BOTH,
4449
HTTP_REQUEST,
45-
HTTP_RESPONSE,
46-
HTTP_BOTH
50+
HTTP_RESPONSE
51+
ctypedef llhttp_type llhttp_type_t
4752

48-
enum http_errno:
53+
enum llhttp_errno:
4954
HPE_OK,
50-
HPE_CB_message_begin,
51-
HPE_CB_url,
52-
HPE_CB_header_field,
53-
HPE_CB_header_value,
54-
HPE_CB_headers_complete,
55-
HPE_CB_body,
56-
HPE_CB_message_complete,
57-
HPE_CB_status,
58-
HPE_CB_chunk_header,
59-
HPE_CB_chunk_complete,
60-
HPE_INVALID_EOF_STATE,
61-
HPE_HEADER_OVERFLOW,
55+
HPE_INTERNAL,
56+
HPE_STRICT,
57+
HPE_LF_EXPECTED,
58+
HPE_UNEXPECTED_CONTENT_LENGTH,
6259
HPE_CLOSED_CONNECTION,
63-
HPE_INVALID_VERSION,
64-
HPE_INVALID_STATUS,
6560
HPE_INVALID_METHOD,
6661
HPE_INVALID_URL,
67-
HPE_INVALID_HOST,
68-
HPE_INVALID_PORT,
69-
HPE_INVALID_PATH,
70-
HPE_INVALID_QUERY_STRING,
71-
HPE_INVALID_FRAGMENT,
72-
HPE_LF_EXPECTED,
62+
HPE_INVALID_CONSTANT,
63+
HPE_INVALID_VERSION,
7364
HPE_INVALID_HEADER_TOKEN,
7465
HPE_INVALID_CONTENT_LENGTH,
7566
HPE_INVALID_CHUNK_SIZE,
76-
HPE_INVALID_CONSTANT,
77-
HPE_INVALID_INTERNAL_STATE,
78-
HPE_STRICT,
67+
HPE_INVALID_STATUS,
68+
HPE_INVALID_EOF_STATE,
69+
HPE_INVALID_TRANSFER_ENCODING,
70+
HPE_CB_MESSAGE_BEGIN,
71+
HPE_CB_HEADERS_COMPLETE,
72+
HPE_CB_MESSAGE_COMPLETE,
73+
HPE_CB_CHUNK_HEADER,
74+
HPE_CB_CHUNK_COMPLETE,
7975
HPE_PAUSED,
80-
HPE_UNKNOWN
76+
HPE_PAUSED_UPGRADE,
77+
HPE_USER
78+
ctypedef llhttp_errno llhttp_errno_t
8179

82-
enum flags:
83-
F_CHUNKED,
80+
enum llhttp_flags:
8481
F_CONNECTION_KEEP_ALIVE,
8582
F_CONNECTION_CLOSE,
8683
F_CONNECTION_UPGRADE,
87-
F_TRAILING,
84+
F_CHUNKED,
8885
F_UPGRADE,
89-
F_SKIPBODY
90-
91-
enum http_method:
92-
DELETE, GET, HEAD, POST, PUT, CONNECT, OPTIONS, TRACE, COPY,
93-
LOCK, MKCOL, MOVE, PROPFIND, PROPPATCH, SEARCH, UNLOCK, BIND,
94-
REBIND, UNBIND, ACL, REPORT, MKACTIVITY, CHECKOUT, MERGE,
95-
MSEARCH, NOTIFY, SUBSCRIBE, UNSUBSCRIBE, PATCH, PURGE, MKCALENDAR,
96-
LINK, UNLINK
97-
98-
void http_parser_init(http_parser *parser, http_parser_type type)
99-
100-
size_t http_parser_execute(http_parser *parser,
101-
const http_parser_settings *settings,
102-
const char *data,
103-
size_t len)
104-
105-
int http_should_keep_alive(const http_parser *parser)
106-
107-
void http_parser_settings_init(http_parser_settings *settings)
108-
109-
const char *http_errno_name(http_errno err)
110-
const char *http_errno_description(http_errno err)
111-
const char *http_method_str(http_method m)
112-
113-
# URL Parser
114-
115-
enum http_parser_url_fields:
116-
UF_SCHEMA = 0,
117-
UF_HOST = 1,
118-
UF_PORT = 2,
119-
UF_PATH = 3,
120-
UF_QUERY = 4,
121-
UF_FRAGMENT = 5,
122-
UF_USERINFO = 6,
123-
UF_MAX = 7
124-
125-
struct http_parser_url_field_data:
126-
uint16_t off
127-
uint16_t len
128-
129-
struct http_parser_url:
130-
uint16_t field_set
131-
uint16_t port
132-
http_parser_url_field_data[<int>UF_MAX] field_data
133-
134-
void http_parser_url_init(http_parser_url *u)
135-
136-
int http_parser_parse_url(const char *buf,
137-
size_t buflen,
138-
int is_connect,
139-
http_parser_url *u)
86+
F_CONTENT_LENGTH,
87+
F_SKIPBODY,
88+
F_TRAILING,
89+
F_LENIENT,
90+
F_TRANSFER_ENCODING
91+
ctypedef llhttp_flags llhttp_flags_t
92+
93+
enum llhttp_method:
94+
HTTP_DELETE,
95+
HTTP_GET,
96+
HTTP_HEAD,
97+
HTTP_POST,
98+
HTTP_PUT,
99+
HTTP_CONNECT,
100+
HTTP_OPTIONS,
101+
HTTP_TRACE,
102+
HTTP_COPY,
103+
HTTP_LOCK,
104+
HTTP_MKCOL,
105+
HTTP_MOVE,
106+
HTTP_PROPFIND,
107+
HTTP_PROPPATCH,
108+
HTTP_SEARCH,
109+
HTTP_UNLOCK,
110+
HTTP_BIND,
111+
HTTP_REBIND,
112+
HTTP_UNBIND,
113+
HTTP_ACL,
114+
HTTP_REPORT,
115+
HTTP_MKACTIVITY,
116+
HTTP_CHECKOUT,
117+
HTTP_MERGE,
118+
HTTP_MSEARCH,
119+
HTTP_NOTIFY,
120+
HTTP_SUBSCRIBE,
121+
HTTP_UNSUBSCRIBE,
122+
HTTP_PATCH,
123+
HTTP_PURGE,
124+
HTTP_MKCALENDAR,
125+
HTTP_LINK,
126+
HTTP_UNLINK,
127+
HTTP_SOURCE,
128+
HTTP_PRI,
129+
HTTP_DESCRIBE,
130+
HTTP_ANNOUNCE,
131+
HTTP_SETUP,
132+
HTTP_PLAY,
133+
HTTP_PAUSE,
134+
HTTP_TEARDOWN,
135+
HTTP_GET_PARAMETER,
136+
HTTP_SET_PARAMETER,
137+
HTTP_REDIRECT,
138+
HTTP_RECORD,
139+
HTTP_FLUSH
140+
ctypedef llhttp_method llhttp_method_t
141+
142+
void llhttp_init(llhttp_t* parser, llhttp_type_t type, const llhttp_settings_t* settings)
143+
144+
void llhttp_settings_init(llhttp_settings_t* settings)
145+
146+
llhttp_errno_t llhttp_execute(llhttp_t* parser, const char* data, size_t len)
147+
148+
void llhttp_resume_after_upgrade(llhttp_t* parser)
149+
150+
int llhttp_should_keep_alive(const llhttp_t* parser)
151+
152+
const char* llhttp_get_error_pos(const llhttp_t* parser)
153+
const char* llhttp_get_error_reason(const llhttp_t* parser)
154+
const char* llhttp_method_name(llhttp_method_t method)
155+
156+
void llhttp_set_error_reason(llhttp_t* parser, const char* reason);

0 commit comments

Comments
 (0)