Skip to content

sqliteai/weblite

Repository files navigation

weblite

Embeddable C library for HTTP/HTTPS requests with automatic WebSocket fallback.

weblite gives C programs a simple, high-level API for making REST requests. When a direct HTTP connection isn't possible (firewalls, restrictive proxies), it automatically falls back to tunneling requests over WebSocket. TLS is supported via a pluggable backend (Mbed TLS, OpenSSL, or LibreSSL), and WebSocket compression is handled with permessage-deflate (RFC 7692).

The entire library compiles as a single static library or a two-file amalgamation (weblite.h + weblite.c), making it easy to drop into any project.

Features

  • HTTP/HTTPS client -- GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS with headers, body, and redirects
  • WebSocket fallback -- transparent REST-over-WebSocket tunneling when HTTP is blocked
  • TLS -- pluggable backend: Mbed TLS (bundled), OpenSSL, or LibreSSL (native libtls)
  • Async requests -- thread-pool-based non-blocking API with callbacks
  • permessage-deflate -- WebSocket compression per RFC 7692 with full parameter negotiation
  • Cross-platform -- POSIX, Windows, WASM, and bare-metal embedded (via platform hooks)
  • Amalgamation -- single-file build for easy integration
  • Zero global state leaks -- explicit init/cleanup lifecycle
  • Custom allocators -- plug in your own malloc/realloc/free

Quick Start

Build

git clone --recurse-submodules https://github.com/user/weblite.git
cd weblite
mkdir build && cd build
cmake .. && make -j8

Usage

#include "weblite.h"
#include <stdio.h>

int main(void) {
    weblite_config_t config = weblite_config_defaults();
    weblite_init(&config);

    weblite_response_t *resp = NULL;
    weblite_error_t err = weblite_get("https://httpbin.org/get", NULL, 0, &resp);

    if (err == WEBLITE_OK) {
        printf("Status: %d\n", resp->status_code);
        printf("Body: %.*s\n", (int)resp->body_len, (char *)resp->body);
    }

    weblite_response_free(resp);
    weblite_cleanup();
    return 0;
}

POST with JSON

const char *body = "{\"key\": \"value\"}";
weblite_header_t headers[] = {
    { "Content-Type", "application/json" },
};

weblite_response_t *resp = NULL;
weblite_post("https://httpbin.org/post",
             headers, 1,
             body, strlen(body),
             &resp);

Async Request

void on_done(const weblite_response_t *resp, void *ctx) {
    printf("Status: %d\n", resp->status_code);
}

weblite_async_handle_t *h = weblite_get_async(
    "https://httpbin.org/get", NULL, 0, on_done, NULL);
weblite_async_wait(h, 10000);

Build Options

CMake option Default Description
WEBLITE_TLS_BACKEND mbedtls TLS backend: mbedtls, openssl, libressl, none
WEBLITE_ENABLE_COMPRESSION ON WebSocket permessage-deflate via zlib
WEBLITE_ENABLE_THREADS ON Thread pool for async requests
WEBLITE_BUILD_TESTS ON Build unit tests
WEBLITE_BUILD_EXAMPLES ON Build example programs
WEBLITE_PLATFORM auto Target: posix, win32, wasm, embedded

TLS Backend Selection

# Mbed TLS (default, bundled as submodule)
cmake .. -DWEBLITE_TLS_BACKEND=mbedtls

# OpenSSL (uses system-installed OpenSSL)
cmake .. -DWEBLITE_TLS_BACKEND=openssl

# LibreSSL (uses native libtls API, found via pkg-config)
cmake .. -DWEBLITE_TLS_BACKEND=libressl

# LibreSSL with manual paths (when libtls is not in pkg-config)
cmake .. -DWEBLITE_TLS_BACKEND=libressl \
         -DWEBLITE_LIBTLS_LIBRARY=/path/to/libtls.a \
         -DWEBLITE_LIBTLS_INCLUDE_DIR=/path/to/include

# No TLS
cmake .. -DWEBLITE_TLS_BACKEND=none

Amalgamation

Generate a self-contained two-file build (weblite.h + weblite.c):

make amalgamation
# Output in build/amalgamation/

Project Structure

include/          Public headers (weblite.h, weblite_types.h)
src/              Core sources (http.c, ws.c, transport.c, tls_*.c, async.c, ...)
src/platform/     Platform abstraction (POSIX, Win32, WASM, embedded)
extern/mbedtls/   Mbed TLS 3.6.0 (git submodule)
extern/zlib/      zlib (git submodule)
tests/            Unit and conformance tests
examples/         Example programs
tools/            Build utilities (amalgamate.sh)

Testing

weblite has three layers of tests, all passing:

Unit Tests (6 tests)

Fast, offline tests covering internal components:

Test Coverage
test_buf Dynamic buffer (append, clear, format)
test_url URL parsing (schemes, ports, paths, queries)
test_base64 Base64 encode/decode
test_http HTTP request building and response parsing
test_ws WebSocket key derivation (SHA-1, RFC 6455)
test_integration Library lifecycle, config, error strings
make test
# 6/6 tests passed

Network Tests

Integration tests against httpbin.org covering HTTP methods, redirects, authentication, TLS, chunked transfer encoding, and async requests:

make test-network

Autobahn WebSocket Conformance (517 tests)

Full conformance suite via the Autobahn WebSocket Test Suite running in Docker. Tests cover the complete RFC 6455 protocol and RFC 7692 compression:

Result Count
OK 511
NON-STRICT 3
INFORMATIONAL 3
FAILED 0
make test-autobahn
# 517/517 cases completed, 0 failures

API Reference

See API.md for full documentation of all public functions with usage examples.

License

MIT

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •