[master] 5b21cb888 vbf: Prevent pooling of a Connection:close beresp
Dridi Boukelmoune
dridi.boukelmoune at gmail.com
Fri Sep 11 08:37:08 UTC 2020
commit 5b21cb8885c987d9812e046c56e871f6793f6c13
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 1c71e08b4..c09ecafe7 100644
--- a/bin/varnishd/cache/cache_fetch.c
+++ b/bin/varnishd/cache/cache_fetch.c
@@ -452,6 +452,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) {
/* do not count deliberately ending the backend connection as
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