[master] 91100b4 Always send the request body to the backend

Federico G. Schwindt fgsch at lodoss.net
Mon Jun 27 19:23:07 CEST 2016


commit 91100b4cded00150facaf45d3fa5508a6893a304
Author: Federico G. Schwindt <fgsch at lodoss.net>
Date:   Fri Jun 24 00:39:30 2016 +0100

    Always send the request body to the backend
    
    Before this commit it was only sent on pass'd requests, making
    impossible to cache e.g. POST requests.
    
    To keep the previous behaviour unset bereq.body if the method is GET,
    which is normally true for misses.
    
    Fixes #1927.

diff --git a/bin/varnishd/builtin.vcl b/bin/varnishd/builtin.vcl
index 68216db..de237d6 100644
--- a/bin/varnishd/builtin.vcl
+++ b/bin/varnishd/builtin.vcl
@@ -148,6 +148,9 @@ sub vcl_synth {
 # Backend Fetch
 
 sub vcl_backend_fetch {
+    if (bereq.method == "GET") {
+        unset bereq.body;
+    }
     return (fetch);
 }
 
diff --git a/bin/varnishd/cache/cache_fetch.c b/bin/varnishd/cache/cache_fetch.c
index 0239b6e..89a346b 100644
--- a/bin/varnishd/cache/cache_fetch.c
+++ b/bin/varnishd/cache/cache_fetch.c
@@ -180,8 +180,6 @@ vbf_stp_mkbereq(struct worker *wrk, struct busyobj *bo)
 		http_ForceField(bo->bereq0, HTTP_HDR_PROTO, "HTTP/1.1");
 		if (cache_param->http_gzip_support)
 			http_ForceHeader(bo->bereq0, H_Accept_Encoding, "gzip");
-		AN(bo->req);
-		bo->req = NULL;
 		http_CopyHome(bo->bereq0);
 	} else
 		AZ(bo->stale_oc);
@@ -204,7 +202,10 @@ vbf_stp_mkbereq(struct worker *wrk, struct busyobj *bo)
 	bo->ws_bo = WS_Snapshot(bo->ws);
 	HTTP_Copy(bo->bereq, bo->bereq0);
 
-	ObjSetState(bo->wrk, bo->fetch_objcore, BOS_REQ_DONE);
+	if (bo->req->req_body_status == REQ_BODY_NONE) {
+		bo->req = NULL;
+		ObjSetState(bo->wrk, bo->fetch_objcore, BOS_REQ_DONE);
+	}
 	return (F_STP_STARTFETCH);
 }
 
@@ -223,7 +224,7 @@ vbf_stp_retry(struct worker *wrk, struct busyobj *bo)
 	vfc = bo->vfc;
 	CHECK_OBJ_NOTNULL(vfc, VFP_CTX_MAGIC);
 
-	assert(bo->fetch_objcore->boc->state == BOS_REQ_DONE);
+	assert(bo->fetch_objcore->boc->state <= BOS_REQ_DONE);
 
 	VSLb_ts_busyobj(bo, "Retry", W_TIM_real(wrk));
 
@@ -263,11 +264,6 @@ vbf_stp_startfetch(struct worker *wrk, struct busyobj *bo)
 
 	AZ(bo->storage_hint);
 
-	if (bo->do_pass)
-		AN(bo->req);
-	else
-		AZ(bo->req);
-
 	if (bo->retries > 0)
 		http_Unset(bo->bereq, "\012X-Varnish:");
 
@@ -457,7 +453,11 @@ vbf_stp_startfetch(struct worker *wrk, struct busyobj *bo)
 		return (F_STP_ERROR);
 	}
 
-	assert(bo->fetch_objcore->boc->state == BOS_REQ_DONE);
+	assert(bo->fetch_objcore->boc->state <= BOS_REQ_DONE);
+	if (bo->fetch_objcore->boc->state != BOS_REQ_DONE) {
+		bo->req = NULL;
+		ObjSetState(wrk, bo->fetch_objcore, BOS_REQ_DONE);
+	}
 
 	if (bo->do_esi)
 		bo->do_stream = 0;
diff --git a/bin/varnishtest/tests/r01927.vtc b/bin/varnishtest/tests/r01927.vtc
new file mode 100644
index 0000000..e981521
--- /dev/null
+++ b/bin/varnishtest/tests/r01927.vtc
@@ -0,0 +1,46 @@
+varnishtest "Test requests other than GET are cacheable"
+
+server s1 {
+	rxreq
+	expect req.method == "POST"
+	expect req.body == "foo"
+	txresp -body bar
+	rxreq
+	expect req.method == "POST"
+	expect req.body == "foo"
+	txresp -body baz
+} -start
+
+varnish v1 -vcl+backend {
+	sub vcl_recv {
+		# We ignore the actual body and verb for this test.
+		return (hash);
+	}
+	sub vcl_miss {
+		return (fetch);
+	}
+	sub vcl_backend_fetch {
+		set bereq.method = "POST";
+		set bereq.first_byte_timeout = 1s;
+	}
+	sub vcl_backend_response {
+		set beresp.ttl = 1s;
+		set beresp.grace = 2s;
+	}
+} -start
+
+client c1 {
+	txreq -req "POST" -body "foo"
+	rxresp
+	expect resp.body == "bar"
+	txreq -req "POST" -body "foo"
+	rxresp
+	expect resp.body == "bar"
+	delay 1
+	txreq -req "POST" -body "foo"
+	rxresp
+	expect resp.body == "bar"
+	txreq -req "POST" -body "foo"
+	rxresp
+	expect resp.body == "baz"
+} -run
diff --git a/include/tbl/http_headers.h b/include/tbl/http_headers.h
index 5ada35a..198049b 100644
--- a/include/tbl/http_headers.h
+++ b/include/tbl/http_headers.h
@@ -71,7 +71,7 @@ H("Cache-Control",	H_Cache_Control,	  F    )	// 2616 14.9
 H("Connection",		H_Connection,		P|F|I|S)	// 2616 14.10
 H("Content-Encoding",	H_Content_Encoding,	0      )	// 2616 14.11
 H("Content-Language",	H_Content_Language,	0      )	// 2616 14.12
-H("Content-Length",	H_Content_Length,	  F    )	// 2616 14.13
+H("Content-Length",	H_Content_Length,	0      )	// 2616 14.13
 H("Content-Location",	H_Content_Location,	0      )	// 2616 14.14
 H("Content-MD5",	H_Content_MD5,		0      )	// 2616 14.15
 H("Content-Range",	H_Content_Range,	  F|I  )	// 2616 14.16



More information about the varnish-commit mailing list