~/bend-docscommunity

cookie.bend checks

raw source on the hub · import 0x5e4e2a9db839a0214ace6923b04b685b/cookie.bend as Cookie

ezhttp/cookie: Set-Cookie and Cookie (RFC 6265 §§4–5). A thin jar: parse attributes, serialize the request header, and domain/path/secure matching. Expires is stored, not evaluated against a clock. SameSite is stored; there is no browsing context to suppress cross-site sends.

2 imports
import Base
import ./http.bend as Http

Types

Definitions

def cookie.new source · line 24 · raw

@name:String -> @value:String -> Cookie

a session cookie with no attributes yet

def cookie.expires source · line 28 · raw

@c:Cookie -> @when:String -> Cookie

replace Expires

def cookie.age source · line 36 · raw

@c:Cookie -> @age:String -> Cookie

replace Max-Age

def cookie.domain source · line 44 · raw

@c:Cookie -> @host:String -> Cookie

replace Domain and clear host-only

def cookie.dir source · line 52 · raw

@c:Cookie -> @dir:String -> Cookie

replace Path

def cookie.secure_on source · line 60 · raw

@c:Cookie -> Cookie

set the Secure flag

def cookie.http_on source · line 68 · raw

@c:Cookie -> Cookie

set the HttpOnly flag

def cookie.site_set source · line 76 · raw

@c:Cookie -> @site:String -> Cookie

replace SameSite

def cookie.site.none source · line 84 · raw

@_low:String -> @hit:Bool -> String

None, or unrecognized

def cookie.site.strict source · line 92 · raw

@+low:String -> @hit:Bool -> String

Strict, or continue

def cookie.site.lax source · line 100 · raw

@+low:String -> @hit:Bool -> String

Lax / Strict / None, canonical spelling (RFC 6265bis SameSite)

def cookie.site source · line 108 · raw

@+raw:String -> String

canonicalize a SameSite value; anything else is dropped

def cookie.age_ok source · line 113 · raw

@c:Cookie -> @+raw:String -> @m:Maybe<&2, Nat> -> Cookie

keep a numeric Max-Age, ignore the attribute when it is not digits

def cookie.flag.http source · line 121 · raw

@c:Cookie -> @_name:String -> @hit:Bool -> Cookie

HttpOnly flag, or leave the cookie alone

def cookie.flag.secure source · line 129 · raw

@c:Cookie -> @+name:String -> @hit:Bool -> Cookie

Secure flag, else HttpOnly

def cookie.flag source · line 137 · raw

@c:Cookie -> @+name:String -> Cookie

a flag attribute (no equals sign)

def cookie.named.site source · line 141 · raw

@c:Cookie -> @_name:String -> @value:String -> @hit:Bool -> Cookie

SameSite, or an unrecognized attribute

def cookie.named.path source · line 150 · raw

@c:Cookie -> @+name:String -> @+value:String -> @hit:Bool -> Cookie

Path

def cookie.named.domain source · line 159 · raw

@c:Cookie -> @+name:String -> @+value:String -> @hit:Bool -> Cookie

Domain, stored lowercase

def cookie.named.age source · line 168 · raw

@c:Cookie -> @+name:String -> @+value:String -> @hit:Bool -> Cookie

Max-Age

def cookie.named.expires source · line 177 · raw

@c:Cookie -> @+name:String -> @+value:String -> @hit:Bool -> Cookie

Expires, stored as the HTTP-date text

def cookie.named source · line 186 · raw

@c:Cookie -> @+name:String -> @+value:String -> Cookie

one name=value attribute

def cookie.apply.cut source · line 190 · raw

@c:Cookie -> @+piece:String -> @cut:0x5e4e2a9db839a0214ace6923b04b685b/http.Cut -> Cookie

one attribute piece, flag or name=value

def cookie.apply source · line 198 · raw

@c:Cookie -> @+piece:String -> Cookie

one semicolon-separated attribute

def cookie.fold source · line 202 · raw

@ps:List<&2, String> -> @c:Cookie -> Cookie

walk attributes. The list is the shrinking argument.

def cookie.from.name source · line 210 · raw

@+name:String -> @value:String -> @attrs:List<&2, String> -> @empty:Bool -> Maybe<&2, Cookie>

reject an empty name (RFC 6265 §4.1.1)

def cookie.from source · line 219 · raw

@_pair:String -> @attrs:List<&2, String> -> @cut:0x5e4e2a9db839a0214ace6923b04b685b/http.Cut -> Maybe<&2, Cookie>

the name=value pair, then the attribute list

def cookie.parse.parts source · line 229 · raw

@ps:List<&2, String> -> Maybe<&2, Cookie>

Set-Cookie split on ;

def cookie.parse source · line 238 · raw

@line:String -> Maybe<&2, Cookie>

parse one Set-Cookie line (the field value, not the header name)

def cookie.opt.of source · line 242 · raw

@prefix:String -> @value:String -> @empty:Bool -> String

; Name=value when value is present

def cookie.opt source · line 250 · raw

@prefix:String -> @+value:String -> String

an optional attribute clause

def cookie.domain_text source · line 254 · raw

@domain:String -> @host_only:Bool -> String

; Domain=… only when a Domain attribute was set

def cookie.mark source · line 262 · raw

@label:String -> @on:Bool -> String

; Secure / ; HttpOnly when the flag is set

def cookie.line source · line 270 · raw

@c:Cookie -> String

Set-Cookie field value (RFC 6265 §4.1.1)

def cookie.set source · line 284 · raw

@c:Cookie -> 0x5e4e2a9db839a0214ace6923b04b685b/http.Header

a Set-Cookie header

def cookie.pairs.keep source · line 288 · raw

