Skip to content

kaisarcode/http.c

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

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

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.

Parse options

Option Description
--all Parse all messages until EOF, separated by ---.

Build request options

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.

Build response options

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.

Common options

Option Description
-h, --help Show help and exit.
-v, --version Show 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

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

Source Layout

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

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).

About

HTTP Protocol Parser and Builder

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors