Gojo
Esc
  • Loading…
http
Documentation

Standard library

std/http

HTTP/1.1: a server built on tasks, scopes and cancellation, and a small client.

HTTP/1.1: a server built on tasks, scopes and cancellation, and a small client. Plain HTTP only (no TLS).

struct Hello {
    fn serve(self, req: http.Request) -> http.Response {
        return http.text(200, "hello " + (req.param("name") ?? "world"))
    }
}
fn main() ! io.Error {
    let ln = try net.listen(":8080")
    http.serve(ln, Hello{}, http.Options{})
}

Every connection is a task in the server's scope, so cancelling the task that runs serve cancels the requests in flight. Every request runs under a deadline (Options.deadline): a handler still running then is cancelled and the client gets 504. A client that hangs up cancels its request too: the handler's blocking calls return early.

Types: struct Header, struct Request, struct Response, interface Handler, struct Options, struct Stats

Functions: findHeader, text, json, statusText, serve, serveCounting, request, get, post, decode, encode

Types

struct Header

pub struct Header {
    pub name: String
    pub value: String
}

A header line. Names are matched without regard to case.

struct Request

pub struct Request {
    pub method: String
    // the path, without the query
    pub path: String
    // what follows `?` in the target, still percent-encoded
    pub rawQuery: String = ""
    pub headers: Vec[Header] = []
    pub body: Vec[byte] = []
}

A request, as a handler gets it: the whole body has been read (up to Options.maxBody).

Request.header

pub fn header(self, name: str) -> ?String

The value of header name (any case).

Request.param

pub fn param(self, name: str) -> ?String

A query parameter, decoded: "/search?q=a+b" has param("q") == "a b".

Request.segments

pub fn segments(self) -> Vec[String]

The path's parts: "/todos/7" -> ["todos", "7"].

Request.text

pub fn text(self) -> String

The body, as a string.

struct Response

pub struct Response {
    pub status: int = 200
    pub headers: Vec[Header] = []
    pub body: Vec[byte] = []
}

What a handler answers, and what the client gets back. Content-Length and Connection are set by the server; line breaks in header names and values become spaces.

Response.header

pub fn header(self, name: str) -> ?String

The value of header name (any case).

Response.setHeader

pub fn setHeader(inout self, name: str, value: str)

Adds a header.

Response.text

pub fn text(self) -> String

The body, as a string.

interface Handler

pub interface Handler {
    fn serve(self, req: Request) -> Response
}

Answers requests. serve runs in a goroutine of its own for each connection, under the deadline of Options.deadline; it is cancelled when the deadline passes, the client hangs up or the server stops.

struct Options

pub struct Options {
    // how long a handler may run
    pub deadline: int = 30 * time.second
    // the largest request body accepted
    pub maxBody: int = 8 * 1024 * 1024
}

How the server treats requests.

struct Stats

pub struct Stats {
    pub served: int = 0
    pub timedOut: int = 0
    pub hungUp: int = 0
    pub stopped: int = 0
    pub rejected: int = 0
}

What happened to the requests a server has handled (see serveCounting): answered, stopped at the deadline (answered 504), abandoned by the client, cancelled when the server stopped, or rejected as malformed or too large.

Functions

findHeader

pub fn findHeader(hs: []Header, name: str) -> ?String

The value of header name (any case) in hs.

text

pub fn text(status: int, body: str) -> Response

A plain-text response.

json

pub fn json(status: int, body: str) -> Response

A JSON response; body is JSON text (see json.Value.encode).

statusText

pub fn statusText(status: int) -> str

The reason phrase for a status code: 404 -> "Not Found".

serve

pub fn serve[H: Handler + send](ln: net.Listener, h: H, opts: Options)

Serves until the calling task is cancelled; then cancels the requests in flight and waits for them.

serveCounting

pub fn serveCounting[H: Handler + send](ln: net.Listener, h: H, opts: Options, stats: Mutex[Stats])

Like serve, counting what happened to the requests in stats.

request

pub fn request(method: str, url: str, headers: []Header, body: []byte) -> Response ! io.Error

Sends a request and reads the whole response. url is "http://host[:port]/path?query".

get

pub fn get(url: str) -> Response ! io.Error

A GET request.

post

pub fn post(url: str, contentType: str, body: []byte) -> Response ! io.Error

A POST request with a body of the given type.

decode

pub fn decode(s: str) -> ?String

Percent-decoding (and + as a space, as in query strings); none if malformed.

encode

pub fn encode(s: str) -> String

Percent-encoding of everything but letters, digits and -._~.