@name:String -> @value:String -> @empty:Bool -> @rest:(@_:Unit -> List<&2, String>) -> List<&2, String>

keep name=value when the name is not empty

def cookie.pairs.one source · line 297 · raw

@c:Cookie -> @rest:(@_:Unit -> List<&2, String>) -> List<&2, String>

one cookie as a request pair, dropped when the name is empty

def cookie.pairs source · line 305 · raw

@cs:List<&2, Cookie> -> List<&2, String>

name=value pieces, empty names removed

def cookie.join source · line 313 · raw

@cs:List<&2, Cookie> -> String

Cookie field value: pairs joined by ; (RFC 6265 §5.4)

def cookie.request source · line 317 · raw

@cs:List<&2, Cookie> -> 0x5e4e2a9db839a0214ace6923b04b685b/http.Header

a Cookie request header

def cookie.slashes.ch source · line 321 · raw

@slash:Bool -> @rest:(@_:Unit -> Nat) -> Nat

count / in a path

def cookie.slashes source · line 329 · raw

@p:String -> Nat

how many slashes a path holds

def cookie.skip.ch source · line 337 · raw

@hit:Bool -> @+tail:String -> @rest:(@_:Unit -> String) -> String

drop the reversed prefix through the first slash

def cookie.skip source · line 345 · raw

@p:String -> String

reversed path with the last segment removed

def cookie.before source · line 353 · raw

@p:String -> String

characters before the right-most slash

def cookie.default_of source · line 357 · raw

@+p:String -> @few:Bool -> String

/ when the path has fewer than two slashes, else the directory prefix

def cookie.default_path source · line 365 · raw

@+p:String -> String

default-path (RFC 6265 §5.1.4)

def cookie.fill_domain source · line 369 · raw

@domain:String -> @host_only:Bool -> @host:String -> String

host-only cookies take the response host; Domain stays as parsed

def cookie.fill_path.of source · line 377 · raw

@path:String -> @req:String -> @empty:Bool -> String

an absent Path becomes default-path

def cookie.fill_path source · line 385 · raw

@+path:String -> @req:String -> String

an absent Path becomes default-path

def cookie.receive source · line 389 · raw

@host:String -> @req_path:String -> @c:Cookie -> Cookie

store the response host on a host-only cookie and fill default-path

def cookie.ipv4.step source · line 399 · raw

@dot:Bool -> @digit:Bool -> @if_dot:(@_:Unit -> Bool) -> @if_digit:(@_:Unit -> Bool) -> Bool

a dot continues the scan, a digit keeps it, anything else stops

def cookie.ipv4.go source · line 410 · raw

@host:String -> @seen:Bool -> Bool

true when the host is only digits and dots and contains a dot

def cookie.ipv4 source · line 421 · raw

@host:String -> Bool

IPv4 literal (no subdomain match, RFC 6265 §5.1.3)

def cookie.domain_suffix source · line 425 · raw

@host:String -> @domain:String -> @ip:Bool -> Bool

suffix match when the host is not an IPv4 address

def cookie.domain_eq source · line 433 · raw

@+host:String -> @+domain:String -> @same:Bool -> Bool

exact match, else the suffix rule

def cookie.domain_match source · line 441 · raw

@+host:String -> @+domain:String -> Bool

domain-match (RFC 6265 §5.1.3). Host and domain are compared lowercase.

def cookie.domain_ok source · line 445 · raw

@host:String -> @domain:String -> @host_only:Bool -> Bool

host-only is exact; a Domain attribute uses domain-match

def cookie.path_slash source · line 453 · raw

@+req:String -> @+cpath:String -> @slash:Bool -> Bool

the next request character is /, or the cookie-path already ended in /

def cookie.path_rest source · line 461 · raw

@+req:String -> @+cpath:String -> @same:Bool -> Bool

identical paths match; otherwise the prefix rules (RFC 6265 §5.1.4)

def cookie.path_prefix source · line 469 · raw

@+req:String -> @+cpath:String -> @hit:Bool -> Bool

path-match once the cookie-path is known to be a prefix

def cookie.path_ok source · line 477 · raw

@+req:String -> @+cpath:String -> Bool

path-match (RFC 6265 §5.1.4)

def cookie.send.secure source · line 481 · raw

@tls:Bool -> @secure:Bool -> Bool

Secure cookies ride only on TLS (RFC 6265 §5.4)

def cookie.send.path source · line 489 · raw

@tls:Bool -> @secure:Bool -> @ok:Bool -> Bool

path-match, then the Secure bit

def cookie.send.domain source · line 497 · raw

@req:String -> @tls:Bool -> @secure:Bool -> @cpath:String -> @ok:Bool -> Bool

domain-match, then path-match

def cookie.send source · line 506 · raw

@host:String -> @req_path:String -> @tls:Bool -> @c:Cookie -> Bool

whether this cookie is sent on this request (RFC 6265 §5.4)

def cookie.alive.of source · line 514 · raw

@age:Nat -> @m:Maybe<&2, Nat> -> Bool

no Max-Age means a session cookie (still sendable). 0 means already expired.

def cookie.alive source · line 522 · raw

@max_age:String -> @age:Nat -> Bool

Max-Age against an age in seconds. Expires is not compared to a clock.

def cookie.select.cons source · line 526 · raw

@ok:Bool -> @c:Cookie -> @rest:(@_:Unit -> List<&2, Cookie>) -> List<&2, Cookie>

cons when the cookie matches the request

def cookie.select source · line 535 · raw

@cs:List<&2, Cookie> -> @+host:String -> @+req_path:String -> @+tls:Bool -> List<&2, Cookie>

cookies that would be sent (domain, path, secure)