http.c is an HTTP protocol parser and builder library and CLI. It reads
HTTP wire bytes from stdin, emits normalized message metadata plus the raw
logical body, and builds HTTP wire messages from raw payload bytes and
metadata.
It composes with stream tools such as netl and
nets:
netl 127.0.0.1:8080 'http parse | app'
app | http build response --status 200 | nets 127.0.0.1:8080Parse one HTTP request from stdin:
printf 'GET / HTTP/1.1\r\nHost: localhost\r\n\r\n' | http parseParse all messages from a keep-alive stream:
cat stream.bin | http parse --allBuild a POST request:
printf 'hello' | http build request \
--method POST \
--target /api \
--header 'host: localhost' \
--header 'content-type: text/plain'Build a 200 response:
cat index.html | http build response \
--status 200 \
--header 'content-type: text/html'Build a chunked response:
cat large.bin | http build response \
--status 200 \
--header 'content-type: application/octet-stream' \
--chunked| Command | Description |
|---|---|
parse |
Parse one HTTP message from stdin and emit normalized output. |
parse --all |
Parse all HTTP messages from stdin until EOF. |
build request |
Build an HTTP request from stdin body. |
build response |
Build an HTTP response from stdin body. |
| Option | Description |
|---|---|
--all |
Parse all messages until EOF, separated by ---. |
| Option | Description |
|---|---|
--method <method> |
HTTP method. Default: GET. |
--target <target> |
Request target. Default: /. |
--version <version> |
HTTP version. Default: 1.1. |
--header <name: value> |
Add a request header. Repeatable. |
--chunked |
Use Transfer-Encoding: chunked. |
--chunk-size <n> |
Chunk size in bytes. Default: 8192. |
| Option | Description |
|---|---|
--status <code> |
HTTP status code. Default: 200. |
--reason <phrase> |
Reason phrase. Default: derived from status. |
--version <version> |
HTTP version. Default: 1.1. |
--header <name: value> |
Add a response header. Repeatable. |
--chunked |
Use Transfer-Encoding: chunked. |
--chunk-size <n> |
Chunk size in bytes. Default: 8192. |
--trailer <name: value> |
Add a trailer (chunked only). Repeatable. |
| Option | Description |
|---|---|
-h, --help |
Show help and exit. |
-v, --version |
Show version and exit. |
http parse writes metadata lines, one empty line, then raw body bytes:
http.type=request
http.version=1.1
request.method=POST
request.target=/api?a=1
request.path=/api
request.query=a=1
header.host=localhost
header.content-type=text/plain
body.length=4
hello
Response output:
http.type=response
http.version=1.1
response.status=200
response.reason=OK
header.content-type=text/plain
body.length=4
hello
- Header names are lowercased.
- Repeated headers are emitted as separate lines in order.
- Chunked bodies are automatically dechunked; only logical payload bytes appear.
- Trailers are emitted as
trailer.<name>=<value>lines beforebody.length. body.lengthalways reflects the logical byte count, not the wire byte count.
For --all, messages are separated by \n---\n on its own line.
The consumer uses body.length to determine the exact end of each body.
#include "http.h"
kc_http_t *ctx = kc_http_open();
kc_http_set_op(ctx, KC_HTTP_OP_PARSE);
kc_http_exec(ctx);
kc_http_close(ctx);Build a response programmatically:
kc_http_t *ctx = kc_http_open();
kc_http_set_op(ctx, KC_HTTP_OP_BUILD_RESPONSE);
kc_http_set_status(ctx, 200);
kc_http_add_header(ctx, "content-type: text/plain");
kc_http_exec(ctx);
kc_http_close(ctx);kc_http_open()allocates a context with default settings.kc_http_set_*/kc_http_add_*configure the operation.kc_http_exec()reads fromstdinand writes tostdout.kc_http_close()frees all owned memory.
http.c owns HTTP framing completely. Callers provide raw payload bytes and receive logical payload bytes. Wire framing details (chunk syntax, Content-Length, CRLF) are never exposed to the caller.
| Version | Status |
|---|---|
| HTTP/0.9 | Parsed (simple request, no headers, no body) |
| HTTP/1.0 | Full parse and build |
| HTTP/1.1 | Full parse and build, chunked, trailers |
| HTTP/2 | Binary frame parse/build for HEADERS and DATA |
| HTTP/3 | Frame parse/build for HEADERS and DATA |
| File | Role |
|---|---|
src/http.c |
CLI argument parsing only |
src/libhttp.c |
Shared context, helpers, and protocol dispatch |
src/http1.c |
HTTP/0.9, HTTP/1.0, and HTTP/1.1 parser/builder |
src/http2.c |
HTTP/2 frame and HPACK parser/builder |
src/http3.c |
HTTP/3 frame and QPACK parser/builder |
makeArtifacts:
bin/{arch}/{platform}/http
bin/{arch}/{platform}/libhttp.a
bin/{arch}/{platform}/libhttp.so
Windows:
bin/{arch}/windows/http.exe
bin/{arch}/windows/libhttp.dll
bin/{arch}/windows/libhttp.dll.a
make allTargets: x86_64/linux, x86_64/windows, i686/linux, i686/windows,
aarch64/linux, aarch64/android, armv7/linux, armv7/android,
armv7hf/linux, riscv64/linux, powerpc64le/linux, mips/linux,
mipsel/linux, mips64el/linux, s390x/linux, loongarch64/linux.
This project is distributed under the GNU General Public License version 3 (GPLv3).
