Web libraries
These are pure-Langoost libraries shipped in the lib/ directory, written on top of the net.* primitives. You import them by name. They are distinct from the built-in http.serve (see HTTP server) — these give you Langoost-level types and handler functions you can read and extend.
Three libraries are covered here: http_server, websocket, and sse.
http_server
An HTTP/1.1 server. Each accepted connection is handled in its own thread.
Types
type Request = {
method: string,
path: string,
query: string,
version: string,
headers: string[], // raw "Key: Value" lines
body: string,
}
type Response = {
status: int,
headers: string[], // raw "Key: Value" lines
body: string,
}
Functions
| Function | Signature | Description |
|---|---|---|
serve | http_server.serve(port: int, handler) | bind the port and dispatch handler(req: Request) per connection; blocks forever |
header | http_server.header(req, name: string) → string | value of a header (case-insensitive), or "" if missing |
statusText | http_server.statusText(code: int) → string | IANA reason phrase for a status code |
The handler is called as handler(req) and may return either a string (sent as 200 OK with an auto Content-Type) or a Response for full control. Content-Length and Content-Type are added automatically if you omit them.
Example
import http_server
import { Response } from "http_server"
fn handle(req) {
if req.path == "/" {
return "Hello, World!"
}
if req.path == "/json" {
return Response{status: 200, headers: [], body: "{\"ok\":true}"}
}
return Response{status: 404, headers: [], body: "Not Found"}
}
http_server.serve(8080, handle)
websocket
A minimal RFC 6455 server-side WebSocket implementation. Use websocket.serve for end-to-end connections; it runs the handshake and hands your handler the raw connection.
Types
type WSRequest = { path: string, headers: string[] }
Functions
| Function | Signature | Description |
|---|---|---|
serve | websocket.serve(port: int, handler) | listen and call handler(conn: int, path: string) after the handshake completes |
recv | websocket.recv(conn: int) → string | read one frame’s payload; void on close/EOF (auto-replies to pings) |
send | websocket.send(conn: int, msg: string) → bool | send a text frame |
sendBinary | websocket.sendBinary(conn: int, data: string) → bool | send a binary frame |
close | websocket.close(conn: int) | send a close frame and close the connection |
isUpgrade | websocket.isUpgrade(req) → bool | true if the request is a valid WebSocket upgrade |
acceptKey | websocket.acceptKey(req) → string | compute the Sec-WebSocket-Accept value, or "" |
upgradeHeaders | websocket.upgradeHeaders(accept: string) → string[] | response header lines for a 101 handshake |
handshake | websocket.handshake(conn: int, req) → bool | perform the full server-side upgrade on conn |
Example
import websocket
fn handle(conn, path) {
println("ws connected: " + path)
while true {
let msg = websocket.recv(conn)
if typeof(msg) == "void" { break }
websocket.send(conn, "echo: " + msg)
}
websocket.close(conn)
}
websocket.serve(8090, handle)
sse
Server-Sent Events: the connection stays open and the server streams text events to the browser’s EventSource.
Types
type SSERequest = { path: string, headers: string[] }
Functions
| Function | Signature | Description |
|---|---|---|
serve | sse.serve(port: int, handler) | accept connections and call handler(req, emit); returning from the handler closes the socket |
writeHeaders | sse.writeHeaders(conn: int) → bool | write the text/event-stream 200 OK header block |
frame | sse.frame(event: string, data: string) → string | build one event payload; event="" uses the default message |
frameWithID | sse.frameWithID(event: string, data: string, id: string) → string | build an event with a Last-Event-ID hint |
retryHint | sse.retryHint(ms: int) → string | build a reconnect-delay hint frame |
The handler is called as handler(req, emit) where req is an SSERequest and emit is fn(event: string, data: string) which writes one event to the client.
Example
import sse
import thread
fn handle(req, emit) {
let i = 0
while i < 5 {
emit("tick", "n=" + toString(i))
thread.core.sleep(1000)
i = i + 1
}
}
sse.serve(8091, handle)