cl-cookie
2024年10月12日
HTTP cookie manager
CL-Cookie
HTTP cookie manager for Common Lisp.
Key features include:
- Create
cookie
struct instances withmake-cookie
and the following properties:name
,value
,path
,domain
,origin-host
,expires
,max-age
,same-site
,partitioned
,secure-p
,httponly-p
. Thecreation-timestamp
attribute is set automatically at creation time. - Compare cookies with
cookie=
andcookie-equal
. - Convert
Set-Cookie
header string intocookie
instance withparse-set-cookie-headers
. - Serialize
cookie
instances into header strings withwrite-cookie-header
andwrite-set-cookie-header
. - Create
cookie-jar
struct instances withmake-cookie-jar
which allows managing of multiple cookies. You can add multiple cookies to a cookie-jar withmerge-cookies
, or match cookies of certainhost
andpath
withcookie-jar-host-cookies
. - Sanity check for cookie attributes in
make-cookie
,parse-set-cookie-header
,write-set-cookie-header
. Can be turned off by setting*sanity-check*
orsanity-check
parameter (inmake-cookie
andparse-set-cookie-header
) tonil
.
Usage
make-cookie (&key name value path domain origin-host expires max-age same-site partitioned secure-p httponly-p)
(defparameter *cookie* (cl-cookie:make-cookie:name"SID":value"31d4d96e407aad42":origin-host"example.com":path"/api/":domain".example.com":partitionedt:httponly-pt:secure-pt:expires(encode-universal-time6221925120020):max-age3600;; max-age takes precedence over expires:same-site"Strict"));=> *COOKIE* *cookie* ;=> #S(COOKIE :NAME "SID" :VALUE "31d4d96e407aad42" :EXPIRES 3220975326 :PATH "/api/"; :DOMAIN ".example.com" :SAME-SITE "Strict" :MAX-AGE 3600 :PARTITIONED T; :SECURE-P T :HTTPONLY-P T :ORIGIN-HOST "example.com" :CREATION-TIMESTAMP 3921465733)
write-set-cookie-header (cookie &optional stream)
(cl-cookie:write-set-cookie-header *cookie*);=> "SID=31d4d96e407aad42; Expires=2002年1月25日 19:22:06 GMT; Max-age=3600; Path=/api/; Domain=.example.com; SameSite=Strict; Partitioned; Secure; HttpOnly"
Sanity Check
If one of the following conditions is true, an error is emitted:
- Is
name
not supplied? - If
secure
is not present:- is
samesite=none
? - is
partitioned
present?
- is
(make-cookie:value"asdg");; => Invalid Cookie values: No name supplied.;; You should set at least a dummy name to avoid bugs.;; [Condition of type INVALID-COOKIE]
(make-cookie:name"haalllo":value"asdg":same-site"None");; => Invalid Cookie values: Samesite=None cookies require Secure.;; [Condition of type INVALID-COOKIE]
(make-cookie:name"haalllo":partitionedt);; => Invalid Cookie values: Partitioned cookies require Secure.;; [Condition of type INVALID-COOKIE]
If you want to deactivate sanity checks (e.g. for performance reasons)
you can either supply parameter sanity-check
with nil
, or set
*sanity-check*
to nil
.
(make-cookie:name"haalllo":partitionedt:sanity-checknil);; => #S(COOKIE :NAME "haalllo" :PARTITIONED T:CREATION-TIMESTAMP3928172572)
(let((cl-cookie:*sanity-check*))(make-cookie:name"haalllo":value"asdg":same-site"None"));; => #S(COOKIE :NAME "haalllo" :VALUE "asdg" :SAME-SITE "None";; :CREATION-TIMESTAMP 3928172645)
cookie struct accessor functions
(cl-cookie:cookie-name *cookie*);=> "SID" (cl-cookie:cookie-value *cookie*);=> "31d4d96e407aad42" (cl-cookie:cookie-expires *cookie*);=> 3220975326 (cl-cookie:cookie-path *cookie*);=> "/api/" (cl-cookie:cookie-origin-host *cookie*);=> "example.com";; host takes precedence over domain, if both are supplied and conflicting. (cl-cookie:cookie-domain *cookie*);=> ".example.com";; This cookie is accessible for example.com and all subdomains (e.g. docs.example.com) (cl-cookie:cookie-same-site *cookie*);=> "Strict" (cl-cookie:cookie-max-age *cookie*);=> 3600 (cl-cookie:cookie-partitioned *cookie*);=> T (cl-cookie:cookie-secure-p *cookie*);=> T (cl-cookie:cookie-httponly-p *cookie*);=> T
parse-set-cookie-header (set-cookie-string origin-host origin-path)
(cl-cookie:parse-set-cookie-header"my_cookie=my_value; Domain=.example.com; Expires=2024年12月31日 23:59:59 GMT; HttpOnly; Max-Age=7200; Secure; SameSite=None""example.com""/");=> #S(COOKIE :NAME "my_cookie" :VALUE "my_value" :EXPIRES 3944678399 :PATH "/" :DOMAIN ".example.com"; :SAME-SITE "None" :MAX-AGE 7200 :PARTITIONED NIL :SECURE-P T; :HTTPONLY-P T :ORIGIN-HOST "example.com" :CREATION-TIMESTAMP 3921467559)
make-cookie-jar (&key cookies)
(defparameter *cookie-jar* (cl-cookie:make-cookie-jar:cookies(list(cl-cookie:make-cookie:name"SID":value"31d4d96e407aad42":origin-host"example.com":path"/api/":domain".example.com":max-age3600))));=> *cookie-jar*
merge-cookies (cookie-jar cookies)
(cl-cookie:merge-cookies *cookie-jar* (list(cl-cookie:parse-set-cookie-header"SID=31d4d96e407aad42; Path=/; Domain=example.com; Partitioned""www.example.org""/")));=> (#S(CL-COOKIE:COOKIE :NAME "SID" :VALUE "31d4d96e407aad42" :PATH "/api/" :DOMAIN ".example.com"; :ORIGIN-HOST "example.com" :EXPIRES NIL :MAX-AGE 3600 :SAME-SITE NIL; :PARTITIONED NIL :SECURE-P NIL :HTTPONLY-P NIL :CREATION-TIMESTAMP 3921572023); #S(CL-COOKIE:COOKIE :NAME "SID" :VALUE "31d4d96e407aad42" :PATH "/" :DOMAIN "example.com"; :ORIGIN-HOST "www.example.org" :EXPIRES NIL :MAX-AGE NIL :SAME-SITE NIL; :PARTITIONED T :SECURE-P NIL :HTTPONLY-P NIL :CREATION-TIMESTAMP 3921572029))
cookie-jar-host-cookies (cookie-jar host path &key securep)
(cl-cookie:cookie-jar-host-cookies *cookie-jar* "example.com""/");=> (#S(CL-COOKIE:COOKIE :NAME "SID" :VALUE "31d4d96e407aad42" :PATH "/" :DOMAIN "example.com"; :ORIGIN-HOST "www.example.org" :EXPIRES NIL :MAX-AGE NIL :SAME-SITE NIL; :PARTITIONED NIL :SECURE-P NIL :HTTPONLY-P NIL :CREATION-TIMESTAMP 3921566005))
See also
Author
- Eitaro Fukamachi (e.arrows@gmail.com)
Copyright
Copyright (c) 2015 Eitaro Fukamachi (e.arrows@gmail.com)
License
Licensed under the BSD 2-Clause License.