Commit d935e2ae authored by Nils Goroll's avatar Nils Goroll

respect the Expires and max-age Set-Cookie Attributes to delete cookies

parent 7bd89652
...@@ -104,7 +104,7 @@ Cookie line, if necessary. Sample output: ...@@ -104,7 +104,7 @@ Cookie line, if necessary. Sample output:
:: ::
13 VCL_error c vmod esicookies http0 cookies tolerated in hdr: 13 VCL_error c vmod esicookies cookies tolerated in hdr:
13 VCL_error c ...ngcookieline;ok=val;noval=;ok2=val;somuc... 13 VCL_error c ...ngcookieline;ok=val;noval=;ok2=val;somuc...
13 VCL_error c ^- empty cookie value 13 VCL_error c ^- empty cookie value
...@@ -168,8 +168,16 @@ cookies: ...@@ -168,8 +168,16 @@ cookies:
Other limitations: Other limitations:
* Attributes in ``Set-Cookie`` response headers like ``Expires``, * Any attributes in ``Set-Cookie`` response headers but ``Expires``
``Domain`` or ``Path`` are currently ignored. and ``max-age`` are currently ignored.
* The ``Set-Cookie`` attribues ``Expires`` and ``max-age`` are only
evaluated to determine if Cookies should be deleted due to the
respective date being in the past at the time a ``Set-Cookie`` is
processed.
Otherwise Cookies are assumed not to expire between the time of the
``Set-Cookie`` response header being processed and the ``Cookie``
header being generated.
* The Name of the ``Cookie`` header cannot currently be changed. * The Name of the ``Cookie`` header cannot currently be changed.
......
varnishtest "test vmod_esicookies" varnishtest "test vmod_esicookies"
server s1 { server s1 {
rxreq rxreq
expect req.http.Cookie == "fromclient=1" # unmodified
txresp -hdr "Set-Cookie: fromserver1=1" -body { expect req.http.Cookie == "fromclient=1;rm1=a; ;; rm2=b;rm3=a;c2=x"
txresp -hdr "Set-Cookie: fromserver1=1" \
-hdr "Set-Cookie: rm1=expired; bar;Expires=Thu, 16 Oct 2014 15:19:11 GMT; foo" \
-body {
<html> <html>
Before include Before include
<esi:include src="/body1"/> <esi:include src="/body1"/>
...@@ -16,27 +19,29 @@ server s1 { ...@@ -16,27 +19,29 @@ server s1 {
} }
rxreq rxreq
expect req.url == "/body1" expect req.url == "/body1"
expect req.http.Cookie == "fromclient=1; fromserver1=1" expect req.http.Cookie == "fromclient=1; rm2=b; rm3=a; c2=x; fromserver1=1"
txresp -hdr "Set-Cookie: frombody1=1; Secure" \ txresp -hdr "Set-Cookie: frombody1=1; Secure" \
-hdr "Set-Cookie: fromserver1=2; Domain=.foo.com; Path=/; Expires=Wed, 13-Jan-2021 22:23:01 GMT; HttpOnly" \ -hdr "Set-Cookie: fromserver1=2; Domain=.foo.com; Path=/; Expires=Wed, 13-Jan-2999 22:23:01 GMT; HttpOnly" \
-hdr "Set-Cookie: rm2=maxage0;foobar=anyway;alsoignored;max-age=0" \
-body { -body {
Included file Included file
} }
rxreq rxreq
expect req.url == "/body2" expect req.url == "/body2"
expect req.http.Cookie == "fromclient=1; frombody1=1; fromserver1=2" expect req.http.Cookie == "fromclient=1; rm3=a; c2=x; frombody1=1; fromserver1=2"
txresp -hdr "Set-Cookie: a=1" \ txresp -hdr "Set-Cookie: a=1" \
-hdr "Set-Cookie: b =2" \ -hdr "Set-Cookie: b =2" \
-hdr "Set-Cookie: c= 3" \ -hdr "Set-Cookie: c= 3" \
-hdr "Set-Cookie: d=4 " \ -hdr "Set-Cookie: d=4 " \
-hdr "Set-Cookie: e=5 ; foobar" \ -hdr "Set-Cookie: e=5 ; foobar" \
-hdr "Set-Cookie: f= 3; foobar" \ -hdr "Set-Cookie: f= 3; foobar" \
-hdr "Set-Cookie: rm3=negmaxage ; max-age = -9 "\
-body { -body {
Included file Included file
} }
rxreq rxreq
expect req.url == "/body3" expect req.url == "/body3"
expect req.http.Cookie == "fromclient=1; frombody1=1; fromserver1=2; a=1; b=2; c=3; d=4; e=5; f=3" expect req.http.Cookie == "fromclient=1; c2=x; frombody1=1; fromserver1=2; a=1; b=2; c=3; d=4; e=5; f=3"
txresp -body { txresp -body {
Included file Included file
} }
...@@ -82,7 +87,7 @@ varnish v1 -vcl+backend { ...@@ -82,7 +87,7 @@ varnish v1 -vcl+backend {
} -start } -start
client c1 { client c1 {
txreq -url "/" -hdr "Cookie: fromclient=1" txreq -url "/" -hdr "Cookie: fromclient=1;rm1=a; ;; rm2=b;rm3=a;c2=x"
rxresp rxresp
expect resp.status == 200 expect resp.status == 200
expect resp.http.Set-Cookie == "fromserver1=1" expect resp.http.Set-Cookie == "fromserver1=1"
......
...@@ -394,7 +394,7 @@ vesico_warn(struct sess *sp, struct vesico_req *m, ...@@ -394,7 +394,7 @@ vesico_warn(struct sess *sp, struct vesico_req *m,
} }
WSP(sp, SLT_VCL_error, WSP(sp, SLT_VCL_error,
"vmod esicookies http0 %s in hdr:", vesico_warn_str[action]); "vmod esicookies %s in hdr:", vesico_warn_str[action]);
if (phdr.b) { if (phdr.b) {
WSP(sp, SLT_VCL_error, WSP(sp, SLT_VCL_error,
"...%.40s%s", phdr.b, "...%.40s%s", phdr.b,
...@@ -508,7 +508,6 @@ vesico_analyze_cookie_header(struct sess *sp, struct vesico_req *m, ...@@ -508,7 +508,6 @@ vesico_analyze_cookie_header(struct sess *sp, struct vesico_req *m,
* *
* TODO: * TODO:
* - check cookie attributes ? * - check cookie attributes ?
* - expires?
* - domain? * - domain?
* - path? * - path?
* *
...@@ -634,26 +633,61 @@ vesico_to_http0(struct sess *sp, struct vmod_priv *priv, enum gethdr_e where, ...@@ -634,26 +633,61 @@ vesico_to_http0(struct sess *sp, struct vmod_priv *priv, enum gethdr_e where,
/* collect cookies from the set-cookie hdr given */ /* collect cookies from the set-cookie hdr given */
hp = vrt_selecthttp(sp, where); hp = vrt_selecthttp(sp, where);
for (n = HTTP_HDR_FIRST; n < hp->nhd; n++) { for (n = HTTP_HDR_FIRST; n < hp->nhd; n++) {
if (http_IsHdr(&hp->hd[n], hdr)) { txt h, c, arg;
txt h; enum vesico_analyze_action act;
char *p;
Tcheck(hp->hd[n]); if (! http_IsHdr(&hp->hd[n], hdr))
h.b = hp->hd[n].b + *hdr; continue;
while (isspace(*(h.b)))
h.b++;
p = strchr(h.b, ';'); Tcheck(hp->hd[n]);
if (p) h.b = hp->hd[n].b + *hdr;
h.e = p; h.e = hp->hd[n].e;
else
h.e = hp->hd[n].e;
ret = vesico_analyze_cookie_header(sp, m, h, &cookies, /* handle invalid empty header */
&cs, VESICOAC_ADD); if (Tlen(h) == 0)
if (ret != VESICO_OK) continue;
return (vesico_err_str[ret]);
/*
* Diverging from
* https://tools.ietf.org/html/rfc6265#section-5.2 :
*
* * we accept a cookie name withtout a value
*/
act = VESICOAC_ADD;
if (http_split(&h, ";", &c) == 0)
continue;
if (Tlen(c) == 0)
continue;
while (http_split(&h, ";", &arg)) {
txt na, va;
if ((http_nv(arg, "=", &na, &va) == 0) ||
(na.b == NULL) ||
(va.b == NULL))
continue;
if (Tlen(na) != 7) {
//
} else if (strncasecmp(na.b, "Expires", 7) == 0) {
time_t t = TIM_parse(va.b);
if ((t != 0) &&
(t < TIM_real()))
act = VESICOAC_DEL;
} else if (strncasecmp(na.b, "max-age", 7) == 0) {
if (*va.b == '-' ||
(Tlen(va) == 1 && *va.b == '0'))
act = VESICOAC_DEL;
}
} }
ret = vesico_analyze_cookie_header(sp, m, c, &cookies,
&cs, act);
if (ret != VESICO_OK)
return (vesico_err_str[ret]);
} }
/* if we haven't used any more cookies than we already had we're done */ /* if we haven't used any more cookies than we already had we're done */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment