[master] c42b0d4 Reorder and simplify the logic for determining how we deliver the body (if at all)
Poul-Henning Kamp
phk at FreeBSD.org
Mon Oct 27 21:21:28 CET 2014
commit c42b0d41cbf06dd15e79f2c195bcb092a86d255c
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date: Mon Oct 27 19:56:07 2014 +0000
Reorder and simplify the logic for determining how we deliver
the body (if at all)
diff --git a/bin/varnishd/http1/cache_http1_deliver.c b/bin/varnishd/http1/cache_http1_deliver.c
index 0836f0e..f887a63 100644
--- a/bin/varnishd/http1/cache_http1_deliver.c
+++ b/bin/varnishd/http1/cache_http1_deliver.c
@@ -190,6 +190,7 @@ v1d_dorange(struct req *req, struct busyobj *bo, const char *r)
/*--------------------------------------------------------------------
*/
+
void
V1D_Deliver(struct req *req, struct busyobj *bo)
{
@@ -201,39 +202,41 @@ V1D_Deliver(struct req *req, struct busyobj *bo)
req->res_mode = 0;
+ /*
+ * Determine ESI status first. Not dependent on wantbody, because
+ * we want ESI to supress C-L in HEAD too.
+ */
if (!req->disable_esi &&
ObjGetattr(req->wrk, req->objcore, OA_ESIDATA, NULL) != NULL)
req->res_mode |= RES_ESI;
+ /*
+ * ESI-childen don't care about headers -> early escape
+ */
if (req->esi_level > 0) {
ESI_DeliverChild(req, bo);
return;
}
if (req->res_mode & RES_ESI) {
- /* nothing */
+ RFC2616_Weaken_Etag(req->resp);
+ http_Unset(req->resp, H_Content_Length);
} else if (http_IsStatus(req->resp, 304)) {
- req->res_mode &= ~RES_LEN;
http_Unset(req->resp, H_Content_Length);
req->wantbody = 0;
- } else if (bo != NULL) {
- /* Streaming, decide CHUNKED/EOF later */
- } else if ((req->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;
- } else {
- req->res_mode |= RES_LEN;
- http_Unset(req->resp, H_Content_Length);
+ } else if (bo == NULL &&
+ !http_GetHdr(req->resp, H_Content_Length, NULL)) {
http_PrintfHeader(req->resp,
"Content-Length: %ju", (uintmax_t)ObjGetLen(
req->wrk, req->objcore));
}
+ if (cache_param->http_range_support && http_IsStatus(req->resp, 200)) {
+ http_SetHeader(req->resp, "Accept-Ranges: bytes");
+ if (req->wantbody && http_GetHdr(req->http, H_Range, &r))
+ v1d_dorange(req, bo, r);
+ }
+
if (cache_param->http_gzip_support &&
ObjCheckFlag(req->wrk, req->objcore, OF_GZIPED) &&
!RFC2616_Req_Gzip(req->http)) {
@@ -242,66 +245,47 @@ V1D_Deliver(struct req *req, struct busyobj *bo)
* XXX: we could cache that, but would still deliver
* XXX: with multiple writes because of the gunzip buffer
*/
- req->res_mode &= ~RES_LEN;
req->res_mode |= RES_GUNZIP;
+ http_Unset(req->resp, H_Content_Length);
+ http_Unset(req->resp, H_Content_Encoding);
+ VDP_push(req, VDP_gunzip, NULL, 0);
}
- if (!(req->res_mode & (RES_LEN|RES_CHUNKED|RES_EOF))) {
- /* We havn't chosen yet, do so */
- if (!req->wantbody) {
- /* Nothing */
- } else if (req->http->protover >= 11) {
+ if (http_GetHdr(req->resp, H_Content_Length, NULL))
+ req->res_mode |= RES_LEN;
+
+ if (req->wantbody && !(req->res_mode & RES_LEN)) {
+ if (req->http->protover >= 11) {
req->res_mode |= RES_CHUNKED;
+ http_SetHeader(req->resp, "Transfer-Encoding: chunked");
} else {
req->res_mode |= RES_EOF;
req->doclose = SC_TX_EOF;
}
}
- VSLb(req->vsl, SLT_Debug, "RES_MODE %x", req->res_mode);
-
- if (!(req->res_mode & RES_LEN))
- http_Unset(req->resp, H_Content_Length);
-
- if (req->res_mode & RES_GUNZIP)
- http_Unset(req->resp, H_Content_Encoding);
- if (req->res_mode & RES_CHUNKED)
- http_SetHeader(req->resp, "Transfer-Encoding: chunked");
-
- if (req->res_mode & RES_ESI)
- RFC2616_Weaken_Etag(req->resp);
+ VSLb(req->vsl, SLT_Debug, "RES_MODE %x", req->res_mode);
http_SetHeader(req->resp,
req->doclose ? "Connection: close" : "Connection: keep-alive");
- if (
- req->wantbody &&
- cache_param->http_range_support &&
- http_IsStatus(req->resp, 200)) {
- http_SetHeader(req->resp, "Accept-Ranges: bytes");
- if (http_GetHdr(req->http, H_Range, &r))
- v1d_dorange(req, bo, r);
- }
-
- if (req->res_mode & RES_GUNZIP)
- VDP_push(req, VDP_gunzip, NULL, 0);
-
VDP_push(req, v1d_bytes, NULL, 1);
V1L_Reserve(req->wrk, req->ws, &req->sp->fd, req->vsl, req->t_prev);
req->acct.resp_hdrbytes += HTTP1_Write(req->wrk, req->resp, HTTP1_Resp);
- if (req->res_mode & RES_CHUNKED)
- V1L_Chunked(req->wrk);
-
ois = OIS_DONE;
- if (req->wantbody)
+ if (req->wantbody) {
+ if (req->res_mode & RES_CHUNKED)
+ V1L_Chunked(req->wrk);
+
ois = VDP_DeliverObj(req);
- (void)VDP_bytes(req, VDP_FLUSH, NULL, 0);
+ (void)VDP_bytes(req, VDP_FLUSH, NULL, 0);
- if (ois == OIS_DONE && (req->res_mode & RES_CHUNKED))
- V1L_EndChunk(req->wrk);
+ if (ois == OIS_DONE && (req->res_mode & RES_CHUNKED))
+ V1L_EndChunk(req->wrk);
+ }
if ((V1L_FlushRelease(req->wrk) || ois != OIS_DONE) && req->sp->fd >= 0)
SES_Close(req->sp, SC_REM_CLOSE);
diff --git a/bin/varnishtest/tests/r00801.vtc b/bin/varnishtest/tests/r00801.vtc
index f538d7f..ca1a567 100644
--- a/bin/varnishtest/tests/r00801.vtc
+++ b/bin/varnishtest/tests/r00801.vtc
@@ -13,6 +13,7 @@ varnish v1 -vcl+backend {
sub vcl_recv { return (pass); }
sub vcl_backend_response {
set beresp.do_stream = false;
+ unset beresp.http.content-length;
}
} -start
More information about the varnish-commit
mailing list