Skip to content

Commit

Permalink
Rework VDP/VFP filter registry
Browse files Browse the repository at this point in the history
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
  • Loading branch information
bsdphk committed Dec 1, 2021
1 parent e8ce24c commit 19f77ef
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 81 deletions.
8 changes: 8 additions & 0 deletions bin/varnishd/cache/cache_filter.h
Expand Up @@ -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 *);

Expand Down Expand Up @@ -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 *);
1 change: 1 addition & 0 deletions bin/varnishd/cache/cache_vrt.c
Expand Up @@ -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)
Expand Down
170 changes: 89 additions & 81 deletions bin/varnishd/cache/cache_vrt_filter.c
Expand Up @@ -60,126 +60,134 @@ 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;

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
Expand Down Expand Up @@ -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));
}

/*--------------------------------------------------------------------
Expand Down

0 comments on commit 19f77ef

Please sign in to comment.