Production-ready HTTP client, server, router, compression, and middleware toolkit for the Alya language ecosystem.
- β‘ High Performance & Reactive I/O: Fast protocol parsing and routing. Seamlessly binds to
event::EventLoopfor non-blocking reactive concurrency (reactive_server), handling thousands of concurrent connections with zero thread overhead. - π RFC 6455 WebSockets: Full-duplex WebSocket server and client connections. Automatic handshake negotiation (
101 Switching Protocols), RFC test-vector verified framing (text, binary, ping, pong, close), and callback-driven protocol drivers (ws_on_message,ws_send, etc.). - ποΈ Web Compression Toolkit: Native integration with
compresssupporting Brotli (br), Zstandard (zstd), Gzip (gzip), and Deflate (deflate). AutomaticAccept-Encodingnegotiation, server response compression middleware, pre-compressed static asset serving (.brand.gz), and client decompression. - π Full HTTP Client: Supports GET, POST, PUT, DELETE, PATCH, HEAD, and OPTIONS with custom headers, query params, timeout handling, and automatic redirect following.
- π HTTP Server & Context: Built on low-level TCP sockets (
std/net) or non-blocking event loops, offering intuitive request context (HttpContext), JSON responses, text responses, file serving, and status helpers. - π£οΈ Parametric Router & Route Groups: Fast URL pattern matching with wildcard (
*path) and named parameters (:id), plus subrouter groups with shared path prefixes and middleware chains. - π‘οΈ Extensible Middleware: Out-of-the-box middleware for Compression (
mw_apply_compression), CORS (cors_middleware), request logging (logger_middleware), panic recovery (recovery_middleware), and static file serving (static_middleware). - πͺ Cookie & Header Management: RFC-compliant Cookie serialization/parsing (
Set-CookieandCookieheaders) and case-insensitive HTTP header operations.
http/
βββ alya.toml # Package manifest
βββ src/
β βββ lib.alya # Public API facade & high-level constructors
β βββ types.alya # Core struct definitions (HttpRequest, HttpResponse, Route, etc.)
β βββ core/
β β βββ status.alya # HTTP status codes & standard status messages
β β βββ headers.alya # Case-insensitive header dictionary helpers
β β βββ cookies.alya # Cookie parsing, serialization, and Set-Cookie generation
β β βββ compression.alya# HTTP content encoding, negotiation, and compression engine
β β βββ protocol.alya # HTTP/1.1 request & response parsing and serialization
β βββ router/
β β βββ route.alya # Route definition and parameter extractor
β β βββ router.alya # HTTP router and route registry
β β βββ group.alya # Route grouping with prefix and sub-middlewares
β βββ server/
β β βββ context.alya # HttpContext request/response lifecycle helpers
β β βββ server.alya # TCP socket server, request loop, and connection handler
β β βββ reactive.alya # Event-loop driven non-blocking reactive HTTP server adapter
β βββ websocket/
β β βββ handshake.alya # RFC 6455 WebSocket upgrade & SHA-1 handshake accept token
β β βββ frame.alya # RFC 6455 frame serializer, deserializer, and masking
β β βββ connection.alya # High-level WebSocket bidirectional connection driver
β βββ client/
β β βββ client.alya # HttpClient implementation with socket IO and redirect loop
β β βββ methods.alya # Convenience functions (http_get, http_post, etc.)
β βββ middleware/
β βββ compress.alya # HTTP response compression middleware (Brotli, Zstd, Gzip, Deflate)
β βββ cors.alya # Cross-Origin Resource Sharing (CORS) handler
β βββ logger.alya # Request/response logging middleware
β βββ recovery.alya # Crash and exception recovery middleware
β βββ static.alya # Static file serving with MIME detection & pre-compressed assets
βββ examples/
β βββ compression_demo.alya # Dedicated HTTP compression showcase
β βββ demo.alya # Comprehensive usage demo
βββ tests/ # 14 comprehensive test suites (100% passing)
β βββ test_client.alya
β βββ test_compression.alya
β βββ test_context.alya
β βββ test_cookies.alya
β βββ test_headers.alya
β βββ test_middleware.alya
β βββ test_protocol.alya
β βββ test_reactive_server.alya
β βββ test_router.alya
β βββ test_server.alya
β βββ test_status.alya
β βββ test_websocket_conn.alya
β βββ test_websocket_frame.alya
β βββ test_websocket_handshake.alya
βββ benches/
βββ bench_basic.alya # Performance micro-benchmarks
Add http to your project's alya.toml:
[dependencies]
http = { git = "https://github.com/alya-lang/http", branch = "main" }Or install it directly via the alyac CLI:
alyac add http --git https://github.com/alya-lang/http --branch main
alyac installimport "http" as http
function main()
let app = http::router()
# Route with path parameter
app.get("/users/:id", "get_user")
# JSON API response route
app.post("/api/echo", "post_echo")
# Start listening on port 8080 with compression enabled
let srv = http::server(8080, "127.0.0.1", app)
http::server_enable_compression(srv, 256)
say "Server running on http://127.0.0.1:8080"
end
main()
import "http" as http
function main()
let srv = http::server(8080)
# Enable automatic response compression (Brotli > Zstandard > Gzip > Deflate)
# Responses >= 256 bytes will be compressed according to client's Accept-Encoding
http::server_enable_compression(srv, 256)
# Serve static directory with automatic .br / .gz pre-compressed asset detection
http::server_enable_static(srv, "/static", "./public")
end
main()
import "http" as http
function main()
# Simple GET request
let res = http::http_get("http://httpbin.org/get")
say "Status: " + str(res.status_code)
say "Body: " + res.body
# Client instance with custom options
let client = http::client(5000, 1, 3) # 5s timeout, follow redirects
let post_res = client.post("http://httpbin.org/post", "{\"hello\":\"world\"}", "application/json")
say "Response: " + post_res.body
end
main()
import "http" as http
function main()
# Create and serialize a secure cookie
let c = http::cookie("session_id", "xyz123", "/", 3600, 1, 1, "Strict")
let cookie_hdr = http::cookie_format(c)
say "Set-Cookie: " + cookie_hdr
# Parse cookies from incoming request header
let parsed = http::cookie_parse_all("theme=dark; session_id=xyz123")
say "Theme: " + parsed["theme"]
end
main()
| Function | Parameters | Description |
|---|---|---|
http_get(url, headers) |
url: string, headers: map |
Performs an HTTP GET request |
http_post(url, body, content_type, headers) |
url: string, body: string, ... |
Performs an HTTP POST request |
http_put(url, body, content_type, headers) |
url: string, body: string, ... |
Performs an HTTP PUT request |
http_patch(url, body, content_type, headers) |
url: string, body: string, ... |
Performs an HTTP PATCH request |
http_delete(url, headers) |
url: string, headers: map |
Performs an HTTP DELETE request |
http_query(url, body, content_type, headers) |
url: string, body: string, ... |
Performs an HTTP QUERY request (IETF safe method with body) |
client_new(timeout_ms, follow_redirects, max_redirects) |
timeout_ms: int, ... |
Instantiates a configured HttpClient |
| Function | Parameters | Description |
|---|---|---|
server_new(port, host, router) |
port: int, host: string, router: HttpRouter |
Creates a new HttpServer instance |
server_enable_compression(server, min_length) |
server: HttpServer, min_length: int |
Enables response compression middleware |
server_enable_static(server, prefix, dir) |
server: HttpServer, prefix: string, dir: string |
Enables static file serving with .br/.gz pre-compressed support |
server_enable_cors(server, origin, methods, headers) |
server: HttpServer, ... |
Enables CORS middleware |
server_enable_logger(server, enabled) |
server: HttpServer, enabled: int |
Enables request logger middleware |
context_json(ctx, status_code, json_str) |
ctx: HttpContext, status: int, json: string |
Sends a JSON response with proper header |
context_text(ctx, status_code, text_str) |
ctx: HttpContext, status: int, text: string |
Sends a plain text response |
| Function | Parameters | Description |
|---|---|---|
http_compress(data, encoding) |
data: string, encoding: string |
Compresses string with gzip, br, deflate, zstd |
http_decompress(bytes, encoding) |
bytes: list, encoding: string |
Decompresses byte array back into UTF-8 string |
http_negotiate_encoding(accept_header) |
accept_header: string |
Negotiates best algorithm (br > zstd > gzip > deflate) |
http_is_encoding_supported(encoding) |
encoding: string |
Returns 1 if encoding is supported, 0 otherwise |
compression(min_length) |
min_length: int |
Creates a new CompressionConfig struct (default 256 bytes) |
| Method | Parameters | Description |
|---|---|---|
router_new(not_found_action) |
not_found: string |
Instantiates a new route registry |
router_get(r, pattern, handler) |
pattern: string, handler: string |
Registers a GET route handler |
router_post(r, pattern, handler) |
pattern: string, handler: string |
Registers a POST route handler |
router_put(r, pattern, handler) |
pattern: string, handler: string |
Registers a PUT route handler |
router_delete(r, pattern, handler) |
pattern: string, handler: string |
Registers a DELETE route handler |
router_patch(r, pattern, handler) |
pattern: string, handler: string |
Registers a PATCH route handler |
router_query(r, pattern, handler) |
pattern: string, handler: string |
Registers a QUERY route handler |
router_group_add(r, prefix, ...) |
prefix: string, ... |
Registers a route under a group prefix |
| Function | Parameters | Description |
|---|---|---|
reactive_server(loop, port, host, router, on_req, on_ws) |
loop: EventLoop, ... |
Spawns an event-loop bound reactive HTTP/WS server |
server_use_event_loop(srv, loop, on_req, on_ws) |
srv: HttpServer, loop: EventLoop |
Binds an existing HttpServer to a non-blocking reactor |
server_close_reactive(srv) |
srv: HttpServer |
Unregisters server watchers and closes all client streams |
| Function | Parameters | Description |
|---|---|---|
websocket(stream, is_server) |
stream: TcpStream, is_server: int |
Wraps a non-blocking stream into a WebSocketConnection |
ws_send(ws, text) |
ws: WebSocketConnection, text: string |
Sends a UTF-8 text message frame |
ws_send_binary(ws, data) |
ws: WebSocketConnection, data: string |
Sends a binary message frame |
ws_ping(ws, data) |
ws: WebSocketConnection, data: string |
Sends an RFC 6455 ping heartbeat frame |
ws_pong(ws, data) |
ws: WebSocketConnection, data: string |
Sends an RFC 6455 pong heartbeat frame |
ws_close(ws, code, reason) |
ws: WebSocketConnection, code: int, reason: string |
Performs clean close handshake |
ws_on_message(ws, callback) |
ws: WebSocketConnection, cb: fn(ws, msg, is_bin) |
Registers message handler callback |
ws_on_close(ws, callback) |
ws: WebSocketConnection, cb: fn(ws, code, reason) |
Registers connection close callback |
ws_on_ping(ws, callback) |
ws: WebSocketConnection, cb: fn(ws, data) |
Registers incoming ping callback |
ws_on_pong(ws, callback) |
ws: WebSocketConnection, cb: fn(ws, data) |
Registers incoming pong callback |
Run all 14 test suites using alyac:
alyac testRun individual test files:
alyac run tests/test_compression.alya
alyac run tests/test_protocol.alya
alyac run tests/test_router.alya
alyac run tests/test_cookies.alyaRun benchmarks:
alyac run benches/bench_basic.alyaRun the demo examples:
alyac run examples/demo.alya
alyac run examples/compression_demo.alyaContributions are welcome! Please follow these steps:
- Fork the repository and clone it locally
- Install the package tools:
alyac install
- Create your feature branch:
git checkout -b feature/my-feature
- Verify tests and code formatting before opening a PR:
alyac test alyac fmt . --check
- Commit your changes:
git commit -m "feat: add feature description" - Open a Pull Request on GitHub.
This project is licensed under the MIT License - see the LICENSE file for details.