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:
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 failuresAPI Reference
See API.md for full documentation of all public functions with usage examples.
License
MIT