brazier/cookie

Types

Why a cookie could not be set. Values are never included: they are often secrets.

pub type CookieError {
  InvalidName(name: String)
  InvalidValue(name: String)
  InvalidPath(name: String, path: String)
  InvalidSameSite(name: String, same_site: String)
  InsecureSameSiteNone(name: String)
  NegativeMaxAge(name: String, max_age: Int)
  PrefixViolation(name: String, reason: String)
  TooLarge(name: String, bytes: Int)
}

Constructors

  • InvalidName(name: String)

    The name is empty or not an RFC 7230 token.

  • InvalidValue(name: String)

    The value contains bytes outside the RFC 6265 cookie-octet set.

  • InvalidPath(name: String, path: String)

    The path is empty, does not start with “/”, or has a CTL or “;”.

  • InvalidSameSite(name: String, same_site: String)

    SameSite is not exactly “Strict”, “Lax” or “None”.

  • InsecureSameSiteNone(name: String)

    SameSite=None without Secure is rejected by browsers.

  • NegativeMaxAge(name: String, max_age: Int)

    Max-Age is negative.

  • PrefixViolation(name: String, reason: String)

    A __Secure- or __Host- prefix requirement is not met.

  • TooLarge(name: String, bytes: Int)

    Name and value together exceed max_name_value_bytes, or the path exceeds max_attribute_bytes. Browsers drop such cookies silently.

Options for setting a cookie.

pub type CookieOptions {
  CookieOptions(
    max_age: option.Option(Int),
    path: String,
    http_only: Bool,
    secure: Bool,
    same_site: String,
  )
}

Constructors

  • CookieOptions(
      max_age: option.Option(Int),
      path: String,
      http_only: Bool,
      secure: Bool,
      same_site: String,
    )

    Arguments

    max_age

    Max age in seconds. None = session cookie. Must be >= 0.

    path

    Cookie path. Must start with “/”. Defaults to “/”.

    http_only

    HttpOnly flag — prevents JavaScript access.

    secure

    Secure flag — only sent over HTTPS.

    same_site

    SameSite attribute: “Strict”, “Lax”, or “None” (“None” requires secure: True).

Values

pub fn default_options() -> CookieOptions

Default cookie options — secure, HttpOnly, SameSite=Lax, path=“/”. Production defaults — Secure=True requires HTTPS. Set secure=False for local dev.

pub fn delete(
  resp: response.Response(body),
  name: String,
) -> Result(response.Response(body), CookieError)

Delete a cookie set with default_options() (Secure, HttpOnly, SameSite=Lax, path “/”): an empty value with Max-Age=0.

pub fn delete_with_options(
  resp: response.Response(body),
  name: String,
  opts: CookieOptions,
) -> Result(response.Response(body), CookieError)

Delete a cookie using the same path/security attributes used to set it.

pub fn error_to_string(error: CookieError) -> String

Human-readable description of a cookie error.

pub fn get(
  req: request.Request(body),
  name: String,
) -> Result(String, Nil)

Get a single cookie value by name from a request. When the browser sent several cookies with the same name (different paths or domains), the first one wins, as in Plug. Use a __Host- name to stop a sibling subdomain from planting a same-named cookie.

case cookie.get(request, "session_token") {
  Ok(token) -> validate(token)
  Error(Nil) -> redirect_to_login()
}
pub const max_attribute_bytes: Int

RFC 6265bis: browsers ignore attribute values over 1024 bytes.

pub const max_name_value_bytes: Int

RFC 6265bis: browsers ignore cookies whose name and value together exceed 4096 bytes.

pub fn parse(
  req: request.Request(body),
) -> List(#(String, String))

Parse all cookies from a request’s Cookie header(s). Returns a list of (name, value) pairs in header order. Pairs without = or with an empty name are skipped. Several Cookie headers (as HTTP/2 proxies may send) are read in order.

let cookies = cookie.parse(request)
// [#("session", "abc123"), #("theme", "dark")]
pub fn set(
  resp: response.Response(body),
  name: String,
  value: String,
  opts: CookieOptions,
) -> Result(response.Response(body), CookieError)

Set a cookie on a response with the given options. A response carries at most one Set-Cookie per name: setting a name again replaces it.

use resp <- result.try(
  response.new(200)
  |> cookie.set("session", token, cookie.default_options()),
)
pub fn set_default(
  resp: response.Response(body),
  name: String,
  value: String,
) -> Result(response.Response(body), CookieError)

Set a cookie with default options (secure, HttpOnly, SameSite=Lax).

pub fn validate(
  name: String,
  value: String,
  opts: CookieOptions,
) -> Result(Nil, CookieError)

Check a complete cookie: name, value and options.

pub fn validate_options(
  name: String,
  opts: CookieOptions,
) -> Result(Nil, CookieError)

Check a cookie’s name and options without a value. Use it to reject a bad configuration before doing work whose result is a cookie.

✨ Search Document