OCaml HTTP cookie handling library with support for Eio-based storage jars
1(** Cookie management library for OCaml
2
3 HTTP cookies are a mechanism that allows "server side
4 connections to store and retrieve information on the client side."
5 Originally designed to enable persistent client-side state for web
6 applications, cookies are essential for storing user preferences, session
7 data, shopping cart contents, and authentication tokens.
8
9 This library provides a complete cookie jar implementation following
10 established web standards while integrating Eio for efficient asynchronous operations.
11
12 {2 Cookie Format and Structure}
13
14 Cookies are set via the Set-Cookie HTTP response header with the basic
15 format: [NAME=VALUE] with optional attributes including:
16 - [expires]: Optional cookie lifetime specification
17 - [domain]: Specifying valid domains using tail matching
18 - [path]: Defining URL subset for cookie validity
19 - [secure]: Transmission over secure channels only
20 - [httponly]: Not accessible to JavaScript
21 - [samesite]: Cross-site request behavior control
22
23 {2 Domain and Path Matching}
24
25 The library implements standard domain and path matching rules:
26 - Domain matching uses "tail matching" (e.g., "acme.com" matches
27 "anvil.acme.com")
28 - Path matching allows subset URL specification for fine-grained control
29 - More specific path mappings are sent first in Cookie headers
30
31 *)
32
33type same_site = [ `Strict | `Lax | `None ]
34(** Cookie same-site policy for controlling cross-site request behavior.
35
36 - [`Strict]: Cookie only sent for same-site requests, providing maximum
37 protection
38 - [`Lax]: Cookie sent for same-site requests and top-level navigation
39 (default for modern browsers)
40 - [`None]: Cookie sent for all cross-site requests (requires [secure] flag)
41*)
42
43type t
44(** HTTP Cookie representation with all standard attributes.
45
46 A cookie represents a name-value pair with associated metadata that controls
47 its scope, security, and lifetime. Cookies with the same [name], [domain],
48 and [path] will overwrite each other when added to a cookie jar. *)
49
50type jar
51(** Cookie jar for storing and managing cookies.
52
53 A cookie jar maintains a collection of cookies with automatic cleanup of
54 expired entries and enforcement of storage limits. It implements the
55 standard browser behavior for cookie storage, including:
56 - Automatic removal of expired cookies
57 - LRU eviction when storage limits are exceeded
58 - Domain and path-based cookie retrieval
59 - Mozilla format persistence for cross-tool compatibility *)
60
61(** {1 Cookie Accessors} *)
62
63val domain : t -> string
64(** Get the domain of a cookie *)
65
66val path : t -> string
67(** Get the path of a cookie *)
68
69val name : t -> string
70(** Get the name of a cookie *)
71
72val value : t -> string
73(** Get the value of a cookie *)
74
75val secure : t -> bool
76(** Check if cookie is secure only *)
77
78val http_only : t -> bool
79(** Check if cookie is HTTP only *)
80
81val expires : t -> Ptime.t option
82(** Get the expiry time of a cookie *)
83
84val same_site : t -> same_site option
85(** Get the same-site policy of a cookie *)
86
87val creation_time : t -> Ptime.t
88(** Get the creation time of a cookie *)
89
90val last_access : t -> Ptime.t
91(** Get the last access time of a cookie *)
92
93val make : domain:string -> path:string -> name:string -> value:string ->
94 ?secure:bool -> ?http_only:bool -> ?expires:Ptime.t ->
95 ?same_site:same_site -> creation_time:Ptime.t -> last_access:Ptime.t ->
96 unit -> t
97(** Create a new cookie with the given attributes *)
98
99(** {1 Cookie Jar Creation and Loading} *)
100
101val create : unit -> jar
102(** Create an empty cookie jar *)
103
104val load : clock:_ Eio.Time.clock -> Eio.Fs.dir_ty Eio.Path.t -> jar
105(** Load cookies from Mozilla format file.
106
107 Loads cookies from a file in Mozilla format, using the provided clock to set
108 creation and last access times. Returns an empty jar if the file doesn't
109 exist or cannot be loaded. *)
110
111val save : Eio.Fs.dir_ty Eio.Path.t -> jar -> unit
112(** Save cookies to Mozilla format file *)
113
114(** {1 Cookie Jar Management} *)
115
116val add_cookie : jar -> t -> unit
117(** Add a cookie to the jar *)
118
119val get_cookies :
120 jar ->
121 clock:_ Eio.Time.clock ->
122 domain:string ->
123 path:string ->
124 is_secure:bool ->
125 t list
126(** Get cookies applicable for a URL.
127
128 Returns all cookies that match the given domain and path, and satisfy the
129 secure flag requirement. Also updates the last access time of matching
130 cookies using the provided clock. *)
131
132val clear : jar -> unit
133(** Clear all cookies *)
134
135val clear_expired : jar -> clock:_ Eio.Time.clock -> unit
136(** Clear expired cookies *)
137
138val clear_session_cookies : jar -> unit
139(** Clear session cookies (those without expiry) *)
140
141val count : jar -> int
142(** Get the number of cookies in the jar *)
143
144val get_all_cookies : jar -> t list
145(** Get all cookies in the jar *)
146
147val is_empty : jar -> bool
148(** Check if the jar is empty *)
149
150(** {1 Cookie Creation and Parsing} *)
151
152val parse_set_cookie :
153 clock:_ Eio.Time.clock -> domain:string -> path:string -> string -> t option
154(** Parse Set-Cookie header value into a cookie.
155
156 Parses a Set-Cookie header value following RFC specifications:
157 - Basic format: [NAME=VALUE; attribute1; attribute2=value2]
158 - Supports all standard attributes: [expires], [max-age], [domain], [path],
159 [secure], [httponly], [samesite]
160 - Returns [None] if parsing fails or cookie validation fails
161 - The [domain] and [path] parameters provide the request context for default
162 values
163 - The [clock] parameter is used for calculating expiry times from [max-age]
164 attributes
165
166 Cookie validation rules:
167 - [SameSite=None] requires the [Secure] flag to be set
168
169 Example:
170 [parse_set_cookie ~clock ~domain:"example.com" ~path:"/"
171 "session=abc123; Secure; HttpOnly"] *)
172
173val make_cookie_header : t list -> string
174(** Create cookie header value from cookies.
175
176 Formats a list of cookies into a Cookie header value suitable for HTTP
177 requests.
178 - Format: [name1=value1; name2=value2; name3=value3]
179 - Only includes cookie names and values, not attributes
180 - Cookies should already be filtered for the target domain/path
181 - More specific path mappings should be ordered first in the input list
182
183 Example: [make_cookie_header cookies] might return
184 ["session=abc123; theme=dark"] *)
185
186(** {1 Pretty Printing} *)
187
188val pp : Format.formatter -> t -> unit
189(** Pretty print a cookie *)
190
191val pp_jar : Format.formatter -> jar -> unit
192(** Pretty print a cookie jar *)
193
194(** {1 Mozilla Format} *)
195
196val to_mozilla_format : jar -> string
197(** Write cookies in Mozilla format *)
198
199val from_mozilla_format : clock:_ Eio.Time.clock -> string -> jar
200(** Parse Mozilla format cookies.
201
202 Creates a cookie jar from a string in Mozilla cookie format, using the
203 provided clock to set creation and last access times. *)