pyllhttp
Python wrapper for llhttp
A fork of llhttp compatible with subinterpreters
======
A simple Python wrapper around llhttp, the HTTP parser for Node.js.
Install
pyllhttp via PyPI, or pip install pyllhttp
Usage
import llhttp
from pprint import pprint
pprint({"version": llhttp.version})
class request_parser(llhttp.Request):
headers = {}
url = b''
current_header_field = None
current_header_value = None
def on_message_begin(self):
print(f"MESSAGE BEGIN")
def on_url(self, url):
self.url += url
self.pause()
def on_url_complete(self):
print(f"URL {self.url}")
def on_header_field(self, field):
assert self.current_header_value is None
if self.current_header_field is None:
self.current_header_field = bytearray(field)
else:
self.current_header_field += field
def on_header_field_complete(self):
self.current_header_field = self.current_header_field.decode('iso-8859-1').lower()
assert self.current_header_field not in self.headers
def on_header_value(self, value):
assert self.current_header_field is not None
if self.current_header_value is None:
self.current_header_value = bytearray(value)
else:
self.current_header_value += value
def on_header_value_complete(self):
assert self.current_header_field is not None
self.current_header_value = bytes(self.current_header_value)
print(f"HEADER {self.current_header_field}: {self.current_header_value}")
self.headers[self.current_header_field] = self.current_header_value
self.current_header_field = None
self.current_header_value = None
def on_headers_complete(self):
assert self.current_header_field is None
assert self.current_header_value is None
def on_message_complete(self):
print("MESSAGE COMPLETE")
parser = request_parser()
assert parser.lenient_headers is not True
parser.lenient_headers = True
parser.reset()
assert parser.lenient_headers is True
buffer = b"GET /test HTTP/1.1\r\nlOl:wut\r\nOH: hai\r\n\r\n"
while buffer:
consumed = parser.execute(buffer[:2])
buffer = buffer[consumed:]
if parser.is_paused:
print("UNPAUSING")
parser.unpause()
parser.finish()
pprint({
"method": parser.method,
"url": parser.url,
"version": f"{parser.major}.{parser.minor}",
"headers": parser.headers,
})
{'version': '3.0.0'}
MESSAGE BEGIN
UNPAUSING
UNPAUSING
UNPAUSING
URL b'/test'
HEADER lol: b'wut'
HEADER oh: b'hai'
MESSAGE COMPLETE
{'headers': {'lol': b'wut', 'oh': b'hai'},
'method': 'GET',
'url': b'/test',
'version': '1.1'}
Extra
This project is a toy, started to reacquaint myself with Python c-api modules. If you find it useful, please let me know.
The version number tracks the version of the incorporated llhttp.
License: MIT
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
pyllhttp-6.8.0.tar.gz
(41.0 kB
view details)
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pyllhttp-6.8.0.tar.gz.
File metadata
- Download URL: pyllhttp-6.8.0.tar.gz
- Upload date:
- Size: 41.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.1.0 CPython/3.13.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bcd7e0d265503d5b69c56f7eae944a81a445d2d1a01c0ab90a26050579e564e1
|
|
| MD5 |
77346209a61562c67012c717f79d9688
|
|
| BLAKE2b-256 |
26a771623ee0073184b13fb497b9e146fd7da1082bfa4c6bc685fb1afd281004
|
File details
Details for the file pyllhttp-6.8.0-cp313-cp313-macosx_15_0_arm64.whl.
File metadata
- Download URL: pyllhttp-6.8.0-cp313-cp313-macosx_15_0_arm64.whl
- Upload date:
- Size: 41.9 kB
- Tags: CPython 3.13, macOS 15.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.1.0 CPython/3.13.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a95dfdd488062576a32816d19eef5d5df8eb2e29b172770c3989ac8f656c2c4d
|
|
| MD5 |
fdcd52bfa65b6af2c47e417fb067d4b6
|
|
| BLAKE2b-256 |
d67c9914ffc6c61c7921adc0a639a0c8d10a5d2b1f555e4ad3dfc8c6137a9153
|