Skip to content

Commit 5835761

Browse files
committed
HSH: Limit the number of ban checks before vary matching
Refs: varnishcache#4236
1 parent 002e660 commit 5835761

2 files changed

Lines changed: 54 additions & 1 deletion

File tree

bin/varnishd/cache/cache_hash.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,8 @@ HSH_Lookup(struct req *req, struct objcore **ocp, struct objcore **bocp)
371371
const uint8_t *vary;
372372
intmax_t boc_progress;
373373
unsigned xid = 0;
374+
unsigned ban_checks;
375+
unsigned ban_any_variant;
374376
float dttl = 0.0;
375377

376378
AN(ocp);
@@ -420,6 +422,8 @@ HSH_Lookup(struct req *req, struct objcore **ocp, struct objcore **bocp)
420422
busy_found = 0;
421423
exp_oc = NULL;
422424
exp_t_origin = 0.0;
425+
ban_checks = 0;
426+
ban_any_variant = cache_param->ban_any_variant;
423427
VTAILQ_FOREACH(oc, &oh->objcs, hsh_list) {
424428
/* Must be at least our own ref + the objcore we examine */
425429
assert(oh->refcnt > 1);
@@ -451,7 +455,8 @@ HSH_Lookup(struct req *req, struct objcore **ocp, struct objcore **bocp)
451455
if (oc->ttl <= 0.)
452456
continue;
453457

454-
if (BAN_CheckObject(wrk, oc, req)) {
458+
if (ban_checks++ < ban_any_variant
459+
&& BAN_CheckObject(wrk, oc, req)) {
455460
oc->flags |= OC_F_DYING;
456461
EXP_Remove(oc, NULL);
457462
continue;
@@ -466,6 +471,13 @@ HSH_Lookup(struct req *req, struct objcore **ocp, struct objcore **bocp)
466471
}
467472
}
468473

474+
if (ban_checks >= ban_any_variant
475+
&& BAN_CheckObject(wrk, oc, req)) {
476+
oc->flags |= OC_F_DYING;
477+
EXP_Remove(oc, NULL);
478+
continue;
479+
}
480+
469481
if (req->vcf != NULL) {
470482
vr = req->vcf->func(req, &oc, &exp_oc, 0);
471483
if (vr == VCF_CONTINUE)

bin/varnishtest/tests/c00133.vtc

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
varnishtest "test ban + vary behavior"
2+
3+
server s0 {
4+
rxreq
5+
txresp -hdr "vary: version" -body "Variant A"
6+
rxreq
7+
txresp -hdr "vary: version" -body "Variant B"
8+
rxreq
9+
txresp -hdr "vary: version" -body "New variant A"
10+
rxreq
11+
txresp -hdr "vary: version" -body "New variant B"
12+
} -start
13+
14+
varnish v1 -arg "-p ban_any_variant=0" -vcl+backend {} -start
15+
16+
client c1 {
17+
txreq -hdr "version: a"
18+
rxresp
19+
expect resp.body == "Variant A"
20+
} -run
21+
22+
client c2 {
23+
txreq -hdr "version: b"
24+
rxresp
25+
expect resp.body == "Variant B"
26+
} -run
27+
28+
varnish v1 -cliok "ban req.http.version == a"
29+
30+
# Should this remove a single variant from cache
31+
client c3 {
32+
txreq -hdr "version: a"
33+
rxresp
34+
expect resp.body == "New variant A"
35+
} -run
36+
37+
client c4 {
38+
txreq -hdr "version: b"
39+
rxresp
40+
expect resp.body == "Variant B"
41+
} -run

0 commit comments

Comments
 (0)