[6.0] 8b36d0387 vbf: Prevent pooling of a Connection:close bereq
Reza Naghibi
reza at naghibi.com
Tue Apr 20 18:16:06 UTC 2021
commit 8b36d0387d3a7f99b218cff2ede4198c57487eb8
Author: Dridi Boukelmoune <dridi.boukelmoune at gmail.com>
Date: Tue Sep 29 08:14:58 2020 +0200
vbf: Prevent pooling of a Connection:close bereq
Once we ask the backend to close the connection after a given request
there is no benefit from putting the backend connection back in the
pool. It's actually a surefire way to force a subsequent backend fetch
to fail its first attempt and go straight to its extra chance.
Since we try to maximize connection reuse this would have to come from
VCL and a user asking for the backend to close the connection should
have a good reason to do so, for example when the backend is known to
misbehave under certain circumstances.
Closes #3400
Refs #3405
diff --git a/bin/varnishd/cache/cache_fetch.c b/bin/varnishd/cache/cache_fetch.c
index cc39e16cd..63d3564fe 100644
--- a/bin/varnishd/cache/cache_fetch.c
+++ b/bin/varnishd/cache/cache_fetch.c
@@ -435,6 +435,10 @@ vbf_stp_startfetch(struct worker *wrk, struct busyobj *bo)
if (http_IsStatus(bo->beresp, 304) && vbf_304_logic(bo) < 0)
return (F_STP_ERROR);
+ if (bo->htc->doclose == SC_NULL &&
+ http_GetHdrField(bo->bereq, H_Connection, "close", NULL))
+ bo->htc->doclose = SC_REQ_CLOSE;
+
VCL_backend_response_method(bo->vcl, wrk, NULL, bo, NULL);
if (bo->htc != NULL && bo->htc->doclose == SC_NULL &&
diff --git a/bin/varnishtest/tests/b00073.vtc b/bin/varnishtest/tests/b00073.vtc
index 6cae03450..3372ba094 100644
--- a/bin/varnishtest/tests/b00073.vtc
+++ b/bin/varnishtest/tests/b00073.vtc
@@ -2,28 +2,54 @@ varnishtest "backend connection close"
server s1 {
rxreq
+ expect req.http.connection ~ close
+ expect req.http.beresp-connection !~ close
+ txresp
+ expect_close
+
+ accept
+ rxreq
+ expect req.http.connection !~ close
expect req.http.beresp-connection ~ close
txresp
expect_close
accept
rxreq
+ expect req.http.connection !~ close
expect req.http.beresp-connection !~ close
txresp -hdr "connection: close"
expect_close
+
+ accept
+ rxreq
+ expect req.http.connection ~ close
+ expect req.http.unset-connection == true
+ txresp
+ expect_close
} -start
varnish v1 -vcl+backend {
sub vcl_recv {
return (pass);
}
+ sub vcl_backend_fetch {
+ set bereq.http.connection = bereq.http.bereq-connection;
+ }
sub vcl_backend_response {
+ if (bereq.http.unset-connection) {
+ unset bereq.http.connection;
+ }
# NB: this overrides unconditionally on purpose
set beresp.http.connection = bereq.http.beresp-connection;
}
} -start
client c1 {
+ txreq -hdr "bereq-connection: close, x-varnish"
+ rxresp
+ expect resp.status == 200
+
txreq -hdr "beresp-connection: close, x-varnish"
rxresp
expect resp.status == 200
@@ -31,6 +57,10 @@ client c1 {
txreq
rxresp
expect resp.status == 200
+
+ txreq -hdr "bereq-connection: close" -hdr "unset-connection: true"
+ rxresp
+ expect resp.status == 200
} -run
server s1 -wait
More information about the varnish-commit
mailing list