[master] 0ea8328 Further split the "how" from the "what" of response delivery.
Poul-Henning Kamp
phk at varnish-cache.org
Wed Sep 4 15:14:24 CEST 2013
commit 0ea83286f2aca91d4f8f33c4589dd3e70aebfac7
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date: Wed Sep 4 13:12:45 2013 +0000
Further split the "how" from the "what" of response delivery.
Here be dragons. For instance that if a HEAD is passed, we should
let the Content-Length: unmolested through, whereas normally C-L is a
property of the protocol delivery of the HTTP response.
diff --git a/bin/varnishd/cache/cache_fetch.c b/bin/varnishd/cache/cache_fetch.c
index 8b806be..4c926e9 100644
--- a/bin/varnishd/cache/cache_fetch.c
+++ b/bin/varnishd/cache/cache_fetch.c
@@ -306,8 +306,7 @@ vbf_stp_fetch(struct worker *wrk, struct busyobj *bo)
if (bo->htc.body_status == BS_NONE)
bo->do_stream = 0;
- l = http_EstimateWS(bo->beresp,
- bo->uncacheable ? HTTPH_R_PASS : HTTPH_A_INS, &nhttp);
+ l = 0;
/* Create Vary instructions */
if (!(bo->fetch_objcore->flags & OC_F_PRIVATE)) {
@@ -331,18 +330,15 @@ vbf_stp_fetch(struct worker *wrk, struct busyobj *bo)
AZ(vary);
}
+ l += http_EstimateWS(bo->beresp,
+ bo->uncacheable ? HTTPH_R_PASS : HTTPH_A_INS, &nhttp);
+
if (bo->uncacheable)
bo->fetch_objcore->flags |= OC_F_PASS;
if (bo->exp.ttl < cache_param->shortlived || bo->uncacheable == 1)
bo->storage_hint = TRANSIENT_STORAGE;
- /*
- * Space for producing a Content-Length: header including padding
- * A billion gigabytes is enough for anybody.
- */
- l += strlen("Content-Length: XxxXxxXxxXxxXxxXxx") + sizeof(void *);
-
AZ(bo->stats);
bo->stats = &wrk->stats;
AN(bo->fetch_objcore);
diff --git a/bin/varnishd/cache/cache_http1_fetch.c b/bin/varnishd/cache/cache_http1_fetch.c
index 01511e8..e8dbdaa 100644
--- a/bin/varnishd/cache/cache_http1_fetch.c
+++ b/bin/varnishd/cache/cache_http1_fetch.c
@@ -311,7 +311,6 @@ V1F_fetch_body(struct worker *wrk, struct busyobj *bo)
{
int cls;
struct storage *st;
- int mklen;
ssize_t cl;
struct http_conn *htc;
struct object *obj;
@@ -342,10 +341,8 @@ V1F_fetch_body(struct worker *wrk, struct busyobj *bo)
cls = bo->should_close;
switch (htc->body_status) {
case BS_NONE:
- mklen = 0;
break;
case BS_ZERO:
- mklen = 1;
break;
case BS_LENGTH:
cl = vbf_fetch_number(bo->h_content_length, 10);
@@ -353,7 +350,6 @@ V1F_fetch_body(struct worker *wrk, struct busyobj *bo)
bo->vfp->begin(bo, cl);
if (bo->state == BOS_FETCHING && cl > 0)
cls |= vbf_fetch_straight(bo, htc, cl);
- mklen = 1;
if (bo->vfp->end(bo))
assert(bo->state == BOS_FAILED);
break;
@@ -361,7 +357,6 @@ V1F_fetch_body(struct worker *wrk, struct busyobj *bo)
bo->vfp->begin(bo, cl > 0 ? cl : 0);
if (bo->state == BOS_FETCHING)
cls |= vbf_fetch_chunked(bo, htc);
- mklen = 1;
if (bo->vfp->end(bo))
assert(bo->state == BOS_FAILED);
break;
@@ -369,17 +364,14 @@ V1F_fetch_body(struct worker *wrk, struct busyobj *bo)
bo->vfp->begin(bo, cl > 0 ? cl : 0);
if (bo->state == BOS_FETCHING)
vbf_fetch_eof(bo, htc);
- mklen = 1;
cls = 1;
if (bo->vfp->end(bo))
assert(bo->state == BOS_FAILED);
break;
case BS_ERROR:
cls |= VFP_Error(bo, "error incompatible Transfer-Encoding");
- mklen = 0;
break;
default:
- mklen = 0;
INCOMPL();
}
AZ(bo->vgz_rx);
@@ -401,9 +393,8 @@ V1F_fetch_body(struct worker *wrk, struct busyobj *bo)
bo->vfp = NULL;
- VSLb(bo->vsl, SLT_Fetch_Body, "%u(%s) cls %d mklen %d",
- htc->body_status, body_status_2str(htc->body_status),
- cls, mklen);
+ VSLb(bo->vsl, SLT_Fetch_Body, "%u(%s) cls %d",
+ htc->body_status, body_status_2str(htc->body_status), cls);
http_Teardown(bo->bereq);
http_Teardown(bo->beresp);
@@ -440,12 +431,6 @@ V1F_fetch_body(struct worker *wrk, struct busyobj *bo)
else
assert(uu == obj->len);
}
-
- if (mklen > 0) {
- http_Unset(obj->http, H_Content_Length);
- http_PrintfHeader(obj->http,
- "Content-Length: %zd", obj->len);
- }
}
bo->stats = NULL;
}
diff --git a/bin/varnishd/cache/cache_req_fsm.c b/bin/varnishd/cache/cache_req_fsm.c
index bfde6f7..9ed176e 100644
--- a/bin/varnishd/cache/cache_req_fsm.c
+++ b/bin/varnishd/cache/cache_req_fsm.c
@@ -169,45 +169,6 @@ cnt_deliver(struct worker *wrk, struct req *req)
assert(req->obj->objcore->refcnt > 0);
- req->res_mode = 0;
-
- 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;
- } else if (req->obj->objcore->busyobj == NULL) {
- req->res_mode |= RES_LEN;
- }
-
- if (req->esi_level > 0) {
- /* Included ESI object, always CHUNKED or EOF */
- req->res_mode &= ~RES_LEN;
- req->res_mode |= RES_ESI_CHILD;
- }
-
- if (cache_param->http_gzip_support && req->obj->gziped &&
- !RFC2616_Req_Gzip(req->http)) {
- /*
- * We don't know what it uncompresses to
- * XXX: we could cache that
- */
- req->res_mode &= ~RES_LEN;
- req->res_mode |= RES_GUNZIP;
- }
-
- 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) {
- req->res_mode |= RES_CHUNKED;
- } else {
- req->res_mode |= RES_EOF;
- req->doclose = SC_TX_EOF;
- }
- }
- VSLb(req->vsl, SLT_Debug, "RES_MODE %x", req->res_mode);
-
req->t_resp = W_TIM_real(wrk);
if (!(req->obj->objcore->flags & OC_F_PRIVATE)) {
if ((req->t_resp - req->obj->last_lru) >
@@ -224,7 +185,7 @@ cnt_deliver(struct worker *wrk, struct req *req)
http_FilterResp(req->obj->http, req->resp, 0);
http_Unset(req->resp, H_Date);
- VTIM_format(VTIM_real(), time_str);
+ VTIM_format(req->t_resp, time_str);
http_PrintfHeader(req->resp, "Date: %s", time_str);
if (req->wrk->stats.cache_hit)
@@ -239,17 +200,15 @@ cnt_deliver(struct worker *wrk, struct req *req)
req->obj->exp.age + req->t_resp - req->obj->exp.entered);
http_SetHeader(req->resp, "Via: 1.1 varnish");
-
VCL_deliver_method(req->vcl, wrk, req, NULL, req->http->ws);
- RES_BuildHttp(req);
-
while (req->obj->objcore->busyobj) {
VSLb(req->vsl, SLT_Debug, "HERE %s %d", __func__, __LINE__);
(void)usleep(10000);
}
+ RES_BuildHttp(req);
/* Stop the insanity before it turns "Hotel California" on us */
if (req->restarts >= cache_param->max_restarts)
diff --git a/bin/varnishd/cache/cache_response.c b/bin/varnishd/cache/cache_response.c
index 0dee670..c56932e 100644
--- a/bin/varnishd/cache/cache_response.c
+++ b/bin/varnishd/cache/cache_response.c
@@ -108,13 +108,57 @@ RES_BuildHttp(struct req *req)
CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
CHECK_OBJ_NOTNULL(req->obj, OBJECT_MAGIC);
- if (!(req->res_mode & RES_LEN)) {
- http_Unset(req->resp, H_Content_Length);
- } else if (cache_param->http_range_support) {
- /* We only accept ranges if we know the length */
- http_SetHeader(req->resp, "Accept-Ranges: bytes");
+ req->res_mode = 0;
+
+ 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;
+ } else if (req->obj->objcore->busyobj == NULL) {
+ /* XXX: Not happy with this convoluted test */
+ 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 (cache_param->http_range_support)
+ http_SetHeader(req->resp, "Accept-Ranges: bytes");
+ }
+
+ if (req->esi_level > 0) {
+ /* Included ESI object, always CHUNKED or EOF */
+ req->res_mode &= ~RES_LEN;
+ req->res_mode |= RES_ESI_CHILD;
+ }
+
+ if (cache_param->http_gzip_support && req->obj->gziped &&
+ !RFC2616_Req_Gzip(req->http)) {
+ /*
+ * We don't know what it uncompresses to
+ * XXX: we could cache that
+ */
+ req->res_mode &= ~RES_LEN;
+ req->res_mode |= RES_GUNZIP;
}
+ 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) {
+ req->res_mode |= RES_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);
diff --git a/bin/varnishd/cache/cache_vrt.c b/bin/varnishd/cache/cache_vrt.c
index de2cf78..36b2a43 100644
--- a/bin/varnishd/cache/cache_vrt.c
+++ b/bin/varnishd/cache/cache_vrt.c
@@ -419,8 +419,6 @@ VRT_synth_page(const struct vrt_ctx *ctx, unsigned flags, const char *str, ...)
va_end(ap);
SMS_Finish(ctx->req->obj);
http_Unset(ctx->req->obj->http, H_Content_Length);
- http_PrintfHeader(ctx->req->obj->http,
- "Content-Length: %zd", ctx->req->obj->len);
}
/*--------------------------------------------------------------------*/
More information about the varnish-commit
mailing list