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:
::
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 ^- empty cookie value
......@@ -168,8 +168,16 @@ cookies:
Other limitations:
* Attributes in ``Set-Cookie`` response headers like ``Expires``,
``Domain`` or ``Path`` are currently ignored.
* Any attributes in ``Set-Cookie`` response headers but ``Expires``
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.
......
varnishtest "test vmod_esicookies"
server s1 {
rxreq
expect req.http.Cookie == "fromclient=1"
txresp -hdr "Set-Cookie: fromserver1=1" -body {
# unmodified
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>
Before include
<esi:include src="/body1"/>
......@@ -16,27 +19,29 @@ server s1 {
}
rxreq
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" \
-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 {
Included file
}
rxreq
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" \
-hdr "Set-Cookie: b =2" \
-hdr "Set-Cookie: c= 3" \
-hdr "Set-Cookie: d=4 " \
-hdr "Set-Cookie: e=5 ; foobar" \
-hdr "Set-Cookie: f= 3; foobar" \
-hdr "Set-Cookie: rm3=negmaxage ; max-age = -9 "\
-body {
Included file
}
rxreq
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 {
Included file
}
......@@ -82,7 +87,7 @@ varnish v1 -vcl+backend {
} -start
client c1 {
txreq -url "/" -hdr "Cookie: fromclient=1"
txreq -url "/" -hdr "Cookie: fromclient=1;rm1=a; ;; rm2=b;rm3=a;c2=x"
rxresp
expect resp.status == 200
expect resp.http.Set-Cookie == "fromserver1=1"
......
......@@ -394,7 +394,7 @@ vesico_warn(struct sess *sp, struct vesico_req *m,
}
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) {
WSP(sp, SLT_VCL_error,
"...%.40s%s", phdr.b,
......@@ -508,7 +508,6 @@ vesico_analyze_cookie_header(struct sess *sp, struct vesico_req *m,
*
* TODO:
* - check cookie attributes ?
* - expires?
* - domain?
* - path?
*
......@@ -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 */
hp = vrt_selecthttp(sp, where);
for (n = HTTP_HDR_FIRST; n < hp->nhd; n++) {
if (http_IsHdr(&hp->hd[n], hdr)) {
txt h;
char *p;
txt h, c, arg;
enum vesico_analyze_action act;
Tcheck(hp->hd[n]);
h.b = hp->hd[n].b + *hdr;
while (isspace(*(h.b)))
h.b++;
if (! http_IsHdr(&hp->hd[n], hdr))
continue;
p = strchr(h.b, ';');
if (p)
h.e = p;
else
h.e = hp->hd[n].e;
Tcheck(hp->hd[n]);
h.b = hp->hd[n].b + *hdr;
h.e = hp->hd[n].e;
ret = vesico_analyze_cookie_header(sp, m, h, &cookies,
&cs, VESICOAC_ADD);
if (ret != VESICO_OK)
return (vesico_err_str[ret]);
/* handle invalid empty header */
if (Tlen(h) == 0)
continue;
/*
* 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 */
......
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