[master] 67d69d2f8 cache_vrt_var: for unset bereq.body, remove Content-Length always

Nils Goroll nils.goroll at uplex.de
Thu Feb 6 19:14:06 UTC 2025


commit 67d69d2f8fae919ce9d3fe8e935e1d51fe846d69
Author: Nils Goroll <nils.goroll at uplex.de>
Date:   Thu Feb 6 19:42:22 2025 +0100

    cache_vrt_var: for unset bereq.body, remove Content-Length always
    
    If there is no request body, we need to remove the Content-Length header.
    
    Doing this in VRT_u_bereq_body() is insufficient, because, for a restart on the
    client side and a rollback on the backend side, the headers get restored.
    
    Fixes #4228

diff --git a/bin/varnishd/cache/cache_fetch.c b/bin/varnishd/cache/cache_fetch.c
index 76a819c2c..81608573a 100644
--- a/bin/varnishd/cache/cache_fetch.c
+++ b/bin/varnishd/cache/cache_fetch.c
@@ -410,6 +410,9 @@ vbf_stp_startfetch(struct worker *wrk, struct busyobj *bo)
 
 	VCL_backend_fetch_method(bo->vcl, wrk, NULL, bo, NULL);
 
+	if (bo->bereq_body == NULL && bo->req == NULL)
+		http_Unset(bo->bereq, H_Content_Length);
+
 	if (wrk->vpi->handling == VCL_RET_ABANDON ||
 	    wrk->vpi->handling == VCL_RET_FAIL)
 		return (F_STP_FAIL);
diff --git a/bin/varnishd/cache/cache_vrt_var.c b/bin/varnishd/cache/cache_vrt_var.c
index 5d5be780d..98fbda953 100644
--- a/bin/varnishd/cache/cache_vrt_var.c
+++ b/bin/varnishd/cache/cache_vrt_var.c
@@ -640,17 +640,15 @@ VRT_u_bereq_body(VRT_CTX)
 {
 	CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
 	CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
-	if (ctx->bo->bereq_body != NULL) {
+
+	if (ctx->bo->bereq_body != NULL)
 		(void)HSH_DerefObjCore(ctx->bo->wrk, &ctx->bo->bereq_body, 0);
-		http_Unset(ctx->bo->bereq, H_Content_Length);
-	}
 
 	if (ctx->bo->req != NULL) {
 		CHECK_OBJ(ctx->bo->req, REQ_MAGIC);
 		ctx->bo->req = NULL;
 		ObjSetState(ctx->bo->wrk,
 		    ctx->bo->fetch_objcore, BOS_REQ_DONE);
-		http_Unset(ctx->bo->bereq, H_Content_Length);
 	}
 }
 
diff --git a/bin/varnishtest/tests/v00068.vtc b/bin/varnishtest/tests/v00068.vtc
index cf85d768d..07e77b6f5 100644
--- a/bin/varnishtest/tests/v00068.vtc
+++ b/bin/varnishtest/tests/v00068.vtc
@@ -12,6 +12,18 @@ server s1 {
 	expect req.url == "/cachednobody"
 	expect req.http.Content-Length == <undef>
 	txresp
+
+	rxreq
+	expect req.method == "HEAD"
+	expect req.url == "/head-restart-get"
+	expect req.http.Content-Length == <undef>
+	txresp
+
+	rxreq
+	expect req.method == "GET"
+	expect req.url == "/head-restart-get"
+	expect req.http.Content-Length == <undef>
+	txresp
 } -start
 
 varnish v1 -vcl+backend {
@@ -21,9 +33,28 @@ varnish v1 -vcl+backend {
 		if (req.url == "/cached") {
 			std.cache_req_body(2KB);
 		}
+		set req.http.restarts = req.restarts;
+	}
+
+	sub vcl_hash {
+		hash_data(req.restarts);
 	}
+
+	sub vcl_deliver {
+		if (req.url == "/head-restart-get" && req.restarts == 0) {
+			return (restart);
+		}
+	}
+
 	sub vcl_backend_fetch {
-		unset bereq.body;
+		if (bereq.url == "/head-restart-get" && bereq.http.restarts == "0") {
+			set bereq.method = "HEAD";
+		}
+
+		if (bereq.http.restarts == "0") {
+			unset bereq.body;
+		}
+		return (fetch);
 	}
 } -start
 
@@ -35,4 +66,8 @@ client c1 {
 	txreq -url "/cachednobody"
 	rxresp
 	expect resp.status == 200
+
+	txreq -url "/head-restart-get" -body "fine"
+	rxresp
+	expect resp.status == 200
 } -run


More information about the varnish-commit mailing list