Cookie parsing, validation, and jar management following RFC 6265.
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

OCaml 98.3%
Dune 0.5%
Other 1.2%
15 1 0

Clone this repository

https://tangled.org/gazagnaire.org/ocaml-cookie https://tangled.org/did:plc:jhift2vwcxhou52p3sewcrpx/ocaml-cookie
git@git.recoil.org:gazagnaire.org/ocaml-cookie git@git.recoil.org:did:plc:jhift2vwcxhou52p3sewcrpx/ocaml-cookie

For self-hosted knots, clone URLs may differ based on your setup.

Download tar.gz
README.md

Cookie - HTTP Cookie Management for OCaml#

Cookie parsing, validation, and jar management following RFC 6265.

Packages#

  • cookie (module Cookie): Cookie parsing, creation, and serialization. Handles Set-Cookie and Cookie headers with support for all attributes including SameSite, Partitioned (CHIPS), and HttpOnly.
  • cookie.jar (module Cookie_jar): Cookie jar storage with domain/path matching, delta tracking, and persistence in Mozilla format.

Installation#

Install with opam:

opam install nox-cookie

If opam cannot find the package, it may not yet be released in the public opam-repository. Add the overlay repository, then install it:

opam repo add samoht https://tangled.org/gazagnaire.org/opam-overlay.git
opam update
opam install nox-cookie
  • Domain: Tail matching for hostnames, exact match for IPs
  • Path: Prefix matching with "/" separator
  • Secure: HTTPS-only transmission
  • HttpOnly: No JavaScript access
  • Expires / Max-Age: Cookie lifetime (session cookies when omitted)
  • SameSite: Cross-site request behavior (Strict, Lax, None)
  • Partitioned: CHIPS partitioned storage (requires Secure)

Usage#

Parsing Headers#

let now () = Ptime_clock.now ()

(* Parse a Set-Cookie response header *)
let parse_set_cookie =
  Cookie.of_set_cookie_header ~now ~domain:"example.com" ~path:"/"
    "session=abc123; Secure; HttpOnly; SameSite=Strict"

(* Parse a Cookie request header *)
let parse_cookies =
  Cookie.of_request_header ~now ~domain:"example.com" ~path:"/"
    "session=abc123; theme=dark"

Serializing Headers#

let render_request (cookies : Cookie.t list) = Cookie.request_header cookies
let render_response (cookie : Cookie.t) = Cookie.set_cookie_header cookie

Creating Cookies#

let session_cookie ~now =
  Cookie.v ~domain:"example.com" ~path:"/" ~name:"session" ~value:"abc123"
    ~secure:true ~http_only:true ~same_site:`Strict ~creation_time:(now ())
    ~last_access:(now ()) ()
let api_cookies ~clock (cookie : Cookie.t) =
  let jar = Cookie_jar.v () in
  Cookie_jar.add_cookie jar cookie;
  let matching =
    Cookie_jar.cookies jar ~clock ~domain:"example.com" ~path:"/api"
      ~is_secure:true
  in
  Cookie.request_header matching

Delta Tracking#

let log_pending (jar : Cookie_jar.t) =
  Cookie_jar.delta jar
  |> List.iter (fun c -> Fmt.pr "%s@." (Cookie.set_cookie_header c))

Persistence#

Cookies are persisted in Mozilla format:

let save_jar ~path (jar : Cookie_jar.t) = Cookie_jar.save path jar
let load_jar ~clock ~path = Cookie_jar.load ~clock path

Validation#

The Cookie.Validate module enforces RFC 6265 server requirements:

# Cookie.Validate.cookie_name "session";;
- : (string, string) result = Ok "session"

# Cookie.Validate.cookie_value "abc;123";;
- : (string, string) result =
Error
 "Cookie value \"abc;123\" contains invalid characters: semicolon (0x3B). RFC 6265 cookie values may only contain printable ASCII excluding double-quote, comma, semicolon, and backslash"

# Cookie.Validate.domain_value "example.com";;
- : (string, string) result = Ok "example.com"

Licence#

ISC