← back to home

Kraken

20237 viewsView on GitHub
CSystemsWebNetworkingConcurrency

A multi-threaded HTTP/1.1 server framework written in C with Express-like routing

Kraken Logo

A multi-threaded HTTP server framework built from scratch in C. Built on top of Owl, Kraken provides an Express-like API for routing, static file serving, and basic templating.

What's Inside

Core Features

HTTP Server - Implements HTTP request parsing and response formatting. Parses request lines, headers, and bodies, then builds proper HTTP responses with status codes and headers.

Multi-threaded Architecture - Uses a thread pool to handle concurrent client connections. Each incoming request is dispatched to an available worker thread for parallel request processing.

Hash-based Routing - Routes are stored in a hashmap using SipHash-2-4 for O(1) lookup performance. URI matching is handled through custom comparators with minimal overhead.

Static File Server - Serves static files with automatic MIME type detection for common content types (HTML, CSS, JS, images, fonts, audio, video). Supports directory index files and chunked file transfer for large assets.

Server-Side Rendering - Built-in templating system with placeholder substitution ({{variable}}) for dynamic HTML generation. Load templates from files or strings with efficient string replacement.

Request/Response API

Request Parsing - Automatic parsing of HTTP request lines, headers, and body. Headers stored in a hashmap for fast lookup. URI and HTTP version extraction included.

Response Builder - Simple response API with status code helpers, content-type configuration, and custom header support. Includes enums for common HTTP status codes.

Chunked Transfer - Responses are sent in configurable chunks (4KB buffer) to handle arbitrarily large payloads without memory constraints.

Quick Start

Building

Compile Kraken and its dependencies:

make

Or build as a shared library:

make -e SHARED=1

The server binary will be created as main, and the library will be in lib/.

Hello World Server

#include "kraken.h"
 
#define PORT 8000
#define BACKLOG 10
 
char *index_handler(http_req_t *req, http_res_t *res) {
    return "Hello World";
}
 
int main() {
    http_server_t *server = http_server_init(PORT, BACKLOG);
 
    register_route(server, "/", index_handler);
    register_static(server, "public");
 
    http_server_listen(server);
    http_server_free(server);
}

Dynamic Templates

char *home_handler(http_req_t *req, http_res_t *res) {
    placeholder_t placeholders[] = {
        {"{{title}}", "Welcome to Kraken"},
        {"{{content}}", "Built with C"},
    };
 
    return res_render_template_file(
        "./template.html",
        placeholders,
        NUM_PLACEHOLDERS(placeholders)
    );
}

Working with Headers

char *api_handler(http_req_t *req, http_res_t *res) {
    res_status(res, HTTP_STATUS_OK);
    res_content_type(res, "application/json");
 
    return "{\"message\": \"API response\"}";
}

Technical Implementation

Connection Handling

  1. Accept Loop - Main thread runs an infinite accept loop, blocking until a client connects
  2. Task Dispatch - Each accepted connection is wrapped in a task and enqueued to the thread pool
  3. Worker Processing - Available worker threads dequeue tasks and handle the full request-response cycle
  4. Graceful Cleanup - Connection FDs are closed after response transmission, and resources are freed

Request Processing Pipeline

TCP Connection → Request Buffering → HTTP Parsing → Route Lookup →
Handler Execution → Response Building → Chunked Send → Close

Static File Strategy

Kraken checks multiple registered static directories in order, supporting:

Memory Management

Design Philosophy

Technical Notes

Limitations

Use Cases

2kudos