On this page:
3.1 Cookie Objects
Cookie
Cookie.name
Cookie.value
Cookie.domain
Cookie.path
Cookie.expiration_  time
Cookie.creation_  time
Cookie.access_  time
Cookie.is_  persistent
Cookie.is_  host_  only
Cookie.is_  secure_  only
Cookie.is_  http_  only
Cookie.is_  expired
Cookie.handle
Cookie.from_  handle
3.2 Cookie Jars
Cookie  Jar
Cookie  Jar.save_  cookie
Cookie  Jar.save_  cookies
Cookie  Jar.extract_  and_  save_  cookies
Cookie  Jar.cookies_  matching
Cookie  Jar.cookie_  header
Cookie  Jar.current
Cookie  Jar.handle
3.3 Parsing Utilities
parse.extract_  cookies
parse.parse_  cookie
parse.default_  path
parse.parse_  date
parse.min_  cookie_  seconds
parse.max_  cookie_  seconds
9.0.0.5

3 Cookies for User Agents (Clients)🔗ℹ

 import: net/cookie/user_agent
  package: rhombus-net-cookie-lib

The net/cookie/user_agent library provides cookie support for user agents (i.e., clients).

3.1 Cookie Objects🔗ℹ

class

class user_agent.Cookie(

  name :: cookie.Name,

  value :: cookie.Value,

  ~domain: domain :: cookie.Domain,

  ~path: path :: cookie.PathOrExtension,

  ~expiration_time: expiration_time :: PosInt,

  ~creation_time: creation_time :: PosInt,

  ~access_time: access_time :: PosInt,

  ~is_persistent: is_persistent :: Any.to_boolean,

  ~is_host_only: is_host_only :: Any.to_boolean,

  ~is_secure_only: is_secure_only :: Any.to_boolean,

  ~is_http_only: is_http_only :: Any.to_boolean

)

A structure representing a cookie from a user agent’s point of view. A user angent normally will not need to construct a user_agent.Cookie instance directly, except perhaps for testing. Instead, user_agent.parse.extract_cookies produces instances for all the cookies received in a server’s response.

All times are represented as the number of seconds since the epoch (midnight of January 1, 1970), like the values produced by system.seconds.

method

method (c :: user_agent.Cookie).is_expired(

  now :: Int = system.seconds()

) :: Boolean

Reports whether a cookie’s experiation precedes now.

property

property (c :: user_agent.Cookie).handle

 

function

fun user_agent.Cookie.from_handle(handle)

  :: user_agent.Cookie

Returns the cookie’s internal representation as recognized by Racket libraries or constructs a user_agent.Cookie instance from such a representation.

3.2 Cookie Jars🔗ℹ

class

class user_agent.CookieJar()

A user_agent.CookieJar instance is for saving cookies (imperatively) and extracting all cookies that match a given URL. An instance internally maintains a sorted order that mirrors the sort order specified by RFC 6265 for the Cookie header.

method

method (cj :: user_agent.CookieJar).save_cookie(

  cookie :: user_agent.Cookie,

  ~via_http: via_http :: Any.to_boolean = #true

) :: Void

 

method

method (cj :: user_agent.CookieJar).save_cookies(

  cookies :: Listable.to_list && List.of(user_agent.Cookie),

  ~via_http: via_http :: Any.to_boolean = #true

) :: Void

Adds cookie or all the cookies in cookies to the jar cj, and also removes any expired cookies from cj.

The via_http argument should be true if the cookie was received via an HTTP API. If it is #false, the cookie will be ignored if the its “HTTP only” flag is set or if the cookie is attempting to replace an “HTTP only” cookie already present in the jar.

method

method (cj :: user_agent.CookieJar).extract_and_save_cookies(

  headers :: Map.of(String, Bytes) || (Listable.to_list && List.of(Bytes)),

  ~url: url :: URL,

  ~decode: decode :: Bytes -> String = Bytes.utf8_string

) :: Void

Parses cookies out of headers as received for url and adds them via user_agent.CookieJar.save_cookies.

The given headers may be provided either as a map from string keys to bytes values, such as returned in a Response from http.get, or as a list of unparsed header lines as byte strings. The decode function is used just for values in the case that headers is a map, and decode is used for both keys and values in the case that headers is a list of bytes.

> def site = URL.from_string("http://test.example.com/apps/main")

> def example_cj = user_agent.CookieJar()

