[master] 1452756 Introduce a vfp_ctx structure to hold the context for fetch-filters.

Poul-Henning Kamp phk at FreeBSD.org
Tue Jul 15 10:31:43 CEST 2014


commit 1452756537bf60ee601d1de2e6aaadece005463a
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Tue Jul 15 08:31:20 2014 +0000

    Introduce a vfp_ctx structure to hold the context for fetch-filters.

diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h
index fe060dd..5215775 100644
--- a/bin/varnishd/cache/cache.h
+++ b/bin/varnishd/cache/cache.h
@@ -452,6 +452,15 @@ struct vfp_entry {
 
 VTAILQ_HEAD(vfp_entry_s, vfp_entry);
 
+struct vfp_ctx {
+	unsigned		magic;
+#define VFP_CTX_MAGIC		0x61d9d3e5
+	struct busyobj		*bo;
+
+	struct vfp_entry_s	vfp;
+	struct vfp_entry	*vfp_nxt;
+};
+
 struct busyobj {
 	unsigned		magic;
 #define BUSYOBJ_MAGIC		0x23b95567
@@ -469,8 +478,7 @@ struct busyobj {
 
 	uint8_t			*vary;
 
-	struct vfp_entry_s	vfp;
-	struct vfp_entry	*vfp_nxt;
+	struct vfp_ctx		vfc;
 
 	int			failed;
 	enum busyobj_state_e	state;
@@ -880,11 +888,8 @@ void VBF_Fetch(struct worker *wrk, struct req *req,
 
 /* cache_fetch_proc.c */
 struct storage *VFP_GetStorage(struct busyobj *, ssize_t sz);
-enum vfp_status VFP_Error(struct busyobj *, const char *fmt, ...)
-    __printflike(2, 3);
 void VFP_Init(void);
 void VFP_Fetch_Body(struct busyobj *bo);
-enum vfp_status VFP_Suck(struct busyobj *, void *p, ssize_t *lp);
 
 /* cache_gzip.c */
 struct vgz;
diff --git a/bin/varnishd/cache/cache_busyobj.c b/bin/varnishd/cache/cache_busyobj.c
index 4ebfdc4..f4b4296 100644
--- a/bin/varnishd/cache/cache_busyobj.c
+++ b/bin/varnishd/cache/cache_busyobj.c
@@ -147,7 +147,6 @@ VBO_GetBusyObj(struct worker *wrk, const struct req *req)
 	bo->director = req->director_hint;
 	bo->vcl = req->vcl;
 	VCL_Ref(bo->vcl);
-	VTAILQ_INIT(&bo->vfp);
 
 	bo->t_first = bo->t_prev = NAN;
 	bo->content_length = -1;
diff --git a/bin/varnishd/cache/cache_esi_fetch.c b/bin/varnishd/cache/cache_esi_fetch.c
index 3601cf8..3c367be 100644
--- a/bin/varnishd/cache/cache_esi_fetch.c
+++ b/bin/varnishd/cache/cache_esi_fetch.c
@@ -101,28 +101,30 @@ vfp_vep_callback(struct busyobj *bo, void *priv, ssize_t l, enum vgz_flag flg)
 }
 
 static enum vfp_status
-vfp_esi_end(struct busyobj *bo, struct vef_priv *vef, enum vfp_status retval)
+vfp_esi_end(const struct vfp_ctx *vc, struct vef_priv *vef,
+    enum vfp_status retval)
 {
 	struct vsb *vsb;
 	ssize_t l;
 
-	CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
+	CHECK_OBJ_NOTNULL(vc, VFP_CTX_MAGIC);
+	CHECK_OBJ_NOTNULL(vc->bo, BUSYOBJ_MAGIC);
 	CHECK_OBJ_NOTNULL(vef, VEF_MAGIC);
 
-	vsb = VEP_Finish(vef->vep, bo);
+	vsb = VEP_Finish(vef->vep, vc->bo);
 
 	if (vsb != NULL) {
 		if (retval == VFP_END) {
 			l = VSB_len(vsb);
 			assert(l > 0);
 			/* XXX: This is a huge waste of storage... */
-			bo->fetch_obj->esidata = STV_alloc(bo, l);
-			if (bo->fetch_obj->esidata != NULL) {
-				memcpy(bo->fetch_obj->esidata->ptr,
+			vc->bo->fetch_obj->esidata = STV_alloc(vc->bo, l);
+			if (vc->bo->fetch_obj->esidata != NULL) {
+				memcpy(vc->bo->fetch_obj->esidata->ptr,
 				    VSB_data(vsb), l);
-				bo->fetch_obj->esidata->len = l;
+				vc->bo->fetch_obj->esidata->len = l;
 			} else {
-				retval = VFP_Error(bo,
+				retval = VFP_Error(vc,
 				    "Could not allocate storage for esidata");
 			}
 		}
@@ -130,9 +132,9 @@ vfp_esi_end(struct busyobj *bo, struct vef_priv *vef, enum vfp_status retval)
 	}
 
 	if (vef->vgz != NULL) {
-		VGZ_UpdateObj(vef->vgz, bo->fetch_obj);
+		VGZ_UpdateObj(vef->vgz, vc->bo->fetch_obj);
 		if (VGZ_Destroy(&vef->vgz) != VGZ_END)
-			retval = VFP_Error(bo,
+			retval = VFP_Error(vc,
 			    "ESI+Gzip Failed at the very end");
 	}
 	if (vef->ibuf != NULL)
@@ -142,42 +144,44 @@ vfp_esi_end(struct busyobj *bo, struct vef_priv *vef, enum vfp_status retval)
 }
 
 static enum vfp_status __match_proto__(vfp_init_f)
-vfp_esi_gzip_init(struct busyobj *bo, struct vfp_entry *vfe)
+vfp_esi_gzip_init(struct vfp_ctx *vc, struct vfp_entry *vfe)
 {
 	struct vef_priv *vef;
 
-	CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
+	CHECK_OBJ_NOTNULL(vc, VFP_CTX_MAGIC);
+	CHECK_OBJ_NOTNULL(vc->bo, BUSYOBJ_MAGIC);
 	CHECK_OBJ_NOTNULL(vfe, VFP_ENTRY_MAGIC);
 	ALLOC_OBJ(vef, VEF_MAGIC);
 	if (vef == NULL)
 		return (VFP_ERROR);
-	vef->vgz = VGZ_NewGzip(bo->vsl, "G F E");
-	vef->vep = VEP_Init(bo, vfp_vep_callback, vef);
+	vef->vgz = VGZ_NewGzip(vc->bo->vsl, "G F E");
+	vef->vep = VEP_Init(vc->bo, vfp_vep_callback, vef);
 	vef->ibuf_sz = cache_param->gzip_buffer;
 	vef->ibuf = calloc(1L, vef->ibuf_sz);
 	if (vef->ibuf == NULL)
-		return (vfp_esi_end(bo, vef, VFP_ERROR));
+		return (vfp_esi_end(vc, vef, VFP_ERROR));
 	vef->ibuf_i = vef->ibuf;
 	vef->ibuf_o = vef->ibuf;
 	vfe->priv1 = vef;
 
-	RFC2616_Weaken_Etag(bo->beresp);
-	http_Unset(bo->beresp, H_Content_Length);
-	http_Unset(bo->beresp, H_Content_Encoding);
-	http_SetHeader(bo->beresp, "Content-Encoding: gzip");
+	RFC2616_Weaken_Etag(vc->bo->beresp);
+	http_Unset(vc->bo->beresp, H_Content_Length);
+	http_Unset(vc->bo->beresp, H_Content_Encoding);
+	http_SetHeader(vc->bo->beresp, "Content-Encoding: gzip");
 
 	return (VFP_OK);
 }
 
 static enum vfp_status __match_proto__(vfp_pull_f)
-vfp_esi_gzip_pull(struct busyobj *bo, struct vfp_entry *vfe, void *p,
+vfp_esi_gzip_pull(struct vfp_ctx *vc, struct vfp_entry *vfe, void *p,
    ssize_t *lp)
 {
 	enum vfp_status vp;
 	ssize_t d, l;
 	struct vef_priv *vef;
 
-	CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
+	CHECK_OBJ_NOTNULL(vc, VFP_CTX_MAGIC);
+	CHECK_OBJ_NOTNULL(vc->bo, BUSYOBJ_MAGIC);
 	CHECK_OBJ_NOTNULL(vfe, VFP_ENTRY_MAGIC);
 	CAST_OBJ_NOTNULL(vef, vfe->priv1, VEF_MAGIC);
 	AN(p);
@@ -189,10 +193,10 @@ vfp_esi_gzip_pull(struct busyobj *bo, struct vfp_entry *vfe, void *p,
 		if (d < l)
 			l = d;
 	}
-	vp = VFP_Suck(bo, vef->ibuf_i, &l);
+	vp = VFP_Suck(vc, vef->ibuf_i, &l);
 
 	if (l > 0) {
-		VEP_Parse(vef->vep, bo, vef->ibuf_i, l);
+		VEP_Parse(vef->vep, vc->bo, vef->ibuf_i, l);
 		vef->ibuf_i += l;
 		assert(vef->ibuf_o >= vef->ibuf && vef->ibuf_o <= vef->ibuf_i);
 		if (vef->error) {
@@ -206,33 +210,36 @@ vfp_esi_gzip_pull(struct busyobj *bo, struct vfp_entry *vfe, void *p,
 		vef->ibuf_i = vef->ibuf + l;
 	}
 	if (vp == VFP_END) {
-		vp = vfp_esi_end(bo, vef, vp);
+		vp = vfp_esi_end(vc, vef, vp);
 		vfe->priv1 = NULL;
 	}
 	return (vp);
 }
 
 static enum vfp_status __match_proto__(vfp_init_f)
-vfp_esi_init(struct busyobj *bo, struct vfp_entry *vfe)
+vfp_esi_init(struct vfp_ctx *vc, struct vfp_entry *vfe)
 {
 	struct vef_priv *vef;
 
+	CHECK_OBJ_NOTNULL(vc, VFP_CTX_MAGIC);
+	CHECK_OBJ_NOTNULL(vc->bo, BUSYOBJ_MAGIC);
 	ALLOC_OBJ(vef, VEF_MAGIC);
 	if (vef == NULL)
 		return (VFP_ERROR);
-	vef->vep = VEP_Init(bo, NULL, NULL);
+	vef->vep = VEP_Init(vc->bo, NULL, NULL);
 	vfe->priv1 = vef;
 	return (VFP_OK);
 }
 
 static enum vfp_status __match_proto__(vfp_pull_f)
-vfp_esi_pull(struct busyobj *bo, struct vfp_entry *vfe, void *p, ssize_t *lp)
+vfp_esi_pull(struct vfp_ctx *vc, struct vfp_entry *vfe, void *p, ssize_t *lp)
 {
 	enum vfp_status vp;
 	ssize_t d;
 	struct vef_priv *vef;
 
-	CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
+	CHECK_OBJ_NOTNULL(vc, VFP_CTX_MAGIC);
+	CHECK_OBJ_NOTNULL(vc->bo, BUSYOBJ_MAGIC);
 	CHECK_OBJ_NOTNULL(vfe, VFP_ENTRY_MAGIC);
 	CAST_OBJ_NOTNULL(vef, vfe->priv1, VEF_MAGIC);
 	AN(p);
@@ -242,24 +249,24 @@ vfp_esi_pull(struct busyobj *bo, struct vfp_entry *vfe, void *p, ssize_t *lp)
 		if (d < *lp)
 			*lp = d;
 	}
-	vp = VFP_Suck(bo, p, lp);
+	vp = VFP_Suck(vc, p, lp);
 	if (vp != VFP_ERROR && *lp > 0)
-		VEP_Parse(vef->vep, bo, p, *lp);
+		VEP_Parse(vef->vep, vc->bo, p, *lp);
 	if (vp == VFP_END) {
-		vp = vfp_esi_end(bo, vef, vp);
+		vp = vfp_esi_end(vc, vef, vp);
 		vfe->priv1 = NULL;
 	}
 	return (vp);
 }
 
 static void __match_proto__(vfp_fini_f)
-vfp_esi_fini(struct busyobj *bo, struct vfp_entry *vfe)
+vfp_esi_fini(struct vfp_ctx *vc, struct vfp_entry *vfe)
 {
-	CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
+	CHECK_OBJ_NOTNULL(vc, VFP_CTX_MAGIC);
 	CHECK_OBJ_NOTNULL(vfe, VFP_ENTRY_MAGIC);
 
 	if (vfe->priv1 != NULL)
-		(void)vfp_esi_end(bo, vfe->priv1, VFP_ERROR);
+		(void)vfp_esi_end(vc, vfe->priv1, VFP_ERROR);
 	vfe->priv1 = NULL;
 }
 
diff --git a/bin/varnishd/cache/cache_fetch.c b/bin/varnishd/cache/cache_fetch.c
index 1942765..d3153a9 100644
--- a/bin/varnishd/cache/cache_fetch.c
+++ b/bin/varnishd/cache/cache_fetch.c
@@ -367,6 +367,10 @@ vbf_stp_startfetch(struct worker *wrk, struct busyobj *bo)
 	} else
 		do_ims = 0;
 
+	bo->vfc.magic = VFP_CTX_MAGIC;
+	VTAILQ_INIT(&bo->vfc.vfp);
+	bo->vfc.bo = bo;
+
 	VCL_backend_response_method(bo->vcl, wrk, NULL, bo, bo->beresp->ws);
 
 	if (wrk->handling == VCL_RET_ABANDON)
@@ -447,18 +451,18 @@ vbf_stp_fetch(struct worker *wrk, struct busyobj *bo)
 	assert(bo->do_gzip == 0 || bo->do_gunzip == 0);
 
 	if (bo->do_gunzip || (bo->is_gzip && bo->do_esi))
-		(void)VFP_Push(bo, &vfp_gunzip, 1);
+		(void)VFP_Push(&bo->vfc, &vfp_gunzip, 1);
 
 	if (bo->do_esi && bo->do_gzip) {
-		(void)VFP_Push(bo, &vfp_esi_gzip, 1);
+		(void)VFP_Push(&bo->vfc, &vfp_esi_gzip, 1);
 	} else if (bo->do_esi && bo->is_gzip && !bo->do_gunzip) {
-		(void)VFP_Push(bo, &vfp_esi_gzip, 1);
+		(void)VFP_Push(&bo->vfc, &vfp_esi_gzip, 1);
 	} else if (bo->do_esi) {
-		(void)VFP_Push(bo, &vfp_esi, 1);
+		(void)VFP_Push(&bo->vfc, &vfp_esi, 1);
 	} else if (bo->do_gzip) {
-		(void)VFP_Push(bo, &vfp_gzip, 1);
+		(void)VFP_Push(&bo->vfc, &vfp_gzip, 1);
 	} else if (bo->is_gzip && !bo->do_gunzip) {
-		(void)VFP_Push(bo, &vfp_testgunzip, 1);
+		(void)VFP_Push(&bo->vfc, &vfp_testgunzip, 1);
 	}
 
 	if (bo->fetch_objcore->flags & OC_F_PRIVATE)
@@ -468,14 +472,14 @@ vbf_stp_fetch(struct worker *wrk, struct busyobj *bo)
 	if (bo->htc.body_status == BS_NONE)
 		bo->do_stream = 0;
 
-	if (VFP_Open(bo)) {
-		(void)VFP_Error(bo, "Fetch Pipeline failed to open");
+	if (VFP_Open(&bo->vfc)) {
+		(void)VFP_Error(&bo->vfc, "Fetch Pipeline failed to open");
 		bo->doclose = SC_RX_BODY;
 		return (F_STP_ERROR);
 	}
 
 	if (vbf_beresp2obj(bo)) {
-		(void)VFP_Error(bo, "Could not get storage");
+		(void)VFP_Error(&bo->vfc, "Could not get storage");
 		bo->doclose = SC_RX_BODY;
 		return (F_STP_ERROR);
 	}
diff --git a/bin/varnishd/cache/cache_fetch_proc.c b/bin/varnishd/cache/cache_fetch_proc.c
index 67039f0..10525b2 100644
--- a/bin/varnishd/cache/cache_fetch_proc.c
+++ b/bin/varnishd/cache/cache_fetch_proc.c
@@ -53,17 +53,18 @@ static unsigned fetchfrag;
  */
 
 enum vfp_status
-VFP_Error(struct busyobj *bo, const char *fmt, ...)
+VFP_Error(const struct vfp_ctx *vc, const char *fmt, ...)
 {
 	va_list ap;
 
-	CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
-	assert(bo->state >= BOS_REQ_DONE);
-	if (!bo->failed) {
+	CHECK_OBJ_NOTNULL(vc, VFP_CTX_MAGIC);
+	CHECK_OBJ_NOTNULL(vc->bo, BUSYOBJ_MAGIC);
+	assert(vc->bo->state >= BOS_REQ_DONE);
+	if (!vc->bo->failed) {
 		va_start(ap, fmt);
-		VSLbv(bo->vsl, SLT_FetchError, fmt, ap);
+		VSLbv(vc->bo->vsl, SLT_FetchError, fmt, ap);
 		va_end(ap);
-		bo->failed = 1;
+		vc->bo->failed = 1;
 	}
 	return (VFP_ERROR);
 }
@@ -95,7 +96,7 @@ VFP_GetStorage(struct busyobj *bo, ssize_t sz)
 		l = cache_param->fetch_chunksize;
 	st = STV_alloc(bo, l);
 	if (st == NULL) {
-		(void)VFP_Error(bo, "Could not get storage");
+		(void)VFP_Error(&bo->vfc, "Could not get storage");
 	} else {
 		AZ(st->len);
 		Lck_Lock(&bo->mtx);
@@ -109,29 +110,29 @@ VFP_GetStorage(struct busyobj *bo, ssize_t sz)
  */
 
 static void
-vfp_suck_fini(struct busyobj *bo)
+vfp_suck_fini(struct vfp_ctx *vc)
 {
 	struct vfp_entry *vfe;
 
-	VTAILQ_FOREACH(vfe, &bo->vfp, list)
+	VTAILQ_FOREACH(vfe, &vc->vfp, list)
 		if(vfe->vfp->fini != NULL)
-			vfe->vfp->fini(bo, vfe);
+			vfe->vfp->fini(vc, vfe);
 }
 
 int
-VFP_Open(struct busyobj *bo)
+VFP_Open(struct vfp_ctx *vc)
 {
 	struct vfp_entry *vfe;
 
-	VTAILQ_FOREACH_REVERSE(vfe, &bo->vfp, vfp_entry_s, list) {
+	CHECK_OBJ_NOTNULL(vc, VFP_CTX_MAGIC);
+	VTAILQ_FOREACH_REVERSE(vfe, &vc->vfp, vfp_entry_s, list) {
 		if (vfe->vfp->init == NULL)
 			continue;
-		vfe->closed = vfe->vfp->init(bo, vfe);
+		vfe->closed = vfe->vfp->init(vc, vfe);
 		if (vfe->closed != VFP_OK && vfe->closed != VFP_NULL) {
-			(void)VFP_Error(bo,
-			    "Fetch filter %s failed to open",
+			(void)VFP_Error(vc, "Fetch filter %s failed to open",
 			    vfe->vfp->name);
-			vfp_suck_fini(bo);
+			vfp_suck_fini(vc);
 			return (-1);
 		}
 	}
@@ -145,33 +146,34 @@ VFP_Open(struct busyobj *bo)
  */
 
 enum vfp_status
-VFP_Suck(struct busyobj *bo, void *p, ssize_t *lp)
+VFP_Suck(struct vfp_ctx *vc, void *p, ssize_t *lp)
 {
 	enum vfp_status vp;
 	struct vfp_entry *vfe;
 
-	CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
+	CHECK_OBJ_NOTNULL(vc, VFP_CTX_MAGIC);
+	CHECK_OBJ_NOTNULL(vc->bo, BUSYOBJ_MAGIC);
 	AN(p);
 	AN(lp);
-	vfe = bo->vfp_nxt;
+	vfe = vc->vfp_nxt;
 	CHECK_OBJ_NOTNULL(vfe, VFP_ENTRY_MAGIC);
-	bo->vfp_nxt = VTAILQ_NEXT(vfe, list);
+	vc->vfp_nxt = VTAILQ_NEXT(vfe, list);
 
 	if (vfe->closed == VFP_NULL) {
-		vp = VFP_Suck(bo, p, lp);
+		vp = VFP_Suck(vc, p, lp);
 	} else if (vfe->closed == VFP_OK) {
-		vp = vfe->vfp->pull(bo, vfe, p, lp);
+		vp = vfe->vfp->pull(vc, vfe, p, lp);
 		if (vp == VFP_END || vp == VFP_ERROR) {
 			vfe->closed = vp;
 		} else if (vp != VFP_OK)
-			(void)VFP_Error(bo, "Fetch filter %s returned %d",
+			(void)VFP_Error(vc, "Fetch filter %s returned %d",
 			    vfe->vfp->name, vp);
 	} else {
 		/* Already closed filter */
 		*lp = 0;
 		vp = vfe->closed;
 	}
-	bo->vfp_nxt = vfe;
+	vc->vfp_nxt = vfe;
 	return (vp);
 }
 
@@ -188,7 +190,7 @@ VFP_Fetch_Body(struct busyobj *bo)
 
 	CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
 
-	AN(bo->vfp_nxt);
+	AN(bo->vfc.vfp_nxt);
 
 	est = bo->content_length;
 	if (est < 0)
@@ -215,7 +217,7 @@ VFP_Fetch_Body(struct busyobj *bo)
 		}
 		if (st == NULL) {
 			bo->doclose = SC_RX_BODY;
-			(void)VFP_Error(bo, "Out of storage");
+			(void)VFP_Error(&bo->vfc, "Out of storage");
 			break;
 		}
 
@@ -223,7 +225,7 @@ VFP_Fetch_Body(struct busyobj *bo)
 		assert(st == VTAILQ_LAST(&bo->fetch_obj->store, storagehead));
 		l = st->space - st->len;
 		AZ(bo->failed);
-		vfps = VFP_Suck(bo, st->ptr + st->len, &l);
+		vfps = VFP_Suck(&bo->vfc, st->ptr + st->len, &l);
 		if (l > 0 && vfps != VFP_ERROR) {
 			AZ(VTAILQ_EMPTY(&bo->fetch_obj->store));
 			VBO_extend(bo, l);
@@ -234,33 +236,33 @@ VFP_Fetch_Body(struct busyobj *bo)
 
 	if (vfps == VFP_ERROR) {
 		AN(bo->failed);
-		(void)VFP_Error(bo, "Fetch Pipeline failed to process");
+		(void)VFP_Error(&bo->vfc, "Fetch Pipeline failed to process");
 		bo->doclose = SC_RX_BODY;
 	}
 
-	vfp_suck_fini(bo);
+	vfp_suck_fini(&bo->vfc);
 
 	if (!bo->do_stream)
 		ObjTrimStore(bo->fetch_objcore, bo->stats);
 }
 
 struct vfp_entry *
-VFP_Push(struct busyobj *bo, const struct vfp *vfp, int top)
+VFP_Push(struct vfp_ctx *vc, const struct vfp *vfp, int top)
 {
 	struct vfp_entry *vfe;
 
-	CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
-	vfe = (void*)WS_Alloc(bo->ws, sizeof *vfe);
+	CHECK_OBJ_NOTNULL(vc, VFP_CTX_MAGIC);
+	vfe = (void*)WS_Alloc(vc->bo->ws, sizeof *vfe);
 	AN(vfe);
 	vfe->magic = VFP_ENTRY_MAGIC;
 	vfe->vfp = vfp;
 	vfe->closed = VFP_OK;
 	if (top)
-		VTAILQ_INSERT_HEAD(&bo->vfp, vfe, list);
+		VTAILQ_INSERT_HEAD(&vc->vfp, vfe, list);
 	else
-		VTAILQ_INSERT_TAIL(&bo->vfp, vfe, list);
-	if (VTAILQ_FIRST(&bo->vfp) == vfe)
-		bo->vfp_nxt = vfe;
+		VTAILQ_INSERT_TAIL(&vc->vfp, vfe, list);
+	if (VTAILQ_FIRST(&vc->vfp) == vfe)
+		vc->vfp_nxt = vfe;
 	return (vfe);
 }
 
diff --git a/bin/varnishd/cache/cache_filter.h b/bin/varnishd/cache/cache_filter.h
index ab0c351..9ef68ea 100644
--- a/bin/varnishd/cache/cache_filter.h
+++ b/bin/varnishd/cache/cache_filter.h
@@ -30,6 +30,7 @@
 struct busyobj;
 struct req;
 struct vfp_entry;
+struct vfp_ctx;
 
 /* Fetch processors --------------------------------------------------*/
 
@@ -40,10 +41,10 @@ enum vfp_status {
 	VFP_NULL = 2,
 };
 
-typedef enum vfp_status vfp_init_f(struct busyobj *, struct vfp_entry *);
+typedef enum vfp_status vfp_init_f(struct vfp_ctx *, struct vfp_entry *);
 typedef enum vfp_status
-    vfp_pull_f(struct busyobj *, struct vfp_entry *, void *ptr, ssize_t *len);
-typedef void vfp_fini_f(struct busyobj *, struct vfp_entry *);
+    vfp_pull_f(struct vfp_ctx *, struct vfp_entry *, void *ptr, ssize_t *len);
+typedef void vfp_fini_f(struct vfp_ctx *, struct vfp_entry *);
 
 struct vfp {
 	const char	*name;
@@ -60,9 +61,11 @@ extern const struct vfp vfp_testgunzip;
 extern const struct vfp vfp_esi;
 extern const struct vfp vfp_esi_gzip;
 
-struct vfp_entry *VFP_Push(struct busyobj *bo, const struct vfp *vfp, int top);
-int VFP_Open(struct busyobj *bo);
-
+struct vfp_entry *VFP_Push(struct vfp_ctx *, const struct vfp *, int top);
+int VFP_Open(struct vfp_ctx *bo);
+enum vfp_status VFP_Suck(struct vfp_ctx *, void *p, ssize_t *lp);
+enum vfp_status VFP_Error(const struct vfp_ctx *, const char *fmt, ...)
+    __printflike(2, 3);
 
 /* Deliver processors ------------------------------------------------*/
 
diff --git a/bin/varnishd/cache/cache_gzip.c b/bin/varnishd/cache/cache_gzip.c
index e684089..48da134 100644
--- a/bin/varnishd/cache/cache_gzip.c
+++ b/bin/varnishd/cache/cache_gzip.c
@@ -451,26 +451,27 @@ VGZ_Destroy(struct vgz **vgp)
 #define VFP_TESTGUNZIP	2
 
 static enum vfp_status __match_proto__(vfp_init_f)
-vfp_gzip_init(struct busyobj *bo, struct vfp_entry *vfe)
+vfp_gzip_init(struct vfp_ctx *vc, struct vfp_entry *vfe)
 {
 	struct vgz *vg;
 
-        CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
+        CHECK_OBJ_NOTNULL(vc, VFP_CTX_MAGIC);
+        CHECK_OBJ_NOTNULL(vc->bo, BUSYOBJ_MAGIC);
 	CHECK_OBJ_NOTNULL(vfe, VFP_ENTRY_MAGIC);
 
-	if (bo->content_length == 0) {
-		http_Unset(bo->beresp, H_Content_Encoding);
+	if (vc->bo->content_length == 0) {
+		http_Unset(vc->bo->beresp, H_Content_Encoding);
 		return (VFP_NULL);
 	}
 
 	if (vfe->vfp->priv2 == VFP_GZIP) {
-		if (http_GetHdr(bo->beresp, H_Content_Encoding, NULL))
+		if (http_GetHdr(vc->bo->beresp, H_Content_Encoding, NULL))
 			return (VFP_NULL);
-		vg = VGZ_NewGzip(bo->vsl, vfe->vfp->priv1);
+		vg = VGZ_NewGzip(vc->bo->vsl, vfe->vfp->priv1);
 	} else {
-		if (!http_HdrIs(bo->beresp, H_Content_Encoding, "gzip"))
+		if (!http_HdrIs(vc->bo->beresp, H_Content_Encoding, "gzip"))
 			return (VFP_NULL);
-		vg = VGZ_NewUngzip(bo->vsl, vfe->vfp->priv1);
+		vg = VGZ_NewUngzip(vc->bo->vsl, vfe->vfp->priv1);
 	}
 	if (vg == NULL)
 		return (VFP_ERROR);
@@ -481,13 +482,13 @@ vfp_gzip_init(struct busyobj *bo, struct vfp_entry *vfe)
 	AZ(vg->m_len);
 
 	if (vfe->vfp->priv2 == VFP_GUNZIP || vfe->vfp->priv2 == VFP_GZIP) {
-		http_Unset(bo->beresp, H_Content_Encoding);
-		http_Unset(bo->beresp, H_Content_Length);
-		RFC2616_Weaken_Etag(bo->beresp);
+		http_Unset(vc->bo->beresp, H_Content_Encoding);
+		http_Unset(vc->bo->beresp, H_Content_Length);
+		RFC2616_Weaken_Etag(vc->bo->beresp);
 	}
 
 	if (vfe->vfp->priv2 == VFP_GZIP)
-		http_SetHeader(bo->beresp, "Content-Encoding: gzip");
+		http_SetHeader(vc->bo->beresp, "Content-Encoding: gzip");
 
 	return (VFP_OK);
 }
@@ -499,7 +500,7 @@ vfp_gzip_init(struct busyobj *bo, struct vfp_entry *vfe)
  */
 
 static enum vfp_status __match_proto__(vfp_pull_f)
-vfp_gunzip_pull(struct busyobj *bo, struct vfp_entry *vfe, void *p,
+vfp_gunzip_pull(struct vfp_ctx *vc, struct vfp_entry *vfe, void *p,
     ssize_t *lp)
 {
         ssize_t l;
@@ -509,7 +510,7 @@ vfp_gunzip_pull(struct busyobj *bo, struct vfp_entry *vfe, void *p,
 	size_t dl;
 	enum vfp_status vp = VFP_OK;
 
-        CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
+        CHECK_OBJ_NOTNULL(vc, VFP_CTX_MAGIC);
 	CHECK_OBJ_NOTNULL(vfe, VFP_ENTRY_MAGIC);
 	CAST_OBJ_NOTNULL(vg, vfe->priv1, VGZ_MAGIC);
         AN(p);
@@ -520,7 +521,7 @@ vfp_gunzip_pull(struct busyobj *bo, struct vfp_entry *vfe, void *p,
 	do {
 		if (VGZ_IbufEmpty(vg)) {
 			l = vg->m_sz;
-			vp = VFP_Suck(bo, vg->m_buf, &l);
+			vp = VFP_Suck(vc, vg->m_buf, &l);
 			if (vp == VFP_ERROR)
 				return (vp);
 			VGZ_Ibuf(vg, vg->m_buf, l);
@@ -528,9 +529,9 @@ vfp_gunzip_pull(struct busyobj *bo, struct vfp_entry *vfe, void *p,
 		if (!VGZ_IbufEmpty(vg) || vp == VFP_END) {
 			vr = VGZ_Gunzip(vg, &dp, &dl);
 			if (vr == VGZ_END && !VGZ_IbufEmpty(vg))
-				return(VFP_Error(bo, "Junk after gzip data"));
+				return(VFP_Error(vc, "Junk after gzip data"));
 			if (vr < VGZ_OK)
-				return (VFP_Error(bo,
+				return (VFP_Error(vc,
 				    "Invalid Gzip data: %s", vg->vz.msg));
 			if (dl > 0) {
 				*lp = dl;
@@ -541,7 +542,7 @@ vfp_gunzip_pull(struct busyobj *bo, struct vfp_entry *vfe, void *p,
 		AN(VGZ_IbufEmpty(vg));
 	} while (vp == VFP_OK);
 	if (vr != VGZ_END)
-		return(VFP_Error(bo, "Gunzip error at the very end"));
+		return(VFP_Error(vc, "Gunzip error at the very end"));
 	return (vp);
 }
 
@@ -553,7 +554,7 @@ vfp_gunzip_pull(struct busyobj *bo, struct vfp_entry *vfe, void *p,
  */
 
 static enum vfp_status __match_proto__(vfp_pull_f)
-vfp_gzip_pull(struct busyobj *bo, struct vfp_entry *vfe, void *p,
+vfp_gzip_pull(struct vfp_ctx *vc, struct vfp_entry *vfe, void *p,
     ssize_t *lp)
 {
         ssize_t l;
@@ -563,7 +564,8 @@ vfp_gzip_pull(struct busyobj *bo, struct vfp_entry *vfe, void *p,
 	size_t dl;
 	enum vfp_status vp = VFP_ERROR;
 
-        CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
+        CHECK_OBJ_NOTNULL(vc, VFP_CTX_MAGIC);
+        CHECK_OBJ_NOTNULL(vc->bo, BUSYOBJ_MAGIC);
 	CHECK_OBJ_NOTNULL(vfe, VFP_ENTRY_MAGIC);
 	CAST_OBJ_NOTNULL(vg, vfe->priv1, VGZ_MAGIC);
         AN(p);
@@ -574,7 +576,7 @@ vfp_gzip_pull(struct busyobj *bo, struct vfp_entry *vfe, void *p,
 	do {
 		if (VGZ_IbufEmpty(vg)) {
 			l = vg->m_sz;
-			vp = VFP_Suck(bo, vg->m_buf, &l);
+			vp = VFP_Suck(vc, vg->m_buf, &l);
 			if (vp == VFP_ERROR)
 				break;
 			if (vp == VFP_END)
@@ -584,7 +586,7 @@ vfp_gzip_pull(struct busyobj *bo, struct vfp_entry *vfe, void *p,
 		if (!VGZ_IbufEmpty(vg) || vg->flag == VGZ_FINISH) {
 			vr = VGZ_Gzip(vg, &dp, &dl, vg->flag);
 			if (vr < VGZ_OK)
-				return (VFP_Error(bo, "Gzip failed"));
+				return (VFP_Error(vc, "Gzip failed"));
 			if (dl > 0) {
 				*lp = dl;
 				assert(dp == p);
@@ -595,8 +597,8 @@ vfp_gzip_pull(struct busyobj *bo, struct vfp_entry *vfe, void *p,
 	} while (vg->flag != VGZ_FINISH);
 
 	if (vr != VGZ_END)
-		return (VFP_Error(bo, "Gzip failed"));
-	VGZ_UpdateObj(vg, bo->fetch_obj);
+		return (VFP_Error(vc, "Gzip failed"));
+	VGZ_UpdateObj(vg, vc->bo->fetch_obj);
 	return (VFP_END);
 }
 
@@ -608,7 +610,7 @@ vfp_gzip_pull(struct busyobj *bo, struct vfp_entry *vfe, void *p,
  */
 
 static enum vfp_status __match_proto__(vfp_pull_f)
-vfp_testgunzip_pull(struct busyobj *bo, struct vfp_entry *vfe, void *p,
+vfp_testgunzip_pull(struct vfp_ctx *vc, struct vfp_entry *vfe, void *p,
     ssize_t *lp)
 {
 	struct vgz *vg;
@@ -617,13 +619,14 @@ vfp_testgunzip_pull(struct busyobj *bo, struct vfp_entry *vfe, void *p,
 	size_t dl;
 	enum vfp_status vp;
 
-        CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
+        CHECK_OBJ_NOTNULL(vc, VFP_CTX_MAGIC);
+        CHECK_OBJ_NOTNULL(vc->bo, BUSYOBJ_MAGIC);
 	CHECK_OBJ_NOTNULL(vfe, VFP_ENTRY_MAGIC);
 	CAST_OBJ_NOTNULL(vg, vfe->priv1, VGZ_MAGIC);
         AN(p);
         AN(lp);
 	CAST_OBJ_NOTNULL(vg, vfe->priv1, VGZ_MAGIC);
-	vp = VFP_Suck(bo, p, lp);
+	vp = VFP_Suck(vc, p, lp);
 	if (vp == VFP_ERROR)
 		return (vp);
 	if (*lp > 0 || vp == VFP_END) {
@@ -632,16 +635,16 @@ vfp_testgunzip_pull(struct busyobj *bo, struct vfp_entry *vfe, void *p,
 			VGZ_Obuf(vg, vg->m_buf, vg->m_sz);
 			vr = VGZ_Gunzip(vg, &dp, &dl);
 			if (vr == VGZ_END && !VGZ_IbufEmpty(vg))
-				return(VFP_Error(bo, "Junk after gzip data"));
+				return(VFP_Error(vc, "Junk after gzip data"));
 			if (vr < VGZ_OK)
-				return (VFP_Error(bo,
+				return (VFP_Error(vc,
 				    "Invalid Gzip data: %s", vg->vz.msg));
 		} while (!VGZ_IbufEmpty(vg));
 	}
 	if (vp == VFP_END) {
 		if (vr != VGZ_END)
-			return (VFP_Error(bo, "tGunzip failed"));
-		VGZ_UpdateObj(vg, bo->fetch_obj);
+			return (VFP_Error(vc, "tGunzip failed"));
+		VGZ_UpdateObj(vg, vc->bo->fetch_obj);
 	}
 	return (vp);
 }
@@ -649,11 +652,11 @@ vfp_testgunzip_pull(struct busyobj *bo, struct vfp_entry *vfe, void *p,
 /*--------------------------------------------------------------------*/
 
 static void __match_proto__(vfp_fini_f)
-vfp_gzip_fini(struct busyobj *bo, struct vfp_entry *vfe)
+vfp_gzip_fini(struct vfp_ctx *vc, struct vfp_entry *vfe)
 {
 	struct vgz *vg;
 
-        CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
+        CHECK_OBJ_NOTNULL(vc, VFP_CTX_MAGIC);
 	CHECK_OBJ_NOTNULL(vfe, VFP_ENTRY_MAGIC);
 
 	if (vfe->priv1 != NULL) {
diff --git a/bin/varnishd/cache/cache_http1_fetch.c b/bin/varnishd/cache/cache_http1_fetch.c
index 8ec3553..233267c 100644
--- a/bin/varnishd/cache/cache_http1_fetch.c
+++ b/bin/varnishd/cache/cache_http1_fetch.c
@@ -45,13 +45,14 @@
 /*--------------------------------------------------------------------*/
 
 static enum vfp_status __match_proto__(vfp_pull_f)
-v1f_pull_straight(struct busyobj *bo, struct vfp_entry *vfe, void *p,
+v1f_pull_straight(struct vfp_ctx *vc, struct vfp_entry *vfe, void *p,
     ssize_t *lp)
 {
 	ssize_t l, lr;
 	struct http_conn *htc;
 
-	CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
+	CHECK_OBJ_NOTNULL(vc, VFP_CTX_MAGIC);
+	CHECK_OBJ_NOTNULL(vc->bo, BUSYOBJ_MAGIC);
 	CHECK_OBJ_NOTNULL(vfe, VFP_ENTRY_MAGIC);
 	CAST_OBJ_NOTNULL(htc, vfe->priv1, HTTP_CONN_MAGIC);
 	AN(p);
@@ -65,9 +66,9 @@ v1f_pull_straight(struct busyobj *bo, struct vfp_entry *vfe, void *p,
 	if (vfe->priv2 < l)
 		l = vfe->priv2;
 	lr = HTTP1_Read(htc, p, l);
-	bo->acct.beresp_bodybytes += lr;
+	vc->bo->acct.beresp_bodybytes += lr;
 	if (lr <= 0)
-		return (VFP_Error(bo, "straight insufficient bytes"));
+		return (VFP_Error(vc, "straight insufficient bytes"));
 	*lp = lr;
 	vfe->priv2 -= lr;
 	if (vfe->priv2 == 0)
@@ -87,22 +88,23 @@ static const struct vfp v1f_straight = {
  */
 
 static enum vfp_status __match_proto__(vfp_pull_f)
-v1f_pull_chunked(struct busyobj *bo, struct vfp_entry *vfe, void *p,
+v1f_pull_chunked(struct vfp_ctx *vc, struct vfp_entry *vfe, void *p,
     ssize_t *lp)
 {
 	const char *err;
 	struct http_conn *htc;
 
-	CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
+	CHECK_OBJ_NOTNULL(vc, VFP_CTX_MAGIC);
+	CHECK_OBJ_NOTNULL(vc->bo, BUSYOBJ_MAGIC);
 	CHECK_OBJ_NOTNULL(vfe, VFP_ENTRY_MAGIC);
 	CAST_OBJ_NOTNULL(htc, vfe->priv1, HTTP_CONN_MAGIC);
 	AN(p);
 	AN(lp);
 
 	switch (HTTP1_Chunked(htc, &vfe->priv2, &err,
-	    &bo->acct.beresp_bodybytes, p, lp)) {
+	    &vc->bo->acct.beresp_bodybytes, p, lp)) {
 	case H1CR_ERROR:
-		return (VFP_Error(bo, "%s", err));
+		return (VFP_Error(vc, "%s", err));
 	case H1CR_MORE:
 		return (VFP_OK);
 	case H1CR_END:
@@ -120,23 +122,26 @@ static const struct vfp v1f_chunked = {
 /*--------------------------------------------------------------------*/
 
 static enum vfp_status __match_proto__(vfp_pull_f)
-v1f_pull_eof(struct busyobj *bo, struct vfp_entry *vfe, void *p,
+v1f_pull_eof(struct vfp_ctx *vc, struct vfp_entry *vfe, void *p,
     ssize_t *lp)
 {
 	ssize_t l, lr;
 	struct http_conn *htc;
 
-	CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
+	CHECK_OBJ_NOTNULL(vc, VFP_CTX_MAGIC);
 	CHECK_OBJ_NOTNULL(vfe, VFP_ENTRY_MAGIC);
 	CAST_OBJ_NOTNULL(htc, vfe->priv1, HTTP_CONN_MAGIC);
 	AN(p);
+
+	// XXX: update vc->bo->acct.beresp_bodybytes ?
+
 	AN(lp);
 
 	l = *lp;
 	*lp = 0;
 	lr = HTTP1_Read(htc, p, l);
 	if (lr < 0)
-		return (VFP_Error(bo,"eof socket fail"));
+		return (VFP_Error(vc, "eof socket fail"));
 	if (lr == 0)
 		return (VFP_END);
 	*lp = lr;
@@ -166,19 +171,19 @@ V1F_Setup_Fetch(struct busyobj *bo)
 	switch(htc->body_status) {
 	case BS_EOF:
 		assert(bo->content_length == -1);
-		vfe = VFP_Push(bo, &v1f_eof, 0);
+		vfe = VFP_Push(&bo->vfc, &v1f_eof, 0);
 		vfe->priv1 = &bo->htc;
 		vfe->priv2 = 0;
 		break;
 	case BS_LENGTH:
 		assert(bo->content_length > 0);
-		vfe = VFP_Push(bo, &v1f_straight, 0);
+		vfe = VFP_Push(&bo->vfc, &v1f_straight, 0);
 		vfe->priv1 = &bo->htc;
 		vfe->priv2 = bo->content_length;
 		break;
 	case BS_CHUNKED:
 		assert(bo->content_length == -1);
-		vfe = VFP_Push(bo, &v1f_chunked, 0);
+		vfe = VFP_Push(&bo->vfc, &v1f_chunked, 0);
 		vfe->priv1 = &bo->htc;
 		vfe->priv2 = -1;
 		break;
diff --git a/bin/varnishd/cache/cache_panic.c b/bin/varnishd/cache/cache_panic.c
index d7f1182..88dc9f5 100644
--- a/bin/varnishd/cache/cache_panic.c
+++ b/bin/varnishd/cache/cache_panic.c
@@ -302,9 +302,9 @@ pan_busyobj(const struct busyobj *bo)
 
 	VSB_printf(pan_vsp, "    bodystatus = %d (%s),\n",
 	    bo->htc.body_status, body_status_2str(bo->htc.body_status));
-	if (!VTAILQ_EMPTY(&bo->vfp)) {
+	if (!VTAILQ_EMPTY(&bo->vfc.vfp)) {
 		VSB_printf(pan_vsp, "    filters =");
-		VTAILQ_FOREACH(vfe, &bo->vfp, list)
+		VTAILQ_FOREACH(vfe, &bo->vfc.vfp, list)
 			VSB_printf(pan_vsp, " %s=%d",
 			    vfe->vfp->name, (int)vfe->closed);
 		VSB_printf(pan_vsp, "\n");



More information about the varnish-commit mailing list