Cookie jar for storing and managing HTTP cookies.
This module provides a complete cookie jar implementation following RFC 6265 while integrating Eio for efficient asynchronous operations.
A cookie jar maintains a collection of cookies with automatic cleanup of expired entries. It implements the standard browser behavior for cookie storage, including:
- Automatic removal of expired cookies
- Domain and path-based cookie retrieval per Section 5.4
- Delta tracking for Set-Cookie headers
- Mozilla format persistence for cross-tool compatibility
Standards and References
This cookie jar implements the storage model from:
- RFC 6265 Section 5.3 - Storage Model - Cookie insertion, replacement, and expiration
- RFC 6265 Section 5.4 - The Cookie Header - Cookie retrieval and ordering
Key RFC 6265 requirements implemented:
- Domain matching per Section 5.1.3
- Path matching per Section 5.1.4
- Cookie ordering per Section 5.4 Step 2
- Creation time preservation per Section 5.3 Step 11.3
Related Libraries
Cookeio- HTTP cookie parsing, validation, and serializationRequests- HTTP client that uses this jar for cookie persistenceXdge- XDG Base Directory support for cookie file paths
Cookie jar for storing and managing cookies.
A cookie jar maintains a collection of cookies with automatic cleanup of expired entries and enforcement of storage limits. It implements the standard browser behavior for cookie storage per RFC 6265 Section 5.3.
Cookie Jar Creation and Loading
val create : unit -> tCreate an empty cookie jar.
val load : clock:_ Eio.Time.clock -> Eio.Fs.dir_ty Eio.Path.t -> tLoad cookies from Mozilla format file.
Loads cookies from a file in Mozilla format, using the provided clock to set creation and last access times. Returns an empty jar if the file doesn't exist or cannot be loaded.
val save : Eio.Fs.dir_ty Eio.Path.t -> t -> unitSave cookies to Mozilla format file.
Cookie Jar Management
Add a cookie to the jar.
The cookie is added to the delta, meaning it will appear in Set-Cookie headers when calling delta. If a cookie with the same name/domain/path exists, it will be replaced per RFC 6265 Section 5.3.
Per Section 5.3, Step 11.3, when replacing an existing cookie, the original creation-time is preserved. This ensures stable cookie ordering per Section 5.4, Step 2.
Add an original cookie to the jar.
Original cookies are those received from the client (via Cookie header). They do not appear in the delta. This method should be used when loading cookies from incoming HTTP requests.
Per Section 5.3, Step 11.3, when replacing an existing cookie, the original creation-time is preserved.
Get cookies that need to be sent in Set-Cookie headers.
Returns cookies that have been added via add_cookie and removal cookies for original cookies that have been removed. Does not include original cookies that were added via add_original.
val remove : t -> clock:_ Eio.Time.clock -> Cookeio.t -> unitRemove a cookie from the jar.
If an original cookie with the same name/domain/path exists, creates a removal cookie (empty value, Max-Age=0, past expiration) that appears in the delta. If only a delta cookie exists, simply removes it from the delta.
Per RFC 6265 Section 5.3, cookies are removed by sending a Set-Cookie with an expiry date in the past.
val get_cookies :
t ->
clock:_ Eio.Time.clock ->
domain:string ->
path:string ->
is_secure:bool ->
Cookeio.t listGet cookies applicable for a URL.
Implements the cookie retrieval algorithm from RFC 6265 Section 5.4 for generating the Cookie header.
Algorithm
Per RFC 6265 Section 5.4, the user agent should: 1. Filter cookies by domain matching (Section 5.1.3) 2. Filter cookies by path matching (Section 5.1.4) 3. Filter out cookies with Secure attribute when request is non-secure 4. Filter out expired cookies 5. Sort remaining cookies (longer paths first, then by creation time) 6. Update last-access-time for retrieved cookies
This function implements all these steps, combining original and delta cookies with delta taking precedence. Excludes:
- Removal cookies (empty value)
- Expired cookies (expiry-time in the past per Section 5.3)
- Secure cookies when
is_secure = false
Cookie Ordering
Cookies are sorted per Section 5.4, Step 2:
- Cookies with longer paths are listed before cookies with shorter paths
- Among cookies with equal-length paths, cookies with earlier creation-times are listed first
This ordering ensures more specific cookies take precedence.
Matching Rules
Domain matching follows Section 5.1.3:
- IP addresses require exact match only
- Hostnames support subdomain matching unless host-only flag is set
Path matching follows Section 5.1.4.
val clear : t -> unitClear all cookies.
val clear_expired : t -> clock:_ Eio.Time.clock -> unitClear expired cookies.
Removes cookies whose expiry-time is in the past per RFC 6265 Section 5.3.
val clear_session_cookies : t -> unitClear session cookies.
Removes cookies that have no Expires or Max-Age attribute (session cookies). Per RFC 6265 Section 5.3, these cookies are normally removed when the user agent "session" ends.
val count : t -> intGet the number of unique cookies in the jar.
Get all cookies in the jar.
Returns all cookies including expired ones (for inspection/debugging). Use get_cookies with appropriate domain/path for filtered results that exclude expired cookies, or call clear_expired first.
val is_empty : t -> boolCheck if the jar is empty.
Pretty Printing
val pp : Format.formatter -> t -> unitPretty print a cookie jar.
Mozilla Format
val to_mozilla_format : t -> stringSerialize cookies in Mozilla/Netscape cookie format.
The Mozilla format uses tab-separated fields:
domain \t include_subdomains \t path \t secure \t expires \t name \t valueThe include_subdomains field corresponds to the inverse of the host-only-flag in RFC 6265.
val from_mozilla_format : clock:_ Eio.Time.clock -> string -> tParse Mozilla format cookies.
Creates a cookie jar from a string in Mozilla cookie format, using the provided clock to set creation and last access times. The include_subdomains field is mapped to the host-only-flag per RFC 6265 Section 5.3.