[master] 19f77efe6 Rework VDP/VFP filter registry

Poul-Henning Kamp phk at FreeBSD.org
Wed Dec 1 10:10:09 UTC 2021


commit 19f77efe69aceb78cc9e8a0d36a1dc9b8624cdc3
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Wed Dec 1 10:04:54 2021 +0000

    Rework VDP/VFP filter registry
    
    The old VRT_AddV[DF]P() and VRT_RemoveV[DF]P() are "soft deprecated"
    and work the same as previous.  (Hard deprecation after next major.)
    
    Replaced by:
        const char *VRT_AddFilter(VRT_CTX, const struct vfp *, const struct vdp *
        void VRT_RemoveFilter(VRT_CTX, const struct vfp *, const struct vdp *);
    
    VRT_CTX is mandatory.
    
    Both kinds of filters can be handled in one go, but the names must be identical.
    
    VRT_AddFilter returns NULL on success, and VRT_fail'ed error message otherwise.
    
    Supersedes #3287

diff --git a/bin/varnishd/cache/cache_filter.h b/bin/varnishd/cache/cache_filter.h
index 451c5715b..5d910e9c6 100644
--- a/bin/varnishd/cache/cache_filter.h
+++ b/bin/varnishd/cache/cache_filter.h
@@ -91,6 +91,8 @@ struct vfp_ctx {
 enum vfp_status VFP_Suck(struct vfp_ctx *, void *p, ssize_t *lp);
 enum vfp_status VFP_Error(struct vfp_ctx *, const char *fmt, ...)
     v_printflike_(2, 3);
+
+/* These two deprecated per 2021-12-01, add v_deprecated_ after next major */
 void VRT_AddVFP(VRT_CTX, const struct vfp *);
 void VRT_RemoveVFP(VRT_CTX, const struct vfp *);
 
@@ -147,5 +149,11 @@ struct vdp_ctx {
 };
 
 int VDP_bytes(struct vdp_ctx *, enum vdp_action act, const void *, ssize_t);
+
+/* These two deprecated per 2021-12-01, add v_deprecated_ after next major */
 void VRT_AddVDP(VRT_CTX, const struct vdp *);
 void VRT_RemoveVDP(VRT_CTX, const struct vdp *);
+
+/* Registry functions -------------------------------------------------*/
+const char *VRT_AddFilter(VRT_CTX, const struct vfp *, const struct vdp *);
+void VRT_RemoveFilter(VRT_CTX, const struct vfp *, const struct vdp *);
diff --git a/bin/varnishd/cache/cache_vrt.c b/bin/varnishd/cache/cache_vrt.c
index 31424c2ca..df7440ad8 100644
--- a/bin/varnishd/cache/cache_vrt.c
+++ b/bin/varnishd/cache/cache_vrt.c
@@ -664,6 +664,7 @@ VRT_fail(VRT_CTX, const char *fmt, ...)
 {
 	va_list ap;
 
+	CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
 	assert(ctx->vsl != NULL || ctx->msg != NULL);
 	AN(ctx->handling);
 	if (*ctx->handling == VCL_RET_FAIL)
diff --git a/bin/varnishd/cache/cache_vrt_filter.c b/bin/varnishd/cache/cache_vrt_filter.c
index d5962c7c6..b8e3b7c9a 100644
--- a/bin/varnishd/cache/cache_vrt_filter.c
+++ b/bin/varnishd/cache/cache_vrt_filter.c
@@ -60,104 +60,95 @@ struct vfilter {
 static struct vfilter_head vrt_filters =
     VTAILQ_HEAD_INITIALIZER(vrt_filters);
 
-void
-VRT_AddVFP(VRT_CTX, const struct vfp *filter)
+static const char *
+is_dup_filter(const struct vfilter_head *head, const struct vfp * vfp,
+    const struct vdp *vdp, const char *name)
 {
 	struct vfilter *vp;
-	struct vfilter_head *hd = &vrt_filters;
-
-	CHECK_OBJ_ORNULL(ctx, VRT_CTX_MAGIC);
-	AN(filter);
-	AN(filter->name);
-	AN(*filter->name);
-
-	VTAILQ_FOREACH(vp, hd, list) {
-                if (vp->vfp == NULL)
-			continue;
-		xxxassert(vp->vfp != filter);
-		xxxassert(strcasecmp(vp->name, filter->name));
-	}
-	if (ctx != NULL) {
-		ASSERT_CLI();
-		CHECK_OBJ_NOTNULL(ctx->vcl, VCL_MAGIC);
-		hd = &ctx->vcl->filters;
-		VTAILQ_FOREACH(vp, hd, list) {
-			if (vp->vfp == NULL)
-				continue;
-			xxxassert(vp->vfp != filter);
-			xxxassert(strcasecmp(vp->name, filter->name));
+	VTAILQ_FOREACH(vp, head, list) {
+		if (vfp != NULL && vp->vfp != NULL) {
+			if (vp->vfp == vfp)
+				return ("VFP already registered");
+			if (!strcasecmp(vp->name, name))
+				return ("VFP name already used");
+		}
+		if (vdp != NULL && vp->vdp != NULL) {
+			if (vp->vdp == vdp)
+				return ("VDP already registered");
+			if (!strcasecmp(vp->name, name))
+				return ("VDP name already used");
 		}
 	}
-	ALLOC_OBJ(vp, VFILTER_MAGIC);
-	AN(vp);
-	vp->vfp = filter;
-	vp->name = filter->name;
-	vp->nlen = strlen(vp->name);
-	VTAILQ_INSERT_TAIL(hd, vp, list);
+	return (NULL);
 }
 
-void
-VRT_AddVDP(VRT_CTX, const struct vdp *filter)
+static const char *
+vrt_addfilter(VRT_CTX, const struct vfp *vfp, const struct vdp *vdp)
 {
 	struct vfilter *vp;
 	struct vfilter_head *hd = &vrt_filters;
+	const char *err, *name = NULL;
 
 	CHECK_OBJ_ORNULL(ctx, VRT_CTX_MAGIC);
-	AN(filter);
-	AN(filter->name);
-	AN(*filter->name);
-
-	VTAILQ_FOREACH(vp, hd, list) {
-                if (vp->vdp == NULL)
-			continue;
-		xxxassert(vp->vdp != filter);
-		xxxassert(strcasecmp(vp->name, filter->name));
+	assert(vfp != NULL || vdp != NULL);
+	assert(vfp == NULL || vfp->name != NULL);
+	assert(vdp == NULL || vdp->name != NULL);
+	assert(vfp == NULL || vdp == NULL || !strcasecmp(vfp->name, vdp->name));
+	if (vfp != NULL)
+		name = vfp->name;
+	else if (vdp != NULL)
+		name = vdp->name;
+	AN(name);
+
+	err = is_dup_filter(hd, vfp, vdp, name);
+	if (err != NULL) {
+		if (ctx != NULL)
+			VRT_fail(ctx, "%s (global)", err);
+		return (err);
 	}
 	if (ctx != NULL) {
 		ASSERT_CLI();
 		CHECK_OBJ_NOTNULL(ctx->vcl, VCL_MAGIC);
 		hd = &ctx->vcl->filters;
-		VTAILQ_FOREACH(vp, hd, list) {
-			if (vp->vdp == NULL)
-				continue;
-			xxxassert(vp->vdp != filter);
-			xxxassert(strcasecmp(vp->name, filter->name));
+		err = is_dup_filter(hd, vfp, vdp, name);
+		if (err != NULL) {
+			VRT_fail(ctx, "%s (per-vcl)", err);
+			return (err);
 		}
 	}
+
 	ALLOC_OBJ(vp, VFILTER_MAGIC);
 	AN(vp);
-	vp->vdp = filter;
-	vp->name = filter->name;
-	vp->nlen = strlen(vp->name);
+	vp->vfp = vfp;
+	vp->vdp = vdp;
+	vp->name = name;
+	vp->nlen = strlen(name);
 	VTAILQ_INSERT_TAIL(hd, vp, list);
+	return(err);
 }
 
-void
-VRT_RemoveVFP(VRT_CTX, const struct vfp *filter)
+const char *
+VRT_AddFilter(VRT_CTX, const struct vfp *vfp, const struct vdp *vdp)
 {
-	struct vfilter *vp;
-	struct vfilter_head *hd;
 
 	CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
-	CHECK_OBJ_NOTNULL(ctx->vcl, VCL_MAGIC);
-	hd = &ctx->vcl->filters;
-	AN(filter);
-	AN(filter->name);
-	AN(*filter->name);
+	return (vrt_addfilter(ctx, vfp, vdp));
+}
 
-	ASSERT_CLI();
-	VTAILQ_FOREACH(vp, hd, list) {
-		CHECK_OBJ_NOTNULL(vp, VFILTER_MAGIC);
-		if (vp->vfp == filter)
-			break;
-	}
-	XXXAN(vp);
-	VTAILQ_REMOVE(hd, vp, list);
-	FREE_OBJ(vp);
+void
+VRT_AddVFP(VRT_CTX, const struct vfp *filter)
+{
+	AZ(VRT_AddFilter(ctx, filter, NULL));
 }
 
 void
-VRT_RemoveVDP(VRT_CTX, const struct vdp *filter)
+VRT_AddVDP(VRT_CTX, const struct vdp *filter)
+{
+	AZ(VRT_AddFilter(ctx, NULL, filter));
+}
+
+void
+VRT_RemoveFilter(VRT_CTX, const struct vfp *vfp, const struct vdp *vdp)
 {
 	struct vfilter *vp;
 	struct vfilter_head *hd;
@@ -165,21 +156,38 @@ VRT_RemoveVDP(VRT_CTX, const struct vdp *filter)
 	CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
 	CHECK_OBJ_NOTNULL(ctx->vcl, VCL_MAGIC);
 	hd = &ctx->vcl->filters;
-	AN(filter);
-	AN(filter->name);
-	AN(*filter->name);
+	assert(vfp != NULL || vdp != NULL);
+	assert(vfp == NULL || vfp->name != NULL);
+	assert(vdp == NULL || vdp->name != NULL);
+	assert(vfp == NULL || vdp == NULL || !strcasecmp(vfp->name, vdp->name));
 
 	ASSERT_CLI();
 	VTAILQ_FOREACH(vp, hd, list) {
 		CHECK_OBJ_NOTNULL(vp, VFILTER_MAGIC);
-		if (vp->vdp == filter)
+		if (vp->vfp == vfp && vp->vdp == vdp)
 			break;
 	}
-	XXXAN(vp);
+	AN(vp);
+	assert(vfp == NULL || !strcasecmp(vfp->name, vp->name));
+	assert(vdp == NULL || !strcasecmp(vdp->name, vp->name));
 	VTAILQ_REMOVE(hd, vp, list);
 	FREE_OBJ(vp);
 }
 
+void
+VRT_RemoveVFP(VRT_CTX, const struct vfp *filter)
+{
+
+	VRT_RemoveFilter(ctx, filter, NULL);
+}
+
+void
+VRT_RemoveVDP(VRT_CTX, const struct vdp *filter)
+{
+
+	VRT_RemoveFilter(ctx, NULL, filter);
+}
+
 static const struct vfilter vfilter_error[1];
 
 // XXX: idea(fgs): Allow filters (...) arguments in the list
@@ -269,14 +277,14 @@ VCL_StackVDP(struct req *req, const struct vcl *vcl, const char *fl)
 void
 VCL_VRT_Init(void)
 {
-	VRT_AddVFP(NULL, &VFP_testgunzip);
-	VRT_AddVFP(NULL, &VFP_gunzip);
-	VRT_AddVFP(NULL, &VFP_gzip);
-	VRT_AddVFP(NULL, &VFP_esi);
-	VRT_AddVFP(NULL, &VFP_esi_gzip);
-	VRT_AddVDP(NULL, &VDP_esi);
-	VRT_AddVDP(NULL, &VDP_gunzip);
-	VRT_AddVDP(NULL, &VDP_range);
+	AZ(vrt_addfilter(NULL, &VFP_testgunzip, NULL));
+	AZ(vrt_addfilter(NULL, &VFP_gunzip, NULL));
+	AZ(vrt_addfilter(NULL, &VFP_gzip, NULL));
+	AZ(vrt_addfilter(NULL, &VFP_esi, NULL));
+	AZ(vrt_addfilter(NULL, &VFP_esi_gzip, NULL));
+	AZ(vrt_addfilter(NULL, NULL, &VDP_esi));
+	AZ(vrt_addfilter(NULL, NULL, &VDP_gunzip));
+	AZ(vrt_addfilter(NULL, NULL, &VDP_range));
 }
 
 /*--------------------------------------------------------------------


More information about the varnish-commit mailing list