OCaml HTTP cookie handling library with support for Eio-based storage jars
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%
5 1 0

Clone this repository

https://tangled.org/anil.recoil.org/ocaml-cookeio https://tangled.org/did:plc:nhyitepp3u4u6fcfboegzcjw/ocaml-cookeio
git@git.recoil.org:anil.recoil.org/ocaml-cookeio git@git.recoil.org:did:plc:nhyitepp3u4u6fcfboegzcjw/ocaml-cookeio

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#

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

(* Parse a Cookie request header *)
let cookies =
  Cookie.of_cookie_header
    ~now:(fun () -> Ptime_clock.now ())
    ~domain:"example.com"
    ~path:"/"
    "session=abc123; theme=dark"

Serializing Headers#

(* Generate a Cookie request header from a list of cookies *)
let header = Cookie.cookie_header cookies
(* "session=abc123; theme=dark" *)

(* Generate a Set-Cookie response header *)
let header = Cookie.set_cookie_header cookie

Creating Cookies#

let cookie =
  Cookie.v
    ~domain:"example.com"
    ~path:"/"
    ~name:"session"
    ~value:"abc123"
    ~secure:true
    ~http_only:true
    ~same_site:`Strict
    ~creation_time:(Ptime_clock.now ())
    ~last_access:(Ptime_clock.now ())
    ()
let jar = Cookie_jar.v ()
let () = Cookie_jar.add_cookie jar cookie

let matching =
  Cookie_jar.cookies jar
    ~clock
    ~domain:"example.com"
    ~path:"/api"
    ~is_secure:true

let header = Cookie.cookie_header matching

Delta Tracking#

let new_cookies = Cookie_jar.delta jar
let () =
  List.iter
    (fun c -> print_endline (Cookie.set_cookie_header c))
    new_cookies

Persistence#

Cookies are persisted in Mozilla format:

let () = Cookie_jar.save path jar
let jar = Cookie_jar.load ~clock path

Validation#

The Cookie.Validate module enforces RFC 6265 server requirements:

Cookie.Validate.cookie_name "session"      (* Ok "session" *)
Cookie.Validate.cookie_value "abc;123"     (* Error "..." *)
Cookie.Validate.domain_value "example.com" (* Ok "example.com" *)

Licence#

ISC