std.http

HTTP/1.1 servers and clients, for text such as HTML and JSON.

A server handles one request at a time:

import std.http

let server: http.Server = http.serve("127.0.0.1", 8080)?
while true {
    let request: http.Request = server.next()?
    if request.path == "/hello" {
        request.respond(http.text(200, "Hello!"))?
    } else {
        request.respond(http.not_found())?
    }
}

A client makes a request and reads the whole response:

let response: http.Response = http.get("http://127.0.0.1:8080/hello")?
print(response.body)

Header names are kept in lower case. A server keeps connections open for more requests (HTTP keep-alive) unless the client asks to close them; quiet ones are closed after five seconds. Requests are handled one at a time. A client closes its connection after each response. https:// requests go through libcurl, which native programs then link with.

serve_api(module, request) answers requests for a module's pub fns, POST /api/<name> with the parameters as a JSON object; see the section on API functions below.

Types

struct Request

pub struct Request {
    pub method: string,
    pub path: string,
    pub query: Map[string, string],
    pub headers: Map[string, string],
    pub body: string,
    // and private fields
}

A request a server received.

method

GET, POST, ...

path

The path without the query: /users/7.

query

The query parameters, decoded: ?q=a+b gives "q": "a b".

headers

Header names in lower case.

Methods

pub fn header(self, name: string) -> Option[string]

A header, by name in any case.

pub fn param(self, name: string) -> Option[string]

A query parameter.

pub fn respond(self, r: Response) -> Result[i64, string]

Sends the response. The connection then stays open for the client's next request, unless the client or the response (a connection: close header) asks to close it.

struct Response

pub struct Response {
    pub status: i64,
    pub headers: Map[string, string],
    pub body: string,
}

A response: from a server, or to a client.

Methods

pub fn with_header(self, name: string, value: string) -> Response

The response with a header set.

pub fn header(self, name: string) -> Option[string]

A header, by name in any case.

pub fn ok(self) -> bool

Whether the status is 2xx.

struct Server

pub struct Server {
    pub max_body: i64,
    // and private fields
}

A server, waiting for requests.

max_body

The largest request body it accepts, in bytes; larger ones get 413.

Methods

pub fn with_max_body(self, bytes: i64) -> Server

The server with another largest request body, in bytes.

pub fn port(self) -> i64

The port the server listens on.

pub fn next(self) -> Result[Request, string]

Waits for the next request. A client that sends something that is not HTTP gets a 400 response, headers over 64 KiB get 431 and a body over the limit 413; the server then waits for the next request.

pub fn close(self)

Stops the server.

Functions

fn new_request

pub fn new_request(method: string, path: string, body: string) -> Request

A request that did not come over a connection, for testing a handler: respond on it fails.

fn response

pub fn response(status: i64, content_type: string, body: string) -> Response

A response with a body of the given content type.

fn text

pub fn text(status: i64, body: string) -> Response

A plain text response.

fn json

pub fn json(status: i64, body: string) -> Response

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

fn html

pub fn html(status: i64, body: string) -> Response

An HTML response.

fn not_found

pub fn not_found() -> Response

404 Not Found.

fn redirect

pub fn redirect(location: string) -> Response

A redirect to another location (302 Found).

fn reason

pub fn reason(status: i64) -> string

The standard reason phrase of a status code.

fn serve

pub fn serve(host: string, port: i64) -> Result[Server, string]

Starts a server on a host and port (port 0 picks a free one). It accepts request bodies up to 10 MiB; see with_max_body.

fn get

pub fn get(url: string) -> Result[Response, string]

GET a URL.

fn post

pub fn post(url: string, content_type: string, body: string) -> Result[Response, string]

POST a body of a content type to a URL.

fn request

pub fn request(
    method: string,
    url: string,
    headers: Map[string, string],
    body: string,
) -> Result[Response, string]

Sends a request and reads the response, for http:// and https:// URLs. Redirects are not followed.

fn decode

pub fn decode(text: string) -> Result[string, string]

Percent-decodes text: a%20b and a+b give a b.

fn encode

pub fn encode(text: string) -> string

Percent-encodes text for use in a URL: a b/c gives a%20b%2Fc.