[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