[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