55``Set-Cookie`` headers from the upgrade response and echo them back as a
66``Cookie`` request header for the socket lifetime.
77
8- This is intentionally minimal: it stores name→value pairs without attribute
9- parsing (domain/path/expiry), matching the affinity-only use case in the RFD.
8+ This is intentionally minimal: it stores name→value pairs and only honors
9+ expiration attributes that remove a cookie, matching the affinity-only use case
10+ in the RFD.
1011"""
1112
1213from __future__ import annotations
@@ -23,16 +24,23 @@ def __init__(self) -> None:
2324 def store_set_cookie (self , header_value : str ) -> None :
2425 """Ingest a single ``Set-Cookie`` header value.
2526
26- Only the leading ``name=value`` pair is retained; cookie attributes
27- (``; Path=/``, ``; HttpOnly`` etc.) are ignored.
27+ Only the leading ``name=value`` pair is retained; most cookie attributes
28+ (``; Path=/``, ``; HttpOnly`` etc.) are ignored. Expiration attributes
29+ that explicitly clear a cookie (``Max-Age=0`` or an epoch ``Expires``
30+ value) remove any stored cookie with the same name.
2831 """
29- first = header_value .split (";" , 1 )[0 ].strip ()
32+ parts = [part .strip () for part in header_value .split (";" )]
33+ first = parts [0 ]
3034 if not first or "=" not in first :
3135 return
3236 name , _ , value = first .partition ("=" )
3337 name = name .strip ()
34- if name :
35- self ._cookies [name ] = value .strip ()
38+ if not name :
39+ return
40+ if _is_deletion_cookie (parts [1 :]):
41+ self ._cookies .pop (name , None )
42+ return
43+ self ._cookies [name ] = value .strip ()
3644
3745 def store_set_cookies (self , header_values : list [str ]) -> None :
3846 """Ingest multiple ``Set-Cookie`` header values."""
@@ -51,3 +59,17 @@ def clear(self) -> None:
5159
5260 def __len__ (self ) -> int :
5361 return len (self ._cookies )
62+
63+
64+ def _is_deletion_cookie (attributes : list [str ]) -> bool :
65+ for attribute in attributes :
66+ key , separator , value = attribute .partition ("=" )
67+ if not separator :
68+ continue
69+ key = key .strip ().lower ()
70+ value = value .strip ().lower ()
71+ if key == "max-age" and value == "0" :
72+ return True
73+ if key == "expires" and value in {"thu, 01 jan 1970 00:00:00 gmt" , "0" }:
74+ return True
75+ return False
0 commit comments