[master] 18596a6 Move fetchbody to cache_fetch.c

Poul-Henning Kamp phk at varnish-cache.org
Thu May 16 21:24:01 CEST 2013


commit 18596a610f5cd2f2e01d9014046a26247fa7dc96
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Thu May 16 19:23:32 2013 +0000

    Move fetchbody to cache_fetch.c

diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h
index b86f4c0..3d47cd8 100644
--- a/bin/varnishd/cache/cache.h
+++ b/bin/varnishd/cache/cache.h
@@ -812,11 +812,11 @@ int EXP_NukeOne(struct busyobj *, struct lru *lru);
 void EXP_NukeLRU(struct worker *wrk, struct vsl_log *vsl, struct lru *lru);
 
 /* cache_fetch.c */
+int VBF_Fetch(struct worker *wrk, struct req *req);
 struct storage *FetchStorage(struct busyobj *, ssize_t sz);
 int FetchError(struct busyobj *, const char *error);
 int FetchError2(struct busyobj *, const char *error, const char *more);
 int FetchHdr(struct worker *wrk, struct busyobj *bo, struct req *req);
-void FetchBody(struct worker *w, void *bo);
 void Fetch_Init(void);
 
 /* cache_gzip.c */
diff --git a/bin/varnishd/cache/cache_fetch.c b/bin/varnishd/cache/cache_fetch.c
index 4bacbf1..f42f62a 100644
--- a/bin/varnishd/cache/cache_fetch.c
+++ b/bin/varnishd/cache/cache_fetch.c
@@ -30,6 +30,7 @@
 #include "config.h"
 
 #include <inttypes.h>
+#include <math.h>
 #include <stdio.h>
 #include <stdlib.h>
 
@@ -41,6 +42,7 @@
 #include "vcli_priv.h"
 #include "vct.h"
 #include "vtcp.h"
+#include "vtim.h"
 
 static unsigned fetchfrag;
 
@@ -472,7 +474,7 @@ FetchHdr(struct worker *wrk, struct busyobj *bo, struct req *req)
  * refcount on it, which we must release, when done fetching.
  */
 
-void
+static void
 FetchBody(struct worker *wrk, void *priv)
 {
 	int cls;
@@ -624,6 +626,240 @@ FetchBody(struct worker *wrk, void *priv)
 }
 
 /*--------------------------------------------------------------------
+ */
+
+int
+VBF_Fetch(struct worker *wrk, struct req *req)
+{
+	struct http *hp, *hp2;
+	char *b;
+	uint16_t nhttp;
+	unsigned l;
+	struct vsb *vary = NULL;
+	int varyl = 0, pass;
+	struct busyobj *bo;
+
+	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
+	CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
+	CHECK_OBJ_NOTNULL(req->objcore, OBJCORE_MAGIC);
+	bo = req->busyobj;
+	CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
+
+	if (req->objcore->objhead == NULL) {
+		/* This is a pass from vcl_recv */
+		pass = 1;
+		/* VCL may have fiddled this, but that doesn't help */
+		bo->exp.ttl = -1.;
+	} else if (bo->do_pass) {
+		pass = 1;
+	} else {
+		/* regular object */
+		pass = 0;
+	}
+
+	/*
+	 * The VCL variables beresp.do_g[un]zip tells us how we want the
+	 * object processed before it is stored.
+	 *
+	 * The backend Content-Encoding header tells us what we are going
+	 * to receive, which we classify in the following three classes:
+	 *
+	 *	"Content-Encoding: gzip"	--> object is gzip'ed.
+	 *	no Content-Encoding		--> object is not gzip'ed.
+	 *	anything else			--> do nothing wrt gzip
+	 *
+	 */
+
+	/* We do nothing unless the param is set */
+	if (!cache_param->http_gzip_support)
+		bo->do_gzip = bo->do_gunzip = 0;
+
+	bo->is_gzip = http_HdrIs(bo->beresp, H_Content_Encoding, "gzip");
+
+	bo->is_gunzip = !http_GetHdr(bo->beresp, H_Content_Encoding, NULL);
+
+	/* It can't be both */
+	assert(bo->is_gzip == 0 || bo->is_gunzip == 0);
+
+	/* We won't gunzip unless it is gzip'ed */
+	if (bo->do_gunzip && !bo->is_gzip)
+		bo->do_gunzip = 0;
+
+	/* If we do gunzip, remove the C-E header */
+	if (bo->do_gunzip)
+		http_Unset(bo->beresp, H_Content_Encoding);
+
+	/* We wont gzip unless it is ungziped */
+	if (bo->do_gzip && !bo->is_gunzip)
+		bo->do_gzip = 0;
+
+	/* If we do gzip, add the C-E header */
+	if (bo->do_gzip)
+		http_SetHeader(bo->beresp, "Content-Encoding: gzip");
+
+	/* But we can't do both at the same time */
+	assert(bo->do_gzip == 0 || bo->do_gunzip == 0);
+
+	/* ESI takes precedence and handles gzip/gunzip itself */
+	if (bo->do_esi)
+		bo->vfp = &vfp_esi;
+	else if (bo->do_gunzip)
+		bo->vfp = &vfp_gunzip;
+	else if (bo->do_gzip)
+		bo->vfp = &vfp_gzip;
+	else if (bo->is_gzip)
+		bo->vfp = &vfp_testgzip;
+
+	if (bo->do_esi || req->esi_level > 0)
+		bo->do_stream = 0;
+	if (!req->wantbody)
+		bo->do_stream = 0;
+
+	/* No reason to try streaming a non-existing body */
+	if (bo->htc.body_status == BS_NONE)
+		bo->do_stream = 0;
+
+	l = http_EstimateWS(bo->beresp,
+	    pass ? HTTPH_R_PASS : HTTPH_A_INS, &nhttp);
+
+	/* Create Vary instructions */
+	if (req->objcore->objhead != NULL) {
+		varyl = VRY_Create(bo, &vary);
+		if (varyl > 0) {
+			AN(vary);
+			assert(varyl == VSB_len(vary));
+			l += varyl;
+		} else if (varyl < 0) {
+			/* Vary parse error */
+			AZ(vary);
+			AZ(HSH_Deref(&wrk->stats, req->objcore, NULL));
+			req->objcore = NULL;
+			VDI_CloseFd(&bo->vbc);
+			VBO_DerefBusyObj(wrk, &req->busyobj);
+			return (-1);
+		} else
+			/* No vary */
+			AZ(vary);
+	}
+
+	/*
+	 * Space for producing a Content-Length: header including padding
+	 * A billion gigabytes is enough for anybody.
+	 */
+	l += strlen("Content-Length: XxxXxxXxxXxxXxxXxx") + sizeof(void *);
+
+	if (bo->exp.ttl < cache_param->shortlived ||
+	    pass == 1)
+		bo->storage_hint = TRANSIENT_STORAGE;
+
+	AZ(bo->stats);
+	bo->stats = &wrk->stats;
+	req->obj = STV_NewObject(bo, &req->objcore, bo->storage_hint, l,
+	    nhttp);
+	if (req->obj == NULL) {
+		/*
+		 * Try to salvage the transaction by allocating a
+		 * shortlived object on Transient storage.
+		 */
+		if (bo->exp.ttl > cache_param->shortlived)
+			bo->exp.ttl = cache_param->shortlived;
+		bo->exp.grace = 0.0;
+		bo->exp.keep = 0.0;
+		req->obj = STV_NewObject(bo, &req->objcore, TRANSIENT_STORAGE,
+		    l, nhttp);
+	}
+	bo->stats = NULL;
+	if (req->obj == NULL) {
+		AZ(HSH_Deref(&wrk->stats, req->objcore, NULL));
+		req->objcore = NULL;
+		VDI_CloseFd(&bo->vbc);
+		VBO_DerefBusyObj(wrk, &req->busyobj);
+		return (-1);
+	}
+	CHECK_OBJ_NOTNULL(req->obj, OBJECT_MAGIC);
+
+	bo->storage_hint = NULL;
+
+	AZ(bo->fetch_obj);
+	bo->fetch_obj = req->obj;
+
+	if (bo->do_gzip || (bo->is_gzip && !bo->do_gunzip))
+		req->obj->gziped = 1;
+
+	if (vary != NULL) {
+		req->obj->vary = (void *)WS_Copy(req->obj->http->ws,
+		    VSB_data(vary), varyl);
+		AN(req->obj->vary);
+		VRY_Validate(req->obj->vary);
+		VSB_delete(vary);
+	}
+
+	req->obj->vxid = bo->vsl->wid;
+	req->obj->response = req->err_code;
+	WS_Assert(req->obj->ws_o);
+
+	/* Filter into object */
+	hp = bo->beresp;
+	hp2 = req->obj->http;
+
+	hp2->logtag = HTTP_Obj;
+	http_FilterResp(hp, hp2, pass ? HTTPH_R_PASS : HTTPH_A_INS);
+	http_CopyHome(hp2);
+
+	if (http_GetHdr(hp, H_Last_Modified, &b))
+		req->obj->last_modified = VTIM_parse(b);
+	else
+		req->obj->last_modified = floor(bo->exp.entered);
+
+	assert(WRW_IsReleased(wrk));
+
+	/*
+	 * If we can deliver a 304 reply, we don't bother streaming.
+	 * Notice that vcl_deliver{} could still nuke the headers
+	 * that allow the 304, in which case we return 200 non-stream.
+	 */
+	if (req->obj->response == 200 &&
+	    req->http->conds &&
+	    RFC2616_Do_Cond(req))
+		bo->do_stream = 0;
+
+	/*
+	 * Ready to fetch the body
+	 */
+	bo->fetch_task.func = FetchBody;
+	bo->fetch_task.priv = bo;
+
+	assert(bo->refcount == 2);	/* one for each thread */
+
+	if (req->obj->objcore->objhead != NULL) {
+		EXP_Insert(req->obj);
+		AN(req->obj->objcore->ban);
+		AZ(req->obj->ws_o->overflow);
+		HSH_Unbusy(&wrk->stats, req->obj->objcore);
+	}
+
+	if (!bo->do_stream ||
+	    Pool_Task(wrk->pool, &bo->fetch_task, POOL_NO_QUEUE))
+		FetchBody(wrk, bo);
+
+	if (req->obj->objcore->objhead != NULL)
+		HSH_Ref(req->obj->objcore);
+
+	if (bo->state == BOS_FINISHED) {
+		VBO_DerefBusyObj(wrk, &req->busyobj);
+	} else if (bo->state == BOS_FAILED) {
+		/* handle early failures */
+		(void)HSH_Deref(&wrk->stats, NULL, &req->obj);
+		VBO_DerefBusyObj(wrk, &req->busyobj);
+		return (-1);
+	}
+
+	assert(WRW_IsReleased(wrk));
+	return (0);
+}
+
+
+/*--------------------------------------------------------------------
  * Debugging aids
  */
 
diff --git a/bin/varnishd/cache/cache_req_fsm.c b/bin/varnishd/cache/cache_req_fsm.c
index 07d0742..bb18117 100644
--- a/bin/varnishd/cache/cache_req_fsm.c
+++ b/bin/varnishd/cache/cache_req_fsm.c
@@ -481,239 +481,19 @@ DOT fetchbody:out -> prepresp [style=bold,color=blue]
 static enum req_fsm_nxt
 cnt_fetchbody(struct worker *wrk, struct req *req)
 {
-	struct http *hp, *hp2;
-	char *b;
-	uint16_t nhttp;
-	unsigned l;
-	struct vsb *vary = NULL;
-	int varyl = 0, pass;
-	struct busyobj *bo;
+	int i;
 
 	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
 	CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
-	CHECK_OBJ_NOTNULL(req->objcore, OBJCORE_MAGIC);
-	bo = req->busyobj;
-	CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
-
-	assert(wrk->handling == VCL_RET_DELIVER);
-
-	if (req->objcore->objhead == NULL) {
-		/* This is a pass from vcl_recv */
-		pass = 1;
-		/* VCL may have fiddled this, but that doesn't help */
-		bo->exp.ttl = -1.;
-	} else if (bo->do_pass) {
-		pass = 1;
-	} else {
-		/* regular object */
-		pass = 0;
-	}
-
-	/*
-	 * The VCL variables beresp.do_g[un]zip tells us how we want the
-	 * object processed before it is stored.
-	 *
-	 * The backend Content-Encoding header tells us what we are going
-	 * to receive, which we classify in the following three classes:
-	 *
-	 *	"Content-Encoding: gzip"	--> object is gzip'ed.
-	 *	no Content-Encoding		--> object is not gzip'ed.
-	 *	anything else			--> do nothing wrt gzip
-	 *
-	 */
-
-	/* We do nothing unless the param is set */
-	if (!cache_param->http_gzip_support)
-		bo->do_gzip = bo->do_gunzip = 0;
-
-	bo->is_gzip = http_HdrIs(bo->beresp, H_Content_Encoding, "gzip");
-
-	bo->is_gunzip = !http_GetHdr(bo->beresp, H_Content_Encoding, NULL);
-
-	/* It can't be both */
-	assert(bo->is_gzip == 0 || bo->is_gunzip == 0);
-
-	/* We won't gunzip unless it is gzip'ed */
-	if (bo->do_gunzip && !bo->is_gzip)
-		bo->do_gunzip = 0;
-
-	/* If we do gunzip, remove the C-E header */
-	if (bo->do_gunzip)
-		http_Unset(bo->beresp, H_Content_Encoding);
-
-	/* We wont gzip unless it is ungziped */
-	if (bo->do_gzip && !bo->is_gunzip)
-		bo->do_gzip = 0;
-
-	/* If we do gzip, add the C-E header */
-	if (bo->do_gzip)
-		http_SetHeader(bo->beresp, "Content-Encoding: gzip");
-
-	/* But we can't do both at the same time */
-	assert(bo->do_gzip == 0 || bo->do_gunzip == 0);
-
-	/* ESI takes precedence and handles gzip/gunzip itself */
-	if (bo->do_esi)
-		bo->vfp = &vfp_esi;
-	else if (bo->do_gunzip)
-		bo->vfp = &vfp_gunzip;
-	else if (bo->do_gzip)
-		bo->vfp = &vfp_gzip;
-	else if (bo->is_gzip)
-		bo->vfp = &vfp_testgzip;
-
-	if (bo->do_esi || req->esi_level > 0)
-		bo->do_stream = 0;
-	if (!req->wantbody)
-		bo->do_stream = 0;
-
-	/* No reason to try streaming a non-existing body */
-	if (bo->htc.body_status == BS_NONE)
-		bo->do_stream = 0;
-
-	l = http_EstimateWS(bo->beresp,
-	    pass ? HTTPH_R_PASS : HTTPH_A_INS, &nhttp);
-
-	/* Create Vary instructions */
-	if (req->objcore->objhead != NULL) {
-		varyl = VRY_Create(bo, &vary);
-		if (varyl > 0) {
-			AN(vary);
-			assert(varyl == VSB_len(vary));
-			l += varyl;
-		} else if (varyl < 0) {
-			/* Vary parse error */
-			AZ(vary);
-			req->err_code = 503;
-			req->req_step = R_STP_ERROR;
-			AZ(HSH_Deref(&wrk->stats, req->objcore, NULL));
-			req->objcore = NULL;
-			VDI_CloseFd(&bo->vbc);
-			VBO_DerefBusyObj(wrk, &req->busyobj);
-			return (REQ_FSM_MORE);
-		} else
-			/* No vary */
-			AZ(vary);
-	}
 
-	/*
-	 * Space for producing a Content-Length: header including padding
-	 * A billion gigabytes is enough for anybody.
-	 */
-	l += strlen("Content-Length: XxxXxxXxxXxxXxxXxx") + sizeof(void *);
-
-	if (bo->exp.ttl < cache_param->shortlived ||
-	    pass == 1)
-		bo->storage_hint = TRANSIENT_STORAGE;
-
-	AZ(bo->stats);
-	bo->stats = &wrk->stats;
-	req->obj = STV_NewObject(bo, &req->objcore, bo->storage_hint, l,
-	    nhttp);
-	if (req->obj == NULL) {
-		/*
-		 * Try to salvage the transaction by allocating a
-		 * shortlived object on Transient storage.
-		 */
-		if (bo->exp.ttl > cache_param->shortlived)
-			bo->exp.ttl = cache_param->shortlived;
-		bo->exp.grace = 0.0;
-		bo->exp.keep = 0.0;
-		req->obj = STV_NewObject(bo, &req->objcore, TRANSIENT_STORAGE,
-		    l, nhttp);
-	}
-	bo->stats = NULL;
-	if (req->obj == NULL) {
+	i = VBF_Fetch(wrk, req);
+	if (i < 0) {
 		req->err_code = 503;
 		req->req_step = R_STP_ERROR;
-		AZ(HSH_Deref(&wrk->stats, req->objcore, NULL));
-		req->objcore = NULL;
-		VDI_CloseFd(&bo->vbc);
-		VBO_DerefBusyObj(wrk, &req->busyobj);
-		return (REQ_FSM_MORE);
-	}
-	CHECK_OBJ_NOTNULL(req->obj, OBJECT_MAGIC);
-
-	bo->storage_hint = NULL;
-
-	AZ(bo->fetch_obj);
-	bo->fetch_obj = req->obj;
-
-	if (bo->do_gzip || (bo->is_gzip && !bo->do_gunzip))
-		req->obj->gziped = 1;
-
-	if (vary != NULL) {
-		req->obj->vary = (void *)WS_Copy(req->obj->http->ws,
-		    VSB_data(vary), varyl);
-		AN(req->obj->vary);
-		VRY_Validate(req->obj->vary);
-		VSB_delete(vary);
-	}
-
-	req->obj->vxid = bo->vsl->wid;
-	req->obj->response = req->err_code;
-	WS_Assert(req->obj->ws_o);
-
-	/* Filter into object */
-	hp = bo->beresp;
-	hp2 = req->obj->http;
-
-	hp2->logtag = HTTP_Obj;
-	http_FilterResp(hp, hp2, pass ? HTTPH_R_PASS : HTTPH_A_INS);
-	http_CopyHome(hp2);
-
-	if (http_GetHdr(hp, H_Last_Modified, &b))
-		req->obj->last_modified = VTIM_parse(b);
-	else
-		req->obj->last_modified = floor(bo->exp.entered);
-
-	assert(WRW_IsReleased(wrk));
-
-	/*
-	 * If we can deliver a 304 reply, we don't bother streaming.
-	 * Notice that vcl_deliver{} could still nuke the headers
-	 * that allow the 304, in which case we return 200 non-stream.
-	 */
-	if (req->obj->response == 200 &&
-	    req->http->conds &&
-	    RFC2616_Do_Cond(req))
-		bo->do_stream = 0;
-
-	/*
-	 * Ready to fetch the body
-	 */
-	bo->fetch_task.func = FetchBody;
-	bo->fetch_task.priv = bo;
-
-	assert(bo->refcount == 2);	/* one for each thread */
-
-	if (req->obj->objcore->objhead != NULL) {
-		EXP_Insert(req->obj);
-		AN(req->obj->objcore->ban);
-		AZ(req->obj->ws_o->overflow);
-		HSH_Unbusy(&wrk->stats, req->obj->objcore);
-	}
-
-	if (!bo->do_stream ||
-	    Pool_Task(wrk->pool, &bo->fetch_task, POOL_NO_QUEUE))
-		FetchBody(wrk, bo);
-
-	if (req->obj->objcore->objhead != NULL)
-		HSH_Ref(req->obj->objcore);
-
-	if (bo->state == BOS_FINISHED) {
-		VBO_DerefBusyObj(wrk, &req->busyobj);
-	} else if (bo->state == BOS_FAILED) {
-		/* handle early failures */
-		(void)HSH_Deref(&wrk->stats, NULL, &req->obj);
-		VBO_DerefBusyObj(wrk, &req->busyobj);
-		req->err_code = 503;
-		req->req_step = R_STP_ERROR;
-		return (REQ_FSM_MORE);
+	} else {
+		assert(WRW_IsReleased(wrk));
+		req->req_step = R_STP_PREPRESP;
 	}
-
-	assert(WRW_IsReleased(wrk));
-	req->req_step = R_STP_PREPRESP;
 	return (REQ_FSM_MORE);
 }
 



More information about the varnish-commit mailing list