$ show jeremycw/httpserver.h
httpserver.h is a single-header C library for building high-performance, non-blocking, event-driven HTTP servers. It uses epoll on Linux and kqueue on BSD/macOS for I/O multiplexing, and includes a Ragel-generated HTTP parser that handles chunked transfer encoding, content-length bodies, streaming, and keep-alive connections. The library exposes a clean callback-based API: initialize a server with a port and request handler, then call listen to start the event loop. It also supports a poll mode for integration into existing event loops (e.g., game engines). The codebase is well-structured internally, split into separate compilation units that are concatenated into a single header at build time via M4. It includes comprehensive unit tests (using munit), functional tests (shell-driven), fuzz testing, and CI. Production-grade features include memory usage limits, request timeouts, connection management, and chunked response support. The architecture demonstrates strong C craftsmanship with clear separation of I/O, parsing, response formatting, and connection management.
The LLM identified 2 files worth highlighting for reuse:
A Ragel-based HTTP parser that converts raw byte streams into tokens (method, target, headers, body). It handles chunked transfer encoding, content-length bodies, and streaming (large bodies that exceed buffer capacity). The parser is isolated: it only depends on struct hsh_buffer_s and struct hsh_parser_s from common.h, and can be extracted into a standalone HTTP parsing library with minimal modification. It demonstrates non-obvious skill in using Ragel for state machine generation and efficiently handling incremental parsing with backpressure.
The I/O event handler that abstracts over epoll (Linux) and kqueue (BSD/macOS). It manages read/write readiness, timer events, and connection lifecycle. It provides functions to begin read/write on a request, and dispatches to the appropriate platform-specific callbacks. While tightly coupled to the http_request_t structure, the pattern of separating event registration and handling via a callback table could be reused for other async I/O libraries. It also handles memory-based backpressure (503 when estimated memory exceeds limit).