[4.0] 419a08f Fix a cornercase related to empty pass objects.
Martin Blix Grydeland
martin at varnish-software.com
Fri Nov 7 14:17:23 CET 2014
commit 419a08f5362a0b9885ecae5cc443fb82e2c3c002
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date: Tue Oct 21 09:00:52 2014 +0000
Fix a cornercase related to empty pass objects.
Fixes #1612
Testcase by: daghf
Conflicts:
bin/varnishd/cache/cache_http1_deliver.c
diff --git a/bin/varnishd/cache/cache_http1_deliver.c b/bin/varnishd/cache/cache_http1_deliver.c
index 73aea69..9b0d51b 100644
--- a/bin/varnishd/cache/cache_http1_deliver.c
+++ b/bin/varnishd/cache/cache_http1_deliver.c
@@ -240,29 +240,36 @@ V1D_Deliver(struct req *req, struct busyobj *bo)
req->res_mode = 0;
+ if (req->esi_level > 0)
+ req->res_mode |= RES_ESI_CHILD;
+
if (!req->disable_esi && req->obj->esidata != NULL) {
/* In ESI mode, we can't know the aggregate length */
- req->res_mode &= ~RES_LEN;
req->res_mode |= RES_ESI;
+ RFC2616_Weaken_Etag(req->resp);
+ }
+
+ if (req->res_mode & (RES_ESI_CHILD|RES_ESI)) {
+ /* nothing */
} else if (req->resp->status == 304) {
req->res_mode &= ~RES_LEN;
http_Unset(req->resp, H_Content_Length);
req->wantbody = 0;
- } else if (bo == NULL) {
- /* XXX: Not happy with this convoluted test */
+ } else if (bo != NULL) {
+ /* Streaming, decide CHUNKED/EOF later */
+ } else if ((req->obj->objcore->flags & OC_F_PASS) && !req->wantbody) {
+ /*
+ * if we pass a HEAD the C-L header may already be in the
+ * object and it will not match the actual storage length
+ * which is zero.
+ * Hand that C-L header back to client.
+ */
req->res_mode |= RES_LEN;
- if (!(req->obj->objcore->flags & OC_F_PASS) ||
- req->obj->len != 0) {
- http_Unset(req->resp, H_Content_Length);
- http_PrintfHeader(req->resp,
- "Content-Length: %zd", req->obj->len);
- }
- }
-
- if (req->esi_level > 0) {
- /* Included ESI object, always CHUNKED or EOF */
- req->res_mode &= ~RES_LEN;
- req->res_mode |= RES_ESI_CHILD;
+ } else {
+ req->res_mode |= RES_LEN;
+ http_Unset(req->resp, H_Content_Length);
+ http_PrintfHeader(req->resp,
+ "Content-Length: %zd", req->obj->len);
}
if (cache_param->http_gzip_support && req->obj->gziped &&
@@ -314,9 +321,6 @@ V1D_Deliver(struct req *req, struct busyobj *bo)
v1d_dorange(req, bo, r);
}
- if (req->res_mode & RES_ESI)
- RFC2616_Weaken_Etag(req->resp);
-
WRW_Reserve(req->wrk, &req->sp->fd, req->vsl, req->t_prev);
/*
diff --git a/bin/varnishtest/tests/r00730.vtc b/bin/varnishtest/tests/r00730.vtc
index bb416e8..67b9598 100644
--- a/bin/varnishtest/tests/r00730.vtc
+++ b/bin/varnishtest/tests/r00730.vtc
@@ -4,7 +4,7 @@ server s1 {
rxreq
txresp -bodylen 5
rxreq
- txresp -bodylen 6
+ txresp -nolen -hdr "Content-Length: 6"
} -start
varnish v1 -vcl+backend {
diff --git a/bin/varnishtest/tests/r01612.vtc b/bin/varnishtest/tests/r01612.vtc
new file mode 100644
index 0000000..e66d3ec
--- /dev/null
+++ b/bin/varnishtest/tests/r01612.vtc
@@ -0,0 +1,52 @@
+varnishtest "Missing Content-Length/T-E on passed empty chunked responses."
+
+server s1 {
+ # Empty c-l response is OK.
+ rxreq
+ expect req.url == "/0"
+ txresp
+
+ # Nonzero chunked response is OK.
+ rxreq
+ expect req.url == "/1"
+ send "HTTP/1.1 200 OK\n"
+ send "Transfer-encoding: chunked\n"
+ send "\n"
+ chunkedlen 20
+ chunkedlen 0
+
+ # Empty chunked response is not.
+ rxreq
+ expect req.url == "/2"
+ send "HTTP/1.1 200 OK\n"
+ send "Transfer-encoding: chunked\n"
+ send "\n"
+ chunkedlen 0
+} -start
+
+varnish v1 -vcl+backend {
+ sub vcl_recv {
+ return (pass);
+ }
+ sub vcl_backend_response {
+ set beresp.do_stream = false;
+ }
+} -start
+
+
+client c1 {
+ txreq -url "/0"
+ rxresp
+ expect resp.bodylen == 0
+ expect resp.http.Content-Length == "0"
+
+ txreq -url "/1"
+ rxresp
+ expect resp.bodylen == 20
+ expect resp.http.Content-Length == "20"
+
+ txreq -url "/2"
+ rxresp
+ expect resp.bodylen == 0
+ expect resp.http.Content-Length == "0"
+} -run
More information about the varnish-commit
mailing list