← all modules
module

stdlib::http

defined in C:\Users\bye45\.glide\bin/src/stdlib/http.glide

One incoming HTTP request, fully buffered. Lifetime is tied to the

struct struct HttpRequest

One incoming HTTP request, fully buffered. Lifetime is tied to the handler call that receives it; do not stash the pointer.

headers_block is the raw Name: Value\r\n… text from the wire. Use req.header("name") for case-insensitive lookups instead of poking at it directly.

trait trait ChunkSource

Source of body chunks for a streaming response. The server polls next_chunk repeatedly and writes each return value as one Transfer-Encoding: chunked chunk; none() ends the stream.

Implementors hold their own state — the server doesn't snapshot anything between calls. Glide has no closures, so the typical pattern is a struct with cursor / iterator fields plus an impl ChunkSource for MyStruct that walks them.

glide
pub struct Counter { pub idx: int, pub total: int }

impl ChunkSource for Counter {
    fn next_chunk(self: *Counter) -> ?string {
        if self.idx >= self.total { return none(); }
        self.idx = self.idx + 1;
        return some("tick=".concat(self.idx.to_string()).concat("\n"));
    }
}
struct struct HttpResponse

Outgoing response. Build with HttpResponse::ok() / HttpResponse::with_status(n) then chain the setters; status codes fall back to a generic reason phrase when unknown.

stream_src is null for buffered responses (the common case). Set it via .stream(source) when the body should flow over the wire one chunk at a time — the server emits Transfer-Encoding: chunked and ignores body.

fn fn parse_http_request(raw: string) -> !HttpRequest

Parse a complete HTTP/1.1 request. Returns err(msg) on a malformed or partial request; the server loop drops the connection in that case. Headers are case-folded to lower-case so req.headers.get ("content-length") always works.

glide
let r: !HttpRequest = parse_http_request("GET / HTTP/1.1\r\nHost: x\r\n\r\n");
if r.ok { println!(r.val.method, r.val.path); }
fn fn format_http_response(r: *HttpResponse) -> string

Render a response as wire bytes. Used by the server loop; exposed so callers can pipe responses elsewhere (a logger, a recorder). Always emits Connection: close — the in-process keep-alive path in http_listen calls the internal renderer directly.

glide
let bytes: string = format_http_response(&HttpResponse::ok().body("hi"));
fn fn http_listen(port: int, handler: fn(*HttpRequest) -> HttpResponse) -> !int

Listen on port and dispatch every request through handler. The fn returns err on bind failure and never returns on success — the server loop runs until the process exits.

Concurrency model: * Linux: reactor.c registers each fd with epoll and parks the calling coro on EAGAIN. The body of the loop spawns a coro per accepted connection so thousands of clients share a single OS thread. * Windows / macOS / BSD: there's no reactor yet, so the per-conn spawn would block its worker on the first sync read and starve other coros. The loop runs **serially** until IOCP / kqueue land. Behaviour is correct on every platform; throughput on non-Linux is the obvious one-conn-at-a-time.

glide
fn root(req: *HttpRequest) -> HttpResponse {
    return HttpResponse::ok().body("hello, ".concat(req.path));
}

fn main() -> int {
    http_listen(8080, root);
    return 0;
}
fn fn https_listen(port: int, cert_path: string, key_path: string, handler: fn(*HttpRequest) -> HttpResponse) -> !int

Listen for HTTPS connections on port with cert_path and key_path (both PEM). Each accepted client is dispatched to handler after the TLS handshake succeeds.

glide
fn root(req: *HttpRequest) -> HttpResponse {
    return HttpResponse::ok().body("hello over TLS!");
}

fn main() -> int {
    https_listen(8443, "cert.pem", "key.pem", root);
    return 0;
}
fn fn http_listen_workers(port: int, n: int, handler: fn(*HttpRequest) -> HttpResponse) -> !int

Like http_listen but bound to N worker threads, each with its own SO_REUSEPORT listener. The kernel load-balances accepts across the N threads; per-conn coroutines still feed the shared M:N scheduler, so handler work parallelises across all worker pthreads.

n is the total number of accept threads. The current OS thread runs the last loop, the other n - 1 are spawned via spawn_thread. Picks n = 1 collapses to the same behaviour as http_listen.

Returns err only if the very first bind fails. Subsequent threads that fail to bind die silently — the kernel decides how many fit.

glide
fn main() -> int {
    http_listen_workers(8080, 4, root);
    return 0;
}