HTTP Server
Stone provides the server module for building HTTP servers. This module is only available in native (LLVM) builds — it does not work in the browser/WASM backend.
Quick Start
import server
s = server.serve(8080)
print("Listening on port 8080")
while (true) {
req = server.await_request(s)
server.send_response(req, {status = 200, body = "Hello!"})
}
Build and run:
stone build my_server.stn --target llvm
clang -O3 my_server.ll stone_runtime.c stone_server.c -lm -lws2_32 -o my_server.exe # Windows
clang -O3 my_server.ll stone_runtime.c stone_server.c -lm -o my_server # Linux/macOS
./my_server
server.serve()
Create an HTTP server listening on a port. Returns a server handle.
import server
s = server.serve(3000)
The server binds to 0.0.0.0 (all interfaces) on the given port. It sets SO_REUSEADDR so you can restart quickly after stopping. On Unix, SIGPIPE is ignored so writing to closed connections won't kill the process.
server.await_request()
Block until an HTTP request arrives. Returns a request record.
req = server.await_request(s)
print(req.method) // "GET", "POST", etc.
print(req.path) // "/api/hello"
print(req.body) // Request body (empty string for GET)
Request Record
| Field | Type | Description |
|---|---|---|
method | string | HTTP method ("GET", "POST", etc.) |
path | string | Request path ("/hello", "/api/users") |
body | string | Request body (empty string if none) |
_fd | num | Internal connection file descriptor |
The function reads the full HTTP request including headers and body (via Content-Length). Maximum request size is 64 KB.
server.send_response()
Send an HTTP response and close the connection.
server.send_response(req, {status = 200, body = "Hello from Stone!"})
Response Record
| Field | Type | Default | Description |
|---|---|---|---|
status | num | 200 | HTTP status code |
body | string | "" | Response body |
Supported status codes with text: 200 OK, 201 Created, 204 No Content, 400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found, 405 Method Not Allowed, 500 Internal Server Error. Other codes default to "OK" as status text.
The response is sent with Content-Type: text/plain and Connection: close. The connection is closed after sending.
server.stop()
Close the listening server socket.
server.stop(s)
On Windows, this also cleans up the Winsock subsystem.
Routing Example
Use if/elif on the request path and method to route requests:
import server
s = server.serve(8080)
print("Server running on port 8080")
while (true) {
req = server.await_request(s)
response = if (req.path == "/hello") {
{status = 200, body = "Hello from Stone!"}
} elif (req.path == "/health") {
{status = 200, body = "OK"}
} elif (req.path == "/echo" and req.method == "POST") {
{status = 200, body = req.body}
} else {
{status = 404, body = "Not found"}
}
server.send_response(req, response)
}
Test with curl:
curl http://localhost:8080/hello # "Hello from Stone!"
curl http://localhost:8080/health # "OK"
curl -X POST -d "hi" localhost:8080/echo # "hi"
curl http://localhost:8080/nope # "Not found" (404)
Platform Support
The server module uses POSIX sockets on Linux/macOS and Winsock on Windows. On Windows, link with -lws2_32. The module compiles cross-platform from the same stone_server.c source.
Notes
Import server before calling any server functions. The module only works in LLVM/native builds — calling any server function in the WASM/browser backend throws "server module is only available in native (LLVM) builds". Each await_request blocks the entire program until a connection arrives. Connections are Connection: close (no keep-alive). No chunked transfer encoding — body size is determined by Content-Length.