ewe

IP Address

Information

Builder

Server

Request

Response

Websocket

Experimental

Types

Possible errors that can occur when reading a body.

pub type BodyError {
  BodyTooLarge
  InvalidBody
}

Constructors

  • BodyTooLarge
  • InvalidBody

Ewe’s server builder. Contains all server’s configuration. Can be adjusted with the following functions:

  • ewe.bind
  • ewe.bind_all
  • ewe.with_read_body
  • ewe.with_port
  • ewe.with_random_port
  • ewe.with_ipv6
  • ewe.with_tls
  • ewe.with_name
  • ewe.on_start
  • ewe.on_crash
pub opaque type Builder(body)

Represents a connection between a client and a server, stored inside a Request. Can be converted to a BitArray using ewe.read_body.

pub type Connection =
  @internal Connection

Represents an IP address. Appears when accessing client’s information (ewe.client_stats) or on_start handler (ewe.on_start).

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)

Represents instruction on how WebSocket connection should proceed.

  • continue processing the WebSocket connection.
  • stop the WebSocket connection.
  • stop the WebSocket connection with abnormal reason.
pub opaque type Next(user_state)

Represents a response body. To set the response body, use the following functions:

  • ewe.text
  • ewe.bytes
  • ewe.bits
  • ewe.string_tree
  • ewe.empty
  • ewe.json
pub opaque type ResponseBody

Represents started server’s information. Can be retrieved using ewe.get_server_info.

pub type ServerInfo {
  ServerInfo(
    scheme: http.Scheme,
    ip_address: IpAddress,
    port: Int,
  )
}

Constructors

pub type WebsocketConnection =
  @internal WebsocketConnection

Represents a WebSocket message received from the client.

pub type WebsocketMessage(user_message) {
  Text(String)
  Binary(BitArray)
  User(user_message)
}

Constructors

  • Text(String)
  • Binary(BitArray)
  • User(user_message)

Values

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

Binds server to a specific interface. Crashes program if interface is invalid.

pub fn bind_all(builder: Builder(body)) -> Builder(body)

Binds server to all interfaces.

pub fn bits(
  response: response.Response(a),
  bits: BitArray,
) -> response.Response(ResponseBody)

Sets response body from bits, sets content-length header. Doesn’t set content-type header.

pub fn bytes(
  response: response.Response(a),
  bytes: bytes_tree.BytesTree,
) -> response.Response(ResponseBody)

Sets response body from bytes, sets content-length header. Doesn’t set content-type header.

pub fn continue(user_state: user_state) -> Next(user_state)

Instructs WebSocket connection to continue processing.

pub fn empty(
  response: response.Response(a),
) -> response.Response(ResponseBody)

Sets response body to empty, sets content-length header to 0.

pub fn get_client_info(
  connection: @internal Connection,
) -> Result(#(IpAddress, Int), Nil)

Performs an attempt to get the client’s IP address and port.

pub fn get_server_info(
  name: process.Name(@internal Message(ServerInfo)),
) -> Result(ServerInfo, Nil)

Retrieves server’s information. Requires the same name as the one used in ewe.with_name and server to be started. Otherwise, will crash the program.

pub fn ip_address_to_string(address: IpAddress) -> String

Converts an IpAddress to a string for later printing.

pub fn json(
  response: response.Response(a),
  json: string_tree.StringTree,
) -> response.Response(ResponseBody)

Sets response body from string tree (use gleam_json package and encode using json.to_string_tree), sets content-type to application/json; charset=utf-8 and content-length headers.

pub fn new(
  handler: fn(request.Request(body)) -> response.Response(
    ResponseBody,
  ),
) -> Builder(body)

Creates new server builder with handler provided.

Default configuration:

  • port: 8080
  • interface: 127.0.0.1
  • No ipv6 support
  • No TLS support
  • Default process name for server information retrieval
  • on_start: prints Listening on <scheme>://<ip_address>:<port>
  • on_crash: empty 500 response
pub fn on_crash(
  builder: Builder(body),
  on_crash: response.Response(ResponseBody),
) -> Builder(body)

Sets a custom response that will be sent when server crashes.

pub fn on_start(
  builder: Builder(body),
  on_start: fn(ServerInfo) -> Nil,
) -> Builder(body)

Sets a custom handler that will be called after server starts.

pub fn read_body(
  req: request.Request(@internal Connection),
  size_limit size_limit: Int,
) -> Result(request.Request(BitArray), BodyError)

Reads body from a request. If request body is malformed, InvalidBody error is returned. On success, returns a request with body converted to BitArray.

  • When transfer-encoding header set as chunked, BodyTooLarge error is returned if accumulated body is larger than size_limit.
  • Ensures that content-length is in size_limit scope.
pub fn send_binary_frame(
  conn: @internal WebsocketConnection,
  bits: BitArray,
) -> Result(Nil, socket.SocketReason)

Sends a binary frame to the websocket client.

pub fn send_text_frame(
  conn: @internal WebsocketConnection,
  text: String,
) -> Result(Nil, socket.SocketReason)

Sends a text frame to the websocket client.

pub fn start(
  builder: Builder(@internal Connection),
) -> Result(
  actor.Started(static_supervisor.Supervisor),
  actor.StartError,
)

Starts the server.

pub fn stop() -> Next(user_state)

Instructs WebSocket connection to stop.

pub fn stop_abnormal(reason: String) -> Next(user_state)

Instructs WebSocket connection to stop with abnormal reason.

pub fn string_tree(
  response: response.Response(a),
  string_tree: string_tree.StringTree,
) -> response.Response(ResponseBody)

Sets response body from string tree, sets content-length header. Doesn’t set content-type header.

pub fn supervised(
  builder: Builder(@internal Connection),
) -> supervision.ChildSpecification(static_supervisor.Supervisor)

Creates a supervisor that can be appended to a supervision tree.

pub fn text(
  response: response.Response(a),
  text: String,
) -> response.Response(ResponseBody)

Sets response body from string, sets content-type to text/plain; charset=utf-8 and content-length headers.

pub fn upgrade_websocket(
  req: request.Request(@internal Connection),
  on_init on_init: fn(
    @internal WebsocketConnection,
    process.Selector(user_message),
  ) -> #(user_state, process.Selector(user_message)),
  handler handler: fn(
    @internal WebsocketConnection,
    user_state,
    WebsocketMessage(user_message),
  ) -> Next(user_state),
) -> response.Response(ResponseBody)

Upgrade request to a WebSocket connection. If the initial request is not valid for WebSocket upgrade, 400 response is sent. Handler must return instruction on how WebSocket connection should proceed.

pub fn use_expression(
  handler: fn() -> Result(
    response.Response(ResponseBody),
    response.Response(ResponseBody),
  ),
) -> response.Response(ResponseBody)

Experimental function that simplifies error handling in handlers when working with Result type.

Example

pub fn handle_echo(
  req: Request(ewe.Connection),
) -> Response(bytes_tree.BytesTree) {
  let content_type =
    request.get_header(req, "content-type")
    |> result.unwrap("text/plain")

   // Start the use_expression block
   use <- ewe.use_expression()

   // Now you can use result.try with use expressions
   // If any step fails, the error response is automatically returned
   use req <- result.try(
     ewe.read_body(req, 1024)
     |> result.replace_error(
       response.new(400)
       |> ewe.json(error_json("Invalid request body")),
     ),
   )

   response.new(200)
   |> ewe.bits(req.body)
   |> response.set_header("content-type", content_type)
   |> Ok 
}
pub fn with_ipv6(builder: Builder(body)) -> Builder(body)

Enables IPv6 support.

pub fn with_name(
  builder: Builder(body),
  name: process.Name(@internal Message(ServerInfo)),
) -> Builder(body)

Sets a custom process name for server information retrieval, allowing to use ewe.get_server_info after server starts.

pub fn with_port(
  builder: Builder(body),
  port: Int,
) -> Builder(body)

Sets listening port for server.

pub fn with_random_port(builder: Builder(body)) -> Builder(body)

Sets listening port for server to a random port. Useful for testing.

pub fn with_tls(
  builder: Builder(body),
  certificate: String,
  keyfile: String,
) -> Builder(body)

Enables TLS support, requires certificate and key file.

Search Document