[master] dbd9bd12d vrb: Don't cache an empty body

Dridi Boukelmoune dridi.boukelmoune at gmail.com
Wed Jul 3 09:39:05 UTC 2024


commit dbd9bd12d7e15bd364d23c0f32b1190154c7cc3f
Author: Dridi Boukelmoune <dridi.boukelmoune at gmail.com>
Date:   Fri Apr 8 19:40:55 2022 +0200

    vrb: Don't cache an empty body
    
    It's either guaranteed to fail a fetch or cache nothing, in the sense of
    accessing to the request body through a VMOD. It is still possible to
    end up with an empty body cached, if req.body turned out to be empty and
    couldn't be predicted. It is no longer possible to actively try caching
    an empty one.

diff --git a/bin/varnishd/cache/cache_req_body.c b/bin/varnishd/cache/cache_req_body.c
index 51d45471e..f2c894cc0 100644
--- a/bin/varnishd/cache/cache_req_body.c
+++ b/bin/varnishd/cache/cache_req_body.c
@@ -66,6 +66,7 @@ vrb_pull(struct req *req, ssize_t maxsize, objiterate_f *func, void *priv)
 	CHECK_OBJ_NOTNULL(req->htc, HTTP_CONN_MAGIC);
 	CHECK_OBJ_NOTNULL(req->vfc, VFP_CTX_MAGIC);
 	vfc = req->vfc;
+	AN(maxsize);
 
 	req->body_oc = HSH_Private(req->wrk);
 	AN(req->body_oc);
@@ -300,7 +301,11 @@ VRB_Cache(struct req *req, ssize_t maxsize)
 
 	CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
 	assert (req->req_step == R_STP_RECV);
-	assert(maxsize >= 0);
+
+	if (maxsize <= 0) {
+		VSLb(req->vsl, SLT_VCL_Error, "Cannot cache an empty req.body");
+		return (-1);
+	}
 
 	/*
 	 * We only allow caching to happen the first time through vcl_recv{}
diff --git a/bin/varnishtest/tests/c00055.vtc b/bin/varnishtest/tests/c00055.vtc
index 048421967..1656baa61 100644
--- a/bin/varnishtest/tests/c00055.vtc
+++ b/bin/varnishtest/tests/c00055.vtc
@@ -17,7 +17,8 @@ varnish v1 -vcl+backend {
 	import std;
 
 	sub vcl_recv {
-		set req.http.stored = std.cache_req_body(1KB);
+		set req.http.stored = std.cache_req_body(
+			std.bytes(req.http.cache, 1KB));
 		return (pass);
 	}
 
@@ -74,3 +75,45 @@ client c5 {
 	txreq -req POST -hdr "Content-Length: 1025"
 	expect_close
 } -run
+
+server s1 {
+        rxreq
+        expect req.body == chunked_body
+        txresp
+} -start
+
+client c6 {
+        txreq -req POST -nolen -hdr "Transfer-Encoding: chunked"
+        chunked chunked
+        chunked _
+        chunked body
+        chunkedlen 0
+        rxresp
+        expect resp.http.stored == true
+} -run
+
+server s1 {
+        rxreq
+        expect req.bodylen == 0
+        txresp
+} -start
+
+client c7 {
+        txreq -req POST -nolen -hdr "Transfer-Encoding: chunked"
+        chunkedlen 0
+        rxresp
+        expect resp.http.stored == true
+} -run
+
+server s1 {
+        rxreq
+        expect req.bodylen == 0
+        txresp
+} -start
+
+client c8 {
+        txreq -req POST -nolen -hdr "cache: 0B" -hdr "Transfer-Encoding: chunked"
+        chunkedlen 0
+        rxresp
+        expect resp.http.stored == false
+} -run


More information about the varnish-commit mailing list