Check VCL_HEADER vmod arguments

When a VCL_HEADER argument is a vmod return value, it could be

- NULL for an error condition
- from a different context

Also, we should not assert on HDR_OBJ in VRT_selecthttp() to
facilitate error handling in vmods.

Fixes #3623
parent 02061450
...@@ -257,6 +257,9 @@ VRT_selecthttp(VRT_CTX, enum gethdr_e where) ...@@ -257,6 +257,9 @@ VRT_selecthttp(VRT_CTX, enum gethdr_e where)
case HDR_RESP: case HDR_RESP:
hp = ctx->http_resp; hp = ctx->http_resp;
break; break;
case HDR_OBJ:
hp = NULL;
break;
default: default:
WRONG("VRT_selecthttp 'where' invalid"); WRONG("VRT_selecthttp 'where' invalid");
} }
......
...@@ -13,6 +13,15 @@ varnish v1 -vcl+backend { ...@@ -13,6 +13,15 @@ varnish v1 -vcl+backend {
sub vcl_recv { sub vcl_recv {
std.collect(req.http.foo); std.collect(req.http.foo);
} }
sub vcl_hash {
hash_data("/");
return (lookup);
}
sub vcl_hit {
if (req.url == "/obj") {
std.collect(obj.http.foo);
}
}
sub vcl_backend_fetch { sub vcl_backend_fetch {
std.collect(bereq.http.baz); std.collect(bereq.http.baz);
} }
...@@ -29,4 +38,7 @@ client c1 { ...@@ -29,4 +38,7 @@ client c1 {
rxresp rxresp
expect resp.http.bar == "a, b" expect resp.http.bar == "a, b"
expect resp.http.qux == "c; d" expect resp.http.qux == "c; d"
txreq -url "/obj"
rxresp
expect resp.status == 503
} -run } -run
...@@ -789,26 +789,34 @@ xyzzy_collect(VRT_CTX, VCL_STRANDS s) ...@@ -789,26 +789,34 @@ xyzzy_collect(VRT_CTX, VCL_STRANDS s)
/* cf. VRT_SetHdr() */ /* cf. VRT_SetHdr() */
VCL_VOID VCL_VOID
xyzzy_sethdr(VRT_CTX, VCL_HEADER hs, VCL_STRANDS s) xyzzy_sethdr(VRT_CTX, VCL_HEADER hdr, VCL_STRANDS s)
{ {
struct http *hp; struct http *hp;
const char *b; const char *b;
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
AN(hs); if (hdr == NULL) {
AN(hs->what); VRT_fail(ctx, "debug.sethdr(): header argument is NULL");
hp = VRT_selecthttp(ctx, hs->where); return;
}
hp = VRT_selecthttp(ctx, hdr->where);
if (hp == NULL) {
VRT_fail(ctx, "debug.sethdr(): header argument "
"can not be used here");
return;
}
AN(hdr->what);
CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC); CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC);
if (s->n == 0) { if (s->n == 0) {
http_Unset(hp, hs->what); http_Unset(hp, hdr->what);
} else { } else {
b = VRT_StrandsWS(hp->ws, hs->what + 1, s); b = VRT_StrandsWS(hp->ws, hdr->what + 1, s);
if (b == NULL) { if (b == NULL) {
VSLb(ctx->vsl, SLT_LostHeader, "%s", hs->what + 1); VSLb(ctx->vsl, SLT_LostHeader, "%s", hdr->what + 1);
} else { } else {
if (*b != '\0') if (*b != '\0')
WS_Assert_Allocated(hp->ws, b, strlen(b) + 1); WS_Assert_Allocated(hp->ws, b, strlen(b) + 1);
http_Unset(hp, hs->what); http_Unset(hp, hdr->what);
http_SetHeader(hp, b); http_SetHeader(hp, b);
} }
} }
......
...@@ -182,7 +182,16 @@ vmod_collect(VRT_CTX, VCL_HEADER hdr, VCL_STRING sep) ...@@ -182,7 +182,16 @@ vmod_collect(VRT_CTX, VCL_HEADER hdr, VCL_STRING sep)
struct http *hp; struct http *hp;
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
if (hdr == NULL) {
VRT_fail(ctx, "std.collect(): header argument is NULL");
return;
}
hp = VRT_selecthttp(ctx, hdr->where); hp = VRT_selecthttp(ctx, hdr->where);
if (hp == NULL) {
VRT_fail(ctx, "std.collect(): header argument "
"can not be used here");
return;
}
http_CollectHdrSep(hp, hdr->what, sep); http_CollectHdrSep(hp, hdr->what, sep);
} }
......
...@@ -73,6 +73,8 @@ headers, with an additional whitespace for pretty printing. ...@@ -73,6 +73,8 @@ headers, with an additional whitespace for pretty printing.
Care should be taken when collapsing headers. In particular collapsing Care should be taken when collapsing headers. In particular collapsing
``Set-Cookie`` will lead to unexpected results on the browser side. ``Set-Cookie`` will lead to unexpected results on the browser side.
Using *hdr* from ``obj.http`` triggers a VCL failure.
Examples:: Examples::
std.collect(req.http.accept); std.collect(req.http.accept);
......
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