Requests
Read headers and query parameters
The server owns request storage. request.header(name) looks up names without regard to ASCII case. request.param(name) percent-decodes a query value, including + as a space, and returns request-owned storage. Null means no value was found or storage could not be produced; an empty string is a present empty value.
import http
let greeting = fn (request:Http:Request*, response:Http:Response*) -> void {
let name = request.param("name")
if !name { response.text(400, "missing name"); return }
if name[0] == 0 { response.text(400, "empty name"); return }
response.text(200, name)
}Validate decoded input
For /hello?name=Ada+Lovelace, name is Ada Lovelace. Validate values according to the operation you perform; decoding does not validate application data.
Body length is authoritative
request.body_length counts bytes. A body can contain zero bytes, so do not measure binary data with strlen or treat it as an arbitrary null-terminated string.
import http
let echo_bytes = fn (request:Http:Request*, response:Http:Response*) -> void {
response.send(200, "application/octet-stream", request.body, request.body_length)
}Do not destroy handler arguments or free a returned parameter/header. For asynchronous work, make your own copy of the necessary bytes before the handler returns. Never store a borrowed request pointer for a later job.