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
-
ServerInfo(scheme: http.Scheme, ip_address: IpAddress, port: Int)
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 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 aschunked
,BodyTooLarge
error is returned if accumulated body is larger thansize_limit
. - Ensures that
content-length
is insize_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_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_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.