mist

Types

pub opaque type Builder(request_body, response_body)

These are the types of errors raised by trying to read the certificate and key files.

pub type CertificateError {
  NoCertificate
  NoKey
  NoKeyOrCertificate
}

Constructors

  • NoCertificate
  • NoKey
  • NoKeyOrCertificate

The values returning from streaming the request body. The Chunk variant gives back some data and the next token. Done signifies that we have completed reading the body.

pub type Chunk {
  Chunk(
    data: BitArray,
    consume: fn(Int) -> Result(Chunk, ReadError),
  )
  Done
}

Constructors

  • Chunk(
      data: BitArray,
      consume: fn(Int) -> Result(Chunk, ReadError),
    )
  • Done

Re-exported type that represents the default Request body type. See mist.read_body to convert this type into a BitString. The Connection also holds some additional information about the request. Currently, the only useful field is client_ip which is a Result with a tuple of integers representing the IPv4 address.

pub type Connection =
  InternalConnection
pub type ConnectionInfo {
  ConnectionInfo(port: Int, ip_address: IpAddress)
}

Constructors

  • ConnectionInfo(port: Int, ip_address: IpAddress)

Potential errors when opening a file to send. This list is currently not exhaustive with POSIX errors.

pub type FileError {
  IsDir
  NoAccess
  NoEntry
  UnknownFileError
}

Constructors

  • IsDir
  • NoAccess
  • NoEntry
  • UnknownFileError

These are the possible errors raised when trying to start an Https server. If there are issues reading the certificate or key files, those will be returned.

pub type HttpsError {
  GlistenError(glisten.StartError)
  CertificateError(CertificateError)
}

Constructors

  • GlistenError(glisten.StartError)
  • CertificateError(CertificateError)

When accessing client information, these are the possible shapes of the IP addresses. A best effort will be made to determine whether IPv4 is most relevant.

pub type IpAddress {
  IpV4(Int, Int, Int, Int)
  IpV6(Int, Int, Int, Int, Int, Int, Int, Int)
}

Constructors

  • IpV4(Int, Int, Int, Int)
  • IpV6(Int, Int, Int, Int, Int, Int, Int, Int)
pub type Port {
  Assigned
  Provided(Int)
}

Constructors

  • Assigned
  • Provided(Int)

The possible errors from reading the request body. If the size is larger than the provided value, ExcessBody is returned. If there is an error reading the body from the socket or the body is malformed (i.e a chunked request with invalid sizes), MalformedBody is returned.

pub type ReadError {
  ExcessBody
  MalformedBody
}

Constructors

  • ExcessBody
  • MalformedBody

The response body type. This allows mist to handle these different cases for you. Bytes is the regular data return. Websocket will upgrade the socket to websockets, but should not be used directly. See the mist.upgrade function for usage. Chunked will use Transfer-Encoding: chunked to send an iterator in chunks. File will use Erlang’s sendfile to more efficiently return a file to the client.

pub type ResponseData {
  Websocket(Selector(ProcessDown))
  Bytes(BytesBuilder)
  Chunked(Iterator(BytesBuilder))
  File(descriptor: file.FileDescriptor, offset: Int, length: Int)
  ServerSentEvents(Selector(ProcessDown))
}

Constructors

  • Websocket(Selector(ProcessDown))
  • Bytes(BytesBuilder)
  • Chunked(Iterator(BytesBuilder))
  • File(descriptor: file.FileDescriptor, offset: Int, length: Int)

    See mist.send_file to use this response type.

  • ServerSentEvents(Selector(ProcessDown))
pub opaque type SSEConnection
pub opaque type SSEEvent
pub opaque type Server
pub type WebsocketConnection =
  InternalWebsocketConnection

These are the types of messages that a websocket handler may receive.

pub type WebsocketMessage(custom) {
  Text(String)
  Binary(BitArray)
  Closed
  Shutdown
  Custom(custom)
}

Constructors

  • Text(String)
  • Binary(BitArray)
  • Closed
  • Shutdown
  • Custom(custom)

Functions

pub fn after_start(
  builder: Builder(a, b),
  after_start: fn(Int, Scheme, IpAddress) -> Nil,
) -> Builder(a, b)

Override the default function to be called after the service starts. The default is to log a message with the listening port.

pub fn bind(
  builder: Builder(a, b),
  interface: String,
) -> Builder(a, b)

Specify an interface to listen on. This is a string that can have the following values: “localhost”, a valid IPv4 address (i.e. “127.0.0.1”), or a valid IPv6 address (i.e. “::1”). An invalid value will cause the application to crash.

pub fn event(data: StringBuilder) -> SSEEvent
pub fn event_id(event: SSEEvent, id: String) -> SSEEvent
pub fn event_name(event: SSEEvent, name: String) -> SSEEvent
pub fn get_client_info(
  conn: Connection,
) -> Result(ConnectionInfo, Nil)

Tries to get the IP address and port of a connected client.

pub fn get_port(server: Server) -> Int
pub fn get_supervisor(server: Server) -> Subject(Message)
pub fn ip_address_to_string(address: IpAddress) -> String

Convenience function for printing the IpAddress type. It will convert the IPv6 loopback to the short-hand ::1.

pub fn new(
  handler: fn(Request(a)) -> Response(b),
) -> Builder(a, b)

Create a new mist handler with a given function. The default port is 4000.

pub fn port(builder: Builder(a, b), port: Int) -> Builder(a, b)

Assign a different listening port to the service.

pub fn read_body(
  req: Request(Connection),
  max_body_limit max_body_limit: Int,
) -> Result(Request(BitArray), ReadError)

The request body is not pulled from the socket until requested. The content-length header is used to determine whether the socket is read from or not. The read may also fail, and a ReadError is raised.

pub fn read_request_body(
  builder: Builder(BitArray, a),
  bytes_limit bytes_limit: Int,
  failure_response failure_response: Response(a),
) -> Builder(Connection, a)

This function allows for implicitly reading the body of requests up to a given size. If the size is too large, or the read fails, the provided failure_response will be sent back as the response.

pub fn send_binary_frame(
  connection: WebsocketConnection,
  frame: BitArray,
) -> Result(Nil, SocketReason)

Sends a binary frame across the websocket.

pub fn send_event(
  conn: SSEConnection,
  event: SSEEvent,
) -> Result(Nil, Nil)
pub fn send_file(
  path: String,
  offset offset: Int,
  limit limit: Option(Int),
) -> Result(ResponseData, FileError)

To respond with a file using Erlang’s sendfile, use this function with the specified offset and limit (optional). It will attempt to open the file for reading, get its file size, and then send the file. If the read errors, this will return the relevant FileError. Generally, this will be more memory efficient than manually doing this process with mist.Bytes.

pub fn send_text_frame(
  connection: WebsocketConnection,
  frame: String,
) -> Result(Nil, SocketReason)

Sends a text frame across the websocket.

pub fn server_sent_events(
  request req: Request(Connection),
  initial_response resp: Response(a),
  init init: fn() -> InitResult(b, c),
  loop loop: fn(c, SSEConnection, b) -> Next(c, b),
) -> Response(ResponseData)

Sets up the connection for server-sent events. The initial response provided here will have its headers included in the SSE setup. The body is discarded. The init and loop parameters follow the same shape as the gleam/otp/actor module.

NOTE: There is no proper way within the spec for the server to “close” the SSE connection. There are ways around it.

See: examples/eventz for a sample usage.

pub fn start_http(
  builder: Builder(Connection, ResponseData),
) -> Result(Subject(Message), StartError)

Start a mist service over HTTP with the provided builder.

pub fn start_http_server(
  builder: Builder(Connection, ResponseData),
) -> Result(Server, StartError)

See the documentation for start_http. For now, you almost certainly want to use that. In the future, this will allow access to things like OS-provided ports, graceful shutdown, etc.

pub fn start_https(
  builder: Builder(Connection, ResponseData),
  certfile certfile: String,
  keyfile keyfile: String,
) -> Result(Subject(Message), HttpsError)

Start a mist service over HTTPS with the provided builder. This method requires both a certificate file and a key file. The library will attempt to read these files off of the disk.

pub fn start_https_server(
  builder: Builder(Connection, ResponseData),
  certfile certfile: String,
  keyfile keyfile: String,
) -> Result(Server, HttpsError)

See the documentation for start_https. For now, you almost certainly want to use that. In the future, this will allow access to things like OS-provided ports, graceful shutdown, etc.

pub fn stream(
  req: Request(Connection),
) -> Result(fn(Int) -> Result(Chunk, ReadError), ReadError)

Rather than explicitly reading either the whole body (optionally up to N bytes), this function allows you to consume a stream of the request body. Any errors reading the body will propagate out, or Chunks will be emitted. This provides a consume method to attempt to grab the next size chunk from the socket.

pub fn websocket(
  request request: Request(Connection),
  handler handler: fn(a, WebsocketConnection, WebsocketMessage(b)) ->
    Next(b, a),
  on_init on_init: fn(WebsocketConnection) ->
    #(a, Option(Selector(b))),
  on_close on_close: fn(a) -> Nil,
) -> Response(ResponseData)

Upgrade a request to handle websockets. If the request is malformed, or the websocket process fails to initialize, an empty 400 response will be sent to the client.

The on_init method will be called when the actual WebSocket process is started, and the return value is the initial state and an optional selector for receiving user messages.

The on_close method is called when the WebSocket process shuts down for any reason, valid or otherwise.

pub fn with_ipv6(builder: Builder(a, b)) -> Builder(a, b)

By default, mist will listen on localhost over IPv4. If you specify an IPv4 address to bind to, it will still only serve over IPv4. Calling this function will listen on both IPv4 and IPv6 for the given interface. If it is not supported, your application will crash. If you provide an IPv6 address to mist.bind, this function will have no effect.

Search Document