Packages

A Gleam HTTP service adapter for the Plug web application interface

Current section

Files

Jump to
gleam_plug src gleam http plug.gleam
Raw

src/gleam/http/plug.gleam

import gleam/http
import gleam/result
import gleam/option.{None, Option, Some}
import gleam/dynamic.{Dynamic}
import gleam/bit_builder.{BitBuilder}
pub external type Conn
pub external fn port(Conn) -> Int =
"Elixir.GleamPlug" "port"
pub external fn host(Conn) -> String =
"Elixir.GleamPlug" "host"
pub external fn scheme(Conn) -> http.Scheme =
"Elixir.GleamPlug" "scheme"
external fn elixir_method(Conn) -> Dynamic =
"Elixir.GleamPlug" "method"
pub fn method(conn: Conn) -> http.Method {
conn
|> elixir_method
|> http.method_from_dynamic
|> result.unwrap(http.Get)
}
pub external fn request_path(Conn) -> String =
"Elixir.GleamPlug" "request_path"
pub external fn req_headers(Conn) -> List(http.Header) =
"Elixir.GleamPlug" "req_headers"
external fn elixir_query_string(Conn) -> String =
"Elixir.GleamPlug" "query_string"
pub fn query_string(conn: Conn) -> Option(String) {
case elixir_query_string(conn) {
"" -> None
q -> Some(q)
}
}
/// Convert a Plug connection to a Gleam HTTP request which can be
/// used to call a Gleam HTTP service.
///
/// It is common Plug applications to extract and decode the request
/// body using a middleware so this function does not attempt to read
/// the body directly from the conn, instead it must be given as the
/// second argument.
///
pub fn conn_to_request(conn: Conn, body: a) -> http.Request(a) {
http.Request(
body: body,
headers: req_headers(conn),
host: host(conn),
path: request_path(conn),
method: method(conn),
port: Some(port(conn)),
query: query_string(conn),
scheme: scheme(conn),
)
}
external fn send_resp(conn: Conn, status: Int, body: BitBuilder) -> Conn =
"Elixir.Plug.Conn" "send_resp"
external fn merge_resp_headers(conn: Conn, headers: List(http.Header)) -> Conn =
"Elixir.Plug.Conn" "merge_resp_headers"
/// Send a Gleam HTTP response over the Plug connection.
///
/// Note that this function does not halt the connection, so if subsequent
/// plugs try to send another response, it will error out. Use the `halt`
/// function after this function if you want to halt the plug pipeline.
///
pub fn send(response: http.Response(BitBuilder), conn: Conn) -> Conn {
conn
|> merge_resp_headers(response.headers)
|> send_resp(response.status, response.body)
}
/// Halts the Plug pipeline by preventing further plugs downstream from being
/// invoked. See the docs for Plug.Builder for more information on halting a
/// Plug pipeline.
///
pub external fn halt(Conn) -> Conn =
"Elixir.Plug.Conn" "halt"