diff --git a/bin/varnishd/cache/cache_hash.c b/bin/varnishd/cache/cache_hash.c index 6446f3beb0..b04a1371e3 100644 --- a/bin/varnishd/cache/cache_hash.c +++ b/bin/varnishd/cache/cache_hash.c @@ -451,12 +451,6 @@ HSH_Lookup(struct req *req, struct objcore **ocp, struct objcore **bocp) if (oc->ttl <= 0.) continue; - if (BAN_CheckObject(wrk, oc, req)) { - oc->flags |= OC_F_DYING; - EXP_Remove(oc, NULL); - continue; - } - if (!req->hash_ignore_vary && ObjHasAttr(wrk, oc, OA_VARY)) { vary = ObjGetAttr(wrk, oc, OA_VARY, NULL); AN(vary); @@ -466,6 +460,12 @@ HSH_Lookup(struct req *req, struct objcore **ocp, struct objcore **bocp) } } + if (BAN_CheckObject(wrk, oc, req)) { + oc->flags |= OC_F_DYING; + EXP_Remove(oc, NULL); + continue; + } + if (req->vcf != NULL) { vr = req->vcf->func(req, &oc, &exp_oc, 0); if (vr == VCF_CONTINUE) diff --git a/bin/varnishtest/tests/c00133.vtc b/bin/varnishtest/tests/c00133.vtc new file mode 100644 index 0000000000..bfcaf5bc5c --- /dev/null +++ b/bin/varnishtest/tests/c00133.vtc @@ -0,0 +1,86 @@ +varnishtest "Optimized HSH_Lookup - ban is checked after Vary is matched" + +server s1 { + rxreq + expect req.url == /foo + expect req.http.foobar == "1" + txresp -hdr "Vary: Foobar" -body "1111" + + rxreq + expect req.url == /foo + expect req.http.foobar == "2" + txresp -hdr "Vary: Foobar" -body "2222" + + rxreq + expect req.url == /foo + expect req.http.foobar == "3" + txresp -hdr "Vary: Foobar" -body "3333" + + rxreq + expect req.url == /foo + expect req.http.foobar == "1" + txresp -hdr "Vary: Foobar" -body "1111" + + rxreq + expect req.url == /foo + expect req.http.foobar == "1" + txresp -hdr "Vary: Foobar" -body "1111" + +} -start + +varnish v1 -vcl+backend { + sub vcl_backend_response { + set beresp.http.url = bereq.url; + } +} -start + + +client c1 { + txreq -url /foo -hdr "Foobar: 1" + rxresp + expect resp.body == "1111" +} -run + +client c1 { + txreq -url /foo -hdr "Foobar: 2" + rxresp + expect resp.body == "2222" +} -run + +client c1 { + txreq -url /foo -hdr "Foobar: 3" + rxresp + expect resp.body == "3333" + +} -run + +varnish v1 -expect n_object == 3 +varnish v1 -expect cache_hit == 0 +varnish v1 -expect cache_miss == 3 + +client c1 { + txreq -url /foo -hdr "Foobar: 1" + rxresp +} -run + +varnish v1 -expect cache_hit == 1 +varnish v1 -expect cache_miss == 3 + +varnish v1 -cliok "ban obj.http.url == /foo" +varnish v1 -cliok "ban obj.http.url == /bar" +varnish v1 -cliok "ban obj.http.url == /baz" + +client c1 { + txreq -url /foo -hdr "Foobar: 1" + rxresp +} -run + +varnish v1 -expect bans_tested == 1 +varnish v1 -expect bans_tests_tested == 3 +varnish v1 -expect bans_obj_killed == 1 +varnish v1 -expect n_object == 3 + + +varnish v1 -expect cache_hit == 1 +varnish v1 -expect cache_miss == 4 +varnish v1 -expect client_req == 5 diff --git a/bin/varnishtest/tests/c00134.vtc b/bin/varnishtest/tests/c00134.vtc new file mode 100644 index 0000000000..9e94827b65 --- /dev/null +++ b/bin/varnishtest/tests/c00134.vtc @@ -0,0 +1,41 @@ +varnishtest "test ban + vary behavior" + +server s0 { + rxreq + txresp -hdr "vary: version" -body "Variant A" + rxreq + txresp -hdr "vary: version" -body "Variant B" + rxreq + txresp -hdr "vary: version" -body "New variant A" + rxreq + txresp -hdr "vary: version" -body "New variant B" +} -start + +varnish v1 -vcl+backend {} -start + +client c1 { + txreq -hdr "version: a" + rxresp + expect resp.body == "Variant A" +} -run + +client c2 { + txreq -hdr "version: b" + rxresp + expect resp.body == "Variant B" +} -run + +varnish v1 -cliok "ban req.http.version == a" + +# Should this remove a single variant from cache +client c3 { + txreq -hdr "version: a" + rxresp + expect resp.body == "New variant A" +} -run + +client c4 { + txreq -hdr "version: b" + rxresp + expect resp.body == "Variant B" +} -run