Skip to content

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

License

Notifications You must be signed in to change notification settings

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

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

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •