KaisarCode

http.c

http.c - HTTP Protocol Parser and Builder

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:8080

CLI

Examples

Parse one HTTP request from stdin:

printf 'GET / HTTP/1.1\r\nHost: localhost\r\n\r\n' | http parse

Parse all messages from a keep-alive stream:

cat stream.bin | http parse --all

Build 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

Commands

CommandDescription
parseParse one HTTP message from stdin and emit normalized output.
parse --allParse all HTTP messages from stdin until EOF.
build requestBuild an HTTP request from stdin body.
build responseBuild an HTTP response from stdin body.

Parse options

OptionDescription
--allParse all messages until EOF, separated by ---.

Build request options

OptionDescription
--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.
--chunkedUse Transfer-Encoding: chunked.
--chunk-size <n>Chunk size in bytes. Default: 8192.

Build response options

OptionDescription
--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.
--chunkedUse Transfer-Encoding: chunked.
--chunk-size <n>Chunk size in bytes. Default: 8192.
--trailer <name: value>Add a trailer (chunked only). Repeatable.

Common options

OptionDescription
-h, --helpShow help and exit.
-v, --versionShow version and exit.

Parse output format

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 before body.length.
  • body.length always 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.


Public API

#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);

Lifecycle

  • kc_http_open() allocates a context with default settings.
  • kc_http_set_* / kc_http_add_* configure the operation.
  • kc_http_exec() reads from stdin and writes to stdout.
  • 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.


Protocol support

VersionStatus
HTTP/0.9Parsed (simple request, no headers, no body)
HTTP/1.0Full parse and build
HTTP/1.1Full parse and build, chunked, trailers
HTTP/2Binary frame parse/build for HEADERS and DATA
HTTP/3Frame parse/build for HEADERS and DATA

Source Layout

FileRole
src/http.cCLI argument parsing only
src/libhttp.cShared context, helpers, and protocol dispatch
src/http1.cHTTP/0.9, HTTP/1.0, and HTTP/1.1 parser/builder
src/http2.cHTTP/2 frame and HPACK parser/builder
src/http3.cHTTP/3 frame and QPACK parser/builder

Build

make

Artifacts:

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

Multiarch Builds

make all

Targets: 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.


License

GPLv3

This project is distributed under the GNU General Public License version 3 (GPLv3).


Repo

GitHub: kaisarcode/http.c