llhttp


Namellhttp JSON
Version 9.3.0.0 PyPI version JSON
download
home_pagehttp://github.com/pallas/pyllhttp
Summaryllhttp in python
upload_time2025-09-01 00:12:55
maintainerNone
docs_urlNone
authorDerrick Lyndon Pallas
requires_pythonNone
licenseMIT
keywords www http parser
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # pyllhttp
Python wrapper for llhttp
======

A simple Python wrapper around [llhttp](https://github.com/nodejs/llhttp),
the HTTP parser for [Node.js](https://nodejs.org/).

## Install

[llhttp](https://pypi.org/project/llhttp/) via PyPI, or `pip install llhttp`

## Usage

```python
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': '9.3.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](https://docs.python.org/3/c-api/) modules.  If you find it useful,
please let me know.

The version number tracks the version of the incorporated llhttp.

License: [MIT](https://opensource.org/licenses/MIT)

            

Raw data

            {
    "_id": null,
    "home_page": "http://github.com/pallas/pyllhttp",
    "name": "llhttp",
    "maintainer": null,
    "docs_url": null,
    "requires_python": null,
    "maintainer_email": null,
    "keywords": "www http parser",
    "author": "Derrick Lyndon Pallas",
    "author_email": "derrick@pallas.us",
    "download_url": "https://files.pythonhosted.org/packages/8c/65/d119afeaa3ec3c1ac75cede9b2e6530a29fe5d56277e754d7489fc17a7e1/llhttp-9.3.0.0.tar.gz",
    "platform": null,
    "description": "# pyllhttp\nPython wrapper for llhttp\n======\n\nA simple Python wrapper around [llhttp](https://github.com/nodejs/llhttp),\nthe HTTP parser for [Node.js](https://nodejs.org/).\n\n## Install\n\n[llhttp](https://pypi.org/project/llhttp/) via PyPI, or `pip install llhttp`\n\n## Usage\n\n```python\nimport llhttp\nfrom pprint import pprint\n\npprint({\"version\": llhttp.version})\n\nclass request_parser(llhttp.Request):\n    headers = {}\n\n    url = b''\n    current_header_field = None\n    current_header_value = None\n\n    def on_message_begin(self):\n        print(f\"MESSAGE BEGIN\")\n\n    def on_url(self, url):\n        self.url += url\n        self.pause()\n\n    def on_url_complete(self):\n        print(f\"URL {self.url}\")\n\n    def on_header_field(self, field):\n        assert self.current_header_value is None\n        if self.current_header_field is None:\n            self.current_header_field = bytearray(field)\n        else:\n            self.current_header_field += field\n\n    def on_header_field_complete(self):\n        self.current_header_field = self.current_header_field.decode('iso-8859-1').lower()\n        assert self.current_header_field not in self.headers\n\n    def on_header_value(self, value):\n        assert self.current_header_field is not None\n        if self.current_header_value is None:\n            self.current_header_value = bytearray(value)\n        else:\n            self.current_header_value += value\n\n    def on_header_value_complete(self):\n        assert self.current_header_field is not None\n        self.current_header_value = bytes(self.current_header_value)\n        print(f\"HEADER {self.current_header_field}: {self.current_header_value}\")\n        self.headers[self.current_header_field] = self.current_header_value\n        self.current_header_field = None\n        self.current_header_value = None\n\n    def on_headers_complete(self):\n        assert self.current_header_field is None\n        assert self.current_header_value is None\n\n    def on_message_complete(self):\n        print(\"MESSAGE COMPLETE\")\n\nparser = request_parser()\n\nassert parser.lenient_headers is not True\nparser.lenient_headers = True\nparser.reset()\nassert parser.lenient_headers is True\n\nbuffer = b\"GET /test HTTP/1.1\\r\\nlOl:wut\\r\\nOH: hai\\r\\n\\r\\n\"\nwhile buffer:\n    consumed = parser.execute(buffer[:2])\n    buffer = buffer[consumed:]\n    if parser.is_paused:\n        print(\"UNPAUSING\")\n        parser.unpause()\n\nparser.finish()\npprint({\n    \"method\": parser.method,\n    \"url\": parser.url,\n    \"version\": f\"{parser.major}.{parser.minor}\",\n    \"headers\": parser.headers,\n})\n```\n\n```\n{'version': '9.3.0'}\nMESSAGE BEGIN\nUNPAUSING\nUNPAUSING\nUNPAUSING\nURL b'/test'\nHEADER lol: b'wut'\nHEADER oh: b'hai'\nMESSAGE COMPLETE\n{'headers': {'lol': b'wut', 'oh': b'hai'},\n 'method': 'GET',\n 'url': b'/test',\n 'version': '1.1'}\n```\n\n## Extra\n\nThis project is a toy, started to reacquaint myself with Python\n[c-api](https://docs.python.org/3/c-api/) modules.  If you find it useful,\nplease let me know.\n\nThe version number tracks the version of the incorporated llhttp.\n\nLicense: [MIT](https://opensource.org/licenses/MIT)\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "llhttp in python",
    "version": "9.3.0.0",
    "project_urls": {
        "Homepage": "http://github.com/pallas/pyllhttp"
    },
    "split_keywords": [
        "www",
        "http",
        "parser"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "8c65d119afeaa3ec3c1ac75cede9b2e6530a29fe5d56277e754d7489fc17a7e1",
                "md5": "26c30d4a133bdb746c0faccf2d863d3b",
                "sha256": "0d989363e7fb6f270b9d49956e7a3945c26778f8c70a166815264309ac6a8295"
            },
            "downloads": -1,
            "filename": "llhttp-9.3.0.0.tar.gz",
            "has_sig": false,
            "md5_digest": "26c30d4a133bdb746c0faccf2d863d3b",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": null,
            "size": 37824,
            "upload_time": "2025-09-01T00:12:55",
            "upload_time_iso_8601": "2025-09-01T00:12:55.149521Z",
            "url": "https://files.pythonhosted.org/packages/8c/65/d119afeaa3ec3c1ac75cede9b2e6530a29fe5d56277e754d7489fc17a7e1/llhttp-9.3.0.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-09-01 00:12:55",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "pallas",
    "github_project": "pyllhttp",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "lcname": "llhttp"
}
        
Elapsed time: 1.40005s