{"id":22449785,"url":"https://github.com/zaki-x86/xhttp","last_synced_at":"2025-03-27T12:16:13.449Z","repository":{"id":224149451,"uuid":"762534350","full_name":"zaki-x86/xhttp","owner":"zaki-x86","description":"Your ultimate HTTP request/response message parser in C++","archived":false,"fork":false,"pushed_at":"2024-02-24T11:24:17.000Z","size":69,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-01T16:28:05.956Z","etag":null,"topics":["cpp","http","llhttp","parser"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zaki-x86.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-02-24T01:39:22.000Z","updated_at":"2024-02-24T11:34:24.000Z","dependencies_parsed_at":null,"dependency_job_id":"63dc54a5-fe2d-44cd-b38e-cf7a4c1cbb13","html_url":"https://github.com/zaki-x86/xhttp","commit_stats":null,"previous_names":["zaki-x86/xhttp"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zaki-x86%2Fxhttp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zaki-x86%2Fxhttp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zaki-x86%2Fxhttp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zaki-x86%2Fxhttp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zaki-x86","download_url":"https://codeload.github.com/zaki-x86/xhttp/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245841761,"owners_count":20681195,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cpp","http","llhttp","parser"],"created_at":"2024-12-06T05:11:51.920Z","updated_at":"2025-03-27T12:16:13.426Z","avatar_url":"https://github.com/zaki-x86.png","language":"C++","readme":"# `xhttp`\n\nReimplementation of [nodejs/llhttp](https://github.com/nodejs/llhttp) with Clean C++ API\n\n\u003e Project is under active development - but it is usable\n\n## Usage\n\n### Parsing an incoming http request message\n\n```cpp\n#include \u003cxhttp\u003e\n#include \u003ciostream\u003e\n\nint main(int argc, char const *argv[])\n{\n    const char* data = \"POST / HTTP/1.1\\r\\nHost: www.example.com\\r\\nContent-Type: application/x-www-form-urlencoded\\r\\nContent-Length: 4\\r\\nConnection: close\\r\\n\\r\\nq=42\\r\\n\\r\\n\";\n    xhttp::parser request_parser(xhttp::Type::REQUEST);\n    \n    request_parser\n        .on_msg_begin([](){\n            std::cout \u003c\u003c \"Parsing started!\\n\";\n            return xhttp::Errno::OK;\n        })\n        .on_method([](const char* at, size_t len){\n            std::string_view method(at, len);\n            std::cout \u003c\u003c \"Method: \" \u003c\u003c method \u003c\u003c \"\\n\";\n            return xhttp::Errno::OK;\n        })\n        .on_url([](const char* at, size_t len){\n            std::string_view url(at, len);\n            std::cout \u003c\u003c \"Url: \" \u003c\u003c url \u003c\u003c \"\\n\";\n            return xhttp::Errno::OK;\n        })\n        .on_version([](const char* at, size_t len){\n            std::string_view version(at, len);\n            std::cout \u003c\u003c \"Version: \" \u003c\u003c version \u003c\u003c \"\\n\";\n            return xhttp::Errno::OK;\n        })\n        .on_header_field([](const char* at, size_t len){\n            std::string_view header(at, len);\n            std::cout \u003c\u003c \"Header: \" \u003c\u003c header \u003c\u003c \"\\n\";\n            return xhttp::Errno::OK;\n        })\n        .on_header_value([](const char* at, size_t len){\n            std::string_view value(at, len);\n            std::cout \u003c\u003c \"Value: \" \u003c\u003c value \u003c\u003c \"\\n\";\n            return xhttp::Errno::OK;\n        })\n        .on_headers_complete([](){\n            std::cout \u003c\u003c \"Headers complete!\\n\";\n            return xhttp::Errno::OK;\n        })\n        .on_body([](const char* at, size_t len){\n            std::string_view body(at, len);\n            std::cout \u003c\u003c \"Body: \" \u003c\u003c body \u003c\u003c \"\\n\";\n            return xhttp::Errno::OK;\n        })\n        .on_msg_complete([](){\n            std::cout \u003c\u003c \"Message complete!\\n\";\n            return xhttp::Errno::OK;\n        })\n        .execute(data, strlen(data));\n\n    return 0;\n}\n\n```\n\nOutput:\n\n```\nParsing started!\nMethod: POST\nUrl: /\nVersion: 1.1\nHeader: Host\nValue: www.example.com\nHeader: Content-Type\nValue: application/x-www-form-urlencoded\nHeader: Content-Length\nValue: 4\nHeader: Connection\nValue: close\nHeaders complete!\nBody: q=42\nMessage complete!\nError: OK\n```\n\n### Parsing an incoming http response message\n\n```cpp\n#include \u003cxhttp\u003e\n#include \u003ciostream\u003e\n\nint main() {\n    xhttp::parser client_parser(xhttp::Type::RESPONSE);\n    \n    const char* data = \"HTTP/1.1 301 Moved Permanently\\r\\nLocation: http://www.google.com/\\r\\nContent-Type: text/html; charset=UTF-8\\r\\nContent-Security-Policy-Report-Only: object-src 'none';base-uri 'self';script-src 'nonce-elPYGZ6nFeqSYbouLhM5fw' 'strict-dynamic' 'report-sample' 'unsafe-eval' 'unsafe-inline' https: http:;report-uri https://csp.withgoogle.com/csp/gws/other-hp\\r\\nDate: Sat, 24 Feb 2024 10:42:00 GMT\\r\\nExpires: Mon, 25 Mar 2024 10:42:00 GMT\\r\\nCache-Control: public, max-age=2592000\\r\\nServer: gws\\r\\nContent-Length: 219\\r\\nX-XSS-Protection: 0\\r\\nX-Frame-Options: SAMEORIGIN\\r\\n\\r\\n\u003cHTML\u003e\\n\u003cHEAD\u003e\\n\u003cmeta http-equiv=\\\"content-type\\\" content=\\\"text/html;charset=utf-8\\\"\u003e\\n\u003cTITLE\u003e301 Moved\u003c/TITLE\u003e\\n\u003c/HEAD\u003e\\n\u003cBODY\u003e\\n\u003cH1\u003e301 Moved\u003c/H1\u003e\\nThe document has moved\u003cA HREF=\\\"http://www.google.com/\\\"\u003ehere\u003c/A\u003e.\\n\u003c/BODY\u003e\\n\u003c/HTML\u003e\\r\\n\\r\\n\";\n\n    client_parser\n        .on_version([](const char* at, size_t len){\n            std::string_view version(at, len);\n            std::cout \u003c\u003c \"Version: \" \u003c\u003c version \u003c\u003c std::endl;\n            return 0;\n        })\n        .on_status([\u0026client_parser](const char* at, size_t len){\n            std::string_view status(at, len);\n            std::cout \u003c\u003c \"Status code: \" \u003c\u003c client_parser.status_code() \u003c\u003c std::endl;\n            std::cout \u003c\u003c \"Status: \" \u003c\u003c status \u003c\u003c std::endl;\n            return 0;\n        })\n        .on_header_field([](const char* at, size_t len){\n            std::string_view header(at, len);\n            std::cout \u003c\u003c \"Header: \" \u003c\u003c header \u003c\u003c std::endl;\n            return 0;\n        })\n        .on_header_value([](const char* at, size_t len){\n            std::string_view value(at, len);\n            std::cout \u003c\u003c \"Value: \" \u003c\u003c value \u003c\u003c std::endl;\n            return 0;\n        })\n        .on_headers_complete([\u0026client_parser](){\n            std::cout \u003c\u003c \"Headers Complete\" \u003c\u003c std::endl;\n            std::cout \u003c\u003c \"Content-Length: \" \u003c\u003c client_parser.content_length() \u003c\u003c std::endl;\n            // based on the content length, you may choose to parse the body or not\n            // by returning 0, you will parse the body, and by returning 1, you will skip parsing the body\n            return 0;\n        })\n        .on_body([](const char* at, size_t len){\n            std::string_view body(at, len);\n            std::cout \u003c\u003c \"Body: \" \u003c\u003c body \u003c\u003c std::endl;\n            return 0;\n        })\n        .on_msg_complete([](){\n            std::cout \u003c\u003c \"Message Complete\" \u003c\u003c std::endl;\n            return 0;\n        })\n        .execute(data, strlen(data));\n}\n```\n\nOutput:\n\n```\nVersion: 1.1\nStatus code: 301\nStatus: Moved Permanently\nHeader: Location\nValue: http://www.google.com/\nHeader: Content-Type\nValue: text/html; charset=UTF-8\nHeader: Content-Security-Policy-Report-Only\nValue: object-src 'none';base-uri 'self';script-src 'nonce-elPYGZ6nFeqSYbouLhM5fw' 'strict-dynamic' 'report-sample' 'unsafe-eval' 'unsafe-inline' https: http:;report-uri https://csp.withgoogle.com/csp/gws/other-hp       \nHeader: Date\nValue: Sat, 24 Feb 2024 10:42:00 GMT\nHeader: Expires\nValue: Mon, 25 Mar 2024 10:42:00 GMT\nHeader: Cache-Control\nValue: public, max-age=2592000\nHeader: Server\nValue: gws\nHeader: Content-Length\nValue: 219\nHeader: X-XSS-Protection\nValue: 0\nHeader: X-Frame-Options\nValue: SAMEORIGIN\nHeaders Complete\nContent-Length: 219\nBody: \u003cHTML\u003e\n\u003cHEAD\u003e\n\u003cmeta http-equiv=\"content-type\" content=\"text/html;charset=utf-8\"\u003e\n\u003cTITLE\u003e301 Moved\u003c/TITLE\u003e\n\u003c/HEAD\u003e\n\u003cBODY\u003e\n\u003cH1\u003e301 Moved\u003c/H1\u003e\nThe document has moved\u003cA HREF=\"http://www.google.com/\"\u003ehere\u003c/A\u003e.\n\u003c/BODY\u003e\n\u003c/HTML\nMessage Complete\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzaki-x86%2Fxhttp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzaki-x86%2Fxhttp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzaki-x86%2Fxhttp/lists"}