fcgi
FastCGI Responder server.
Types
Listen address set on a Builder via listen_unix or listen_tcp.
pub opaque type Address
Server configuration produced by new. Pass it to start to begin
listening.
pub opaque type Builder(address)
Trusted CGI metadata supplied by the upstream proxy and handed to
every request handler alongside the Request.
pub type Context {
Context(
remote_addr: option.Option(String),
remote_port: option.Option(Int),
remote_host: option.Option(String),
remote_user: option.Option(String),
auth_type: option.Option(String),
script_name: option.Option(String),
server_protocol: option.Option(String),
server_software: option.Option(String),
extra: dict.Dict(String, String),
)
}
Constructors
-
Context( remote_addr: option.Option(String), remote_port: option.Option(Int), remote_host: option.Option(String), remote_user: option.Option(String), auth_type: option.Option(String), script_name: option.Option(String), server_protocol: option.Option(String), server_software: option.Option(String), extra: dict.Dict(String, String), )Arguments
- remote_addr
-
Client address as reported by the proxy (CGI
REMOTE_ADDR). - remote_port
-
Client port parsed as
Int; absent if the proxy did not supply a numeric value (CGIREMOTE_PORT). - remote_host
-
Reverse-DNS hostname of the client, when the proxy resolved one (CGI
REMOTE_HOST). - remote_user
-
Authenticated identity, when the proxy set one (CGI
REMOTE_USER). - auth_type
-
Authentication scheme, e.g.
"Basic"(CGIAUTH_TYPE). - script_name
-
Mount prefix assigned to the app by the proxy (CGI
SCRIPT_NAME). - server_protocol
-
HTTP protocol version reported by the proxy, e.g.
"HTTP/1.1"(CGISERVER_PROTOCOL). - server_software
-
Identification string from the upstream proxy (CGI
SERVER_SOFTWARE). - extra
-
Any other CGI variables, keyed by their original uppercase name. Typical entries include
"DOCUMENT_ROOT"and"REQUEST_URI".
Why send_file could not produce a File body.
pub type FileError {
FileNotFound(path: String)
FileAccessDenied(path: String)
FileIsDirectory(path: String)
FileOther(path: String, reason: String)
InvalidRange(offset: Int, limit: option.Option(Int))
}
Constructors
-
FileNotFound(path: String)No file exists at the given path.
-
FileAccessDenied(path: String)The process lacks permission to read the file.
-
FileIsDirectory(path: String)The path resolved to a directory, not a file.
-
FileOther(path: String, reason: String)Any other filesystem error, with the underlying reason as a human-readable string.
-
InvalidRange(offset: Int, limit: option.Option(Int))offsetis negative, orlimitisSome(n)withn < 0.
Why a body read failed.
pub type ReadError {
ClientDisconnected
ReadTimeout
BodyTooLarge
RequestAborted
}
Constructors
-
ClientDisconnectedThe connection from the upstream proxy was closed before the body was fully delivered.
-
ReadTimeoutNo chunk arrived within the configured
body_read_timeout. -
BodyTooLargeThe body exceeded
max_body_size. -
RequestAbortedThe upstream proxy sent
FCGI_ABORT_REQUESTor an unrecoverable framing error while the handler was reading the body. The connection will be closed after the handler returns and the handler’s response, if any, is discarded.
What the server should send back as a response body. Construct with
bytes, send_file, or stream.
pub opaque type ResponseData
Running server returned by start. bound_port is Some(port) for a
TCP listener (useful when listen_tcp was given port 0 and the
kernel chose an ephemeral port) and None for a Unix-domain listener.
pub type Server {
Server(
supervisor: static_supervisor.Supervisor,
bound_port: option.Option(Int),
)
}
Constructors
-
Server( supervisor: static_supervisor.Supervisor, bound_port: option.Option(Int), )
Why the listener could not start.
pub type StartError {
ListenerError(reason: String)
InvalidMaxBodySize(bytes: Int)
InvalidBodyReadTimeout(milliseconds: Int)
}
Constructors
-
ListenerError(reason: String)Wraps a failure from the underlying listener, such as bind or listen failures, an unparseable TCP host, or a Unix-socket path that is already in use.
-
InvalidMaxBodySize(bytes: Int)max_body_sizewas set to a negative value. -
InvalidBodyReadTimeout(milliseconds: Int)body_read_timeoutwas set to zero or a negative value.
Use send_chunk to emit body bytes; each call writes one or more FastCGI
STDOUT records on the open connection.
pub opaque type StreamSender
Values
pub fn body_read_timeout(
builder: Builder(address),
milliseconds: Int,
) -> Builder(address)
Set how long the server waits for the next stdin or params record
before giving up. Must be > 0. Applies between successive socket
reads, including the wait for the first record after accept, not
to the request as a whole. Returns Error(ReadTimeout) to body
readers. Default: 30,000 ms.
pub fn bytes(content: bytes_tree.BytesTree) -> ResponseData
Build an in-memory response body. The whole BytesTree is sent in
one or more STDOUT records.
pub fn listen_tcp(
builder: Builder(address),
host host: String,
port port: Int,
) -> Builder(Address)
Set the TCP host and port the server listens on. host must be a
numeric IP literal: either IPv4 (e.g. "127.0.0.1", "0.0.0.0") or
IPv6 (e.g. "::1", "::").
pub fn listen_unix(
builder: Builder(address),
path: String,
) -> Builder(Address)
Set the Unix domain socket path the server listens on.
pub fn max_body_size(
builder: Builder(address),
bytes: Int,
) -> Builder(address)
Set the maximum body bytes the server will deliver to the handler in
total across all body reads. Must be >= 0; start returns
InvalidMaxBodySize(bytes) for negative values.
When the peer sends more than this many bytes, the next body read
returns Error(BodyTooLarge). The handler may respond as it sees fit,
but the connection is closed after the response is sent because
remaining body bytes cannot be safely drained.
Default: 256 MiB.
pub fn new(
handler: fn(
request.Request(fn() -> Result(Read, ReadError)),
Context,
) -> response.Response(ResponseData),
) -> Builder(Nil)
Build a new FastCGI server with the given handler.
The handler is invoked once Params is fully received. The request
body is delivered incrementally via a BodyReader in req.body;
call it to obtain the first Read and thread consume to advance,
or pass it to read_all for the buffered case.
Default: 256 MiB max body, 30 s body read timeout.
pub fn read_all(
read: fn() -> Result(Read, ReadError),
) -> Result(bytes_tree.BytesTree, ReadError)
Buffer the entire body into a BytesTree. The server’s
max_body_size setting is the upper bound; the underlying reader
returns BodyTooLarge if the peer exceeds it.
The buffered length reflects what the upstream proxy actually sent,
not what CONTENT_LENGTH advertised.
pub fn send_chunk(
sender: StreamSender,
data: bytes_tree.BytesTree,
) -> Result(Nil, Nil)
Emit a chunk of body bytes from inside a Stream producer.
Returns Ok(Nil) when the chunk is written, or Error(Nil) when the
underlying socket write fails (for example, the upstream proxy has
disconnected).
pub fn send_file(
path path: String,
offset offset: Int,
limit limit: option.Option(Int),
) -> Result(ResponseData, FileError)
Open a file and return a response body that streams it via
file:sendfile/5 when the response is sent.
Returns FileError if the file is missing, inaccessible, a
directory, or if offset or limit is negative.
pub fn start(
builder: Builder(Address),
) -> Result(actor.Started(Server), StartError)
Start the server.
pub fn stream(producer: fn(StreamSender) -> Nil) -> ResponseData
Build a streaming response body. The server calls producer(sender)
after sending the response headers; each call to send_chunk(sender, data) writes one or more STDOUT records to the upstream proxy.
A panic raised by producer is caught; the response end records are
still emitted so the upstream proxy sees a clean end-of-request.
pub fn supervised(
builder: Builder(Address),
) -> supervision.ChildSpecification(Server)
Build a supervision.ChildSpecification so the server runs under an
OTP supervisor.