diff --git a/bin/varnishd/cache/cache_fetch.c b/bin/varnishd/cache/cache_fetch.c index 55374cf091..0cdfe0239f 100644 --- a/bin/varnishd/cache/cache_fetch.c +++ b/bin/varnishd/cache/cache_fetch.c @@ -382,6 +382,7 @@ vbf_stp_startfetch(struct worker *wrk, struct busyobj *bo) vtim_real now; unsigned handling, skip_vbr = 0; struct objcore *oc; + const char *met; CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); @@ -396,8 +397,14 @@ vbf_stp_startfetch(struct worker *wrk, struct busyobj *bo) http_PrintfHeader(bo->bereq, "X-Varnish: %ju", VXID(bo->vsl->wid)); - if (bo->bereq_body == NULL && bo->req == NULL) - http_Unset(bo->bereq, H_Content_Length); + if (bo->bereq_body == NULL && bo->req == NULL) { + met = http_GetMethod(bo->bereq); + if (http_method_eq(met, GET) || + http_method_eq(met, HEAD)) + http_Unset(bo->bereq, H_Content_Length); + else + http_ForceHeader(bo->bereq, H_Content_Length, "0"); + } VCL_backend_fetch_method(bo->vcl, wrk, NULL, bo, NULL); diff --git a/bin/varnishtest/tests/e00036.vtc b/bin/varnishtest/tests/e00036.vtc index 9e6e7d86f5..3cd0254e12 100644 --- a/bin/varnishtest/tests/e00036.vtc +++ b/bin/varnishtest/tests/e00036.vtc @@ -17,7 +17,7 @@ server s1 { expect req.method == XGET expect req.url == "/foo/body1" expect req.bodylen == 0 - expect req.http.Content-Length == "" + expect req.http.Content-Length == "0" expect req.http.Transfer-Encoding == "" txresp -body { Included file @@ -40,7 +40,7 @@ server s1 { expect req.method == XGET expect req.url == "/foo/body2" expect req.bodylen == 0 - expect req.http.Content-Length == "" + expect req.http.Content-Length == "0" expect req.http.Transfer-Encoding == "" txresp -body { Included file diff --git a/bin/varnishtest/tests/r04340.vtc b/bin/varnishtest/tests/r04340.vtc new file mode 100644 index 0000000000..64a842d6bf --- /dev/null +++ b/bin/varnishtest/tests/r04340.vtc @@ -0,0 +1,42 @@ +varnishtest "C-L with empty POST" + +server s1 { + rxreq + expect req.method == "POST" + txresp + expect req.http.content-length == 0 + + rxreq + expect req.method == "GET" + txresp + expect req.http.content-length == 0 +} -start + +varnish v1 -vcl+backend { + sub vcl_backend_error { + if (bereq.method == "GETCL0") { + return (retry); + } + } + sub vcl_backend_fetch { + # trick to get a GET with a C-L: 0 + if (bereq.retries == 0 && bereq.method == "GET") { + set bereq.method = "GETCL0"; + return (error); + } + else if (bereq.method == "GETCL0") { + set bereq.method = "GET"; + } + return (fetch); + } +} -start + +client c1 { + txreq -method POST -hdr "content-length: 0" + rxresp + + txreq -method GET -hdr "content-length: 0" + rxresp +} -run + +server s1 -wait