> example_cj.extract_and_save_cookies(

    { "X-Test-Header": #"isThisACookie=no",

      "Set-Cookie": #"a=b; Max-Age=2000; Path=/",

      "Set-Cookie": #"user=bob; Max-Age=86400; Path=/apps" },

    ~url: site

  )

> example_cj.cookie_header(site)

Bytes.copy(#"user=bob")

> example_cj.extract_and_save_cookies(

    [#"X-Ignore-This: thisIsStillNotACookie=yes",

     #"Set-Cookie: p=q; Max-Age=2000; Path=/",

     #"Set-Cookie: usersMom=alice; Max-Age=86400; Path=/apps"],

    ~url: site

  )

> example_cj.cookie_header(site)

Bytes.copy(#"usersMom=alice; user=bob; p=q")

method

method (cj :: user_agent.CookieJar).cookies_matching(

  url :: URL,

  ~is_secure :: is_secure = (URL.scheme(url) == "https")

) :: List.of(user_agent.Cookie)

Returns all cookies in the jar jc that should be sent in the Cookie header for a request made to url. The is_secure argument specifies whether the cookies will be sent via a secure protocol. (If not, cookies with the “Secure” flag set should not be returned by this method.)

This method should produce its cookies in the order expected according to RFC 6265:

  • Cookies with longer paths are listed before cookies with shorter paths.

  • Among cookies that have equal-length path fields, cookies with earlier creation-times are listed before cookies with later creation-times.

If there are multiple cookies in the jar with the same name and different domains or paths, RFC 6265 does not specify which to send. The result listincludes all cookies that match the domain and path of the given URL, in the order specified above.

method

method (cj :: user_agent.CookieJar).cookie_header(

  url :: URL,

  ~encode: encode :: String -> Bytes = String.utf8_bytes,

  ~keep: keep :: user_agent.Cookie -> Any = fun (x): #true,

  ~skip: skip :: user_agent.Cookie -> Any = fun (x): #false

) :: maybe(Bytes)

Finds any unexpired cookies matching url in the jar cj, removes any for which keep produces #false or skip produces a true value, and produces the value portion of a Cookie HTTP request header. The result is #false is no cookies match.

Cookies with the “Secure” flag will be included in this header if and only if url.scheme is "https", unless removed using the keep or skip function.

See user_agent.CookieJar.extract_and_save_cookies for an example.

context parameter

Parameter.def user_agent.CookieJar.current

  :: user_agent.CookieJar

A parameter for a default cookie jar.

property

property (cj :: user_agent.CookieJar).handle

Returns the cookie jar’s internal representation as recognized by Racket libraries.

3.3 Parsing Utilities🔗ℹ

These parsing utilities are normally not used directly, but they are used internally by user_agent.CookieJar.extract_and_save_cookies.

function

fun user_agent.parse.extract_cookies(

  headers :: Map.of(String, Bytes) || (Listable.to_list && List.of(Bytes)),

  ~url: url :: URL,

  ~decode: decode :: Bytes -> String = Bytes.utf8_string

) :: List.of(user_agent.Cookie)

Parses headers in the same way as user_agent.CookieJar.extract_and_save_cookies. but returns a list of cookies.

> user_agent.parse.extract_cookies(

    [#"X-Ignore-This: thisIsStillNotACookie=yes",

     #"Set-Cookie: p=q; Max-Age=2000; Path=/",

     #"Set-Cookie: usersMom=alice; Max-Age=86400; Path=/apps"],

    ~url: site

  )

[

  user_agent.Cookie(

    String.copy("p"),

    String.copy("q"),

    ~domain: "test.example.com",

    ~path: String.copy("/"),

    ~expiration_time: 1764121082,

    ~creation_time: 1764119082,

    ~access_time: 1764119082,

    ~is_persistent: #true,

    ~is_host_only: #true,

    ~is_secure_only: #false,

    ~is_http_only: #false

  ),

  user_agent.Cookie(

    String.copy("usersMom"),

    String.copy("alice"),

    ~domain: "test.example.com",

    ~path: String.copy("/apps"),

    ~expiration_time: 1764205482,

    ~creation_time: 1764119082,

    ~access_time: 1764119082,

    ~is_persistent: #true,

    ~is_host_only: #true,

    ~is_secure_only: #false,

    ~is_http_only: #false

  )

]

function

fun user_agent.parse.parse_cookie(

  bstr :: Bytes,

  ~url: url :: URL,

  ~decode: decode :: Bytes -> String = Bytes.utf8_string

) :: maybe(user_agent.Cookie)

Parses a single cookie from a Set-Cookie header value, returning a cookie if the header value is well-formed and #false otherwise.

function

fun user_agent.parse.default_path(url :: URL)

  :: String

Given a URL, produces the path that should be used for a cookie that has no Path attribute, as specified in Section 5.1.4 of RFC 6265.

function

fun user_agent.parse.parse_date(str :: String)

  :: maybe(date.ZonedDateTime)

Parses the given str as a date, producing #false if it is not possible to extract a date from the string using the algorithm specified in Section 5.1.1 of RFC 6265.

value

def user_agent.parse.min_cookie_seconds

 

value

def user_agent.parse.max_cookie_seconds

The largest and smallest integers that this user agent library will use, or be guaranteed to accept, as time measurements in seconds since the epoch (midnight of January 1, 1970).