Skip to content

Latest commit

 

History

19 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

chttp

A small HTTP/1.1 server library written in C11, with no dependencies beyond a POSIX system. One poll() loop, one thread, non-blocking sockets.

#include "chttp.h"

static int hello(chttp_request *request, chttp_response *response, void *user_data)
{
    (void)request;
    (void)user_data;
    return chttp_response_send_text(response, 200, "hello world\n");
}

int main(void)
{
    chttp_config config = chttp_config_default();
    chttp_server *server = chttp_server_new(&config);

    chttp_server_route(server, CHTTP_GET, "/", hello, NULL);
    chttp_server_run(server);
    chttp_server_free(server);
    return 0;
}

What it does

  • HTTP/1.1 and HTTP/1.0 with correct persistent-connection defaults, Connection: close handling and a configurable keep-alive request cap.
  • Incremental parser that never needs a whole request in memory at once and accepts data one byte at a time.
  • Chunked transfer decoding, including chunk extensions and trailer fields.
  • Expect: 100-continue answered before the body is read.
  • Request pipelining: buffered requests are handled in order.
  • Router with :name captures, a trailing * wildcard, automatic HEAD handling and 405 replies carrying an Allow header.
  • Query strings and percent-decoding for paths and arguments.
  • Static files with MIME lookup, ETag, Last-Modified, If-None-Match, byte ranges (206/416) and traversal protection.
  • Streaming responses from disk in fixed slices instead of loading files into memory.
  • Limits everywhere: request line, header block, body size, connection count and idle timeout are all bounded and configurable.

Build

make              # static library in build/libchttp.a
make examples     # build/bin/hello and build/bin/static_server
make test         # unit tests plus socket level integration tests
make sanitize     # rebuild and run the tests under ASan and UBSan
make format       # clang-format over src, include, examples and tests
sudo make install # PREFIX=/usr/local by default

Requires a C11 compiler (GCC or Clang) and a POSIX platform. Tested on Linux and macOS.

Try it

make examples
./build/bin/hello 8080 &

curl -i localhost:8080/hello/notion
curl -i -X POST --data 'ping' localhost:8080/echo
curl -i localhost:8080/nope

./build/bin/static_server 8081 public &
curl -i localhost:8081/
curl -i -H 'Range: bytes=0-31' localhost:8081/index.html

Using the library

Link against build/libchttp.a and add include/ to your include path:

cc -std=c11 -Iinclude my_server.c build/libchttp.a -o my_server

A handler receives the parsed request and an empty response, fills the response in, and returns CHTTP_OK:

static int show_user(chttp_request *request, chttp_response *response, void *user_data)
{
    const char *id = chttp_request_param(request, "id");   /* /users/:id  */
    const char *fields = chttp_request_query(request, "fields");

    (void)user_data;
    chttp_response_status(response, 200);
    chttp_response_header(response, "Content-Type", "application/json");
    return chttp_response_print(response, "{\"id\":\"%s\",\"fields\":\"%s\"}", id,
                                fields != NULL ? fields : "all");
}

chttp_server_route(server, CHTTP_GET, "/users/:id", show_user, NULL);
chttp_server_static(server, "/assets", "public");

Date, Server, Content-Length and Connection are written by the server, so a handler cannot produce a mis-framed response. chttp_server_stop() is safe to call from a signal handler.

Documentation

  • docs/api.md — every public function, type and config field.
  • docs/architecture.md — the event loop, the parser state machine, the module layout and the deliberate limitations.

Layout

include/chttp.h     public API, the only header a user needs
src/buffer.*        growable byte buffer
src/kv.*            name/value lists for headers, query args, captures
src/util.*          strings, dates, monotonic clock, token lists
src/log.*           levelled logging to stderr
src/http.c          method and status tables
src/url.*           percent-decoding and query parsing
src/mime.*          extension to content type table
src/request.*       incremental request parser
src/response.*      response builder and header serialisation
src/router.*        pattern matching
src/file.*          static file handler
src/connection.*    per-connection state machine
src/server.c        sockets, poll loop, lifecycle
examples/           runnable servers
tests/              unit and integration tests

Limitations

This is a readable, self-contained server, not a replacement for nginx. There is no TLS, no HTTP/2, no sendfile, no request routing across threads and no response compression. Bodies are buffered in memory up to max_body_bytes, so large uploads want a different design.

License

MIT — see LICENSE.

About

Create http using C from scratch

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages