[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