[6.0] bb73128a9 vbf: Prevent pooling of a Connection:close beresp
Reza Naghibi
reza at naghibi.com
Tue Apr 20 18:16:05 UTC 2021
commit bb73128a90f69e6b265f2d0ff8d6ca2ec11a0f55
Author: Dridi Boukelmoune <dridi.boukelmoune at gmail.com>
Date: Tue Sep 8 11:36:52 2020 +0200
vbf: Prevent pooling of a Connection:close beresp
Whether the header was set by the backend or directly in VCL, it is now
possible to signal that a backend connection should not be added back to
the pool after a successful fetch with a Connection:close header.
Pooling such a connection would be counter-productive if closing the
session was requested by the backend itself, because it would then be
likely that reusing the connection would result in busting the extra
chance.
Setting the Connection:close directly in VCL can help mitigating against
a misbehaving backend.
Refs #3400
diff --git a/bin/varnishd/cache/cache_fetch.c b/bin/varnishd/cache/cache_fetch.c
index 026b61452..cc39e16cd 100644
--- a/bin/varnishd/cache/cache_fetch.c
+++ b/bin/varnishd/cache/cache_fetch.c
@@ -437,6 +437,10 @@ vbf_stp_startfetch(struct worker *wrk, struct busyobj *bo)
VCL_backend_response_method(bo->vcl, wrk, NULL, bo, NULL);
+ if (bo->htc != NULL && bo->htc->doclose == SC_NULL &&
+ http_GetHdrField(bo->beresp, H_Connection, "close", NULL))
+ bo->htc->doclose = SC_RESP_CLOSE;
+
if (wrk->handling == VCL_RET_ABANDON || wrk->handling == VCL_RET_FAIL ||
wrk->handling == VCL_RET_ERROR) {
if (bo->htc)
diff --git a/bin/varnishtest/tests/b00073.vtc b/bin/varnishtest/tests/b00073.vtc
new file mode 100644
index 000000000..6cae03450
--- /dev/null
+++ b/bin/varnishtest/tests/b00073.vtc
@@ -0,0 +1,39 @@
+varnishtest "backend connection close"
+
+server s1 {
+ rxreq
+ expect req.http.beresp-connection ~ close
+ txresp
+ expect_close
+
+ accept
+ rxreq
+ expect req.http.beresp-connection !~ close
+ txresp -hdr "connection: close"
+ expect_close
+} -start
+
+varnish v1 -vcl+backend {
+ sub vcl_recv {
+ return (pass);
+ }
+ sub vcl_backend_response {
+ # NB: this overrides unconditionally on purpose
+ set beresp.http.connection = bereq.http.beresp-connection;
+ }
+} -start
+
+client c1 {
+ txreq -hdr "beresp-connection: close, x-varnish"
+ rxresp
+ expect resp.status == 200
+
+ txreq
+ rxresp
+ expect resp.status == 200
+} -run
+
+server s1 -wait
+
+varnish v1 -expect MAIN.backend_recycle == 0
+varnish v1 -expect VBE.vcl1.s1.conn == 0
More information about the varnish-commit
mailing list