Skip to content

Commit

Permalink
Generalize the VDP API: struct vrt_init_ctx
Browse files Browse the repository at this point in the history
This commit is to prepare use of the VDP API also for the backend
side to filter bereq.body through bereq.filters by adding a struct
vrt_init_ctx argument to the VDP init function.

For background, see varnishcache#4035
  • Loading branch information
nigoroll committed May 29, 2024
1 parent 1659215 commit e38c0f7
Show file tree
Hide file tree
Showing 11 changed files with 173 additions and 85 deletions.
33 changes: 23 additions & 10 deletions bin/varnishd/cache/cache_deliver_proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,19 +70,16 @@ VDP_Fini(const struct vdp_ctx *vdc)
}

void
VDP_Init(struct vdp_ctx *vdc, struct worker *wrk, struct vsl_log *vsl,
struct req *req)
VDP_Init(struct vdp_ctx *vdc, struct worker *wrk, struct vsl_log *vsl)
{
AN(vdc);
CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
AN(vsl);
CHECK_OBJ_NOTNULL(req, REQ_MAGIC);

INIT_OBJ(vdc, VDP_CTX_MAGIC);
VTAILQ_INIT(&vdc->vdp);
vdc->wrk = wrk;
vdc->vsl = vsl;
vdc->req = req;
}

/* VDP_bytes
Expand Down Expand Up @@ -146,8 +143,9 @@ VDP_bytes(struct vdp_ctx *vdc, enum vdp_action act,

int
VDP_Push(VRT_CTX, struct vdp_ctx *vdc, struct ws *ws, const struct vdp *vdp,
void *priv)
void *priv, struct objcore *oc, struct http *hd, intmax_t *cl)
{
struct vdp_init_ctx initctx[1];
struct vdp_entry *vdpe;

CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
Expand All @@ -157,6 +155,19 @@ VDP_Push(VRT_CTX, struct vdp_ctx *vdc, struct ws *ws, const struct vdp *vdp,
AN(vdp->name);
AN(vdp->bytes);

CHECK_OBJ_ORNULL(oc, OBJCORE_MAGIC);
CHECK_OBJ_NOTNULL(hd, HTTP_MAGIC);
AN(cl);
assert(*cl >= -1);

if (vdc->retval)
return (vdc->retval);

INIT_OBJ(initctx, VDP_INIT_CTX_MAGIC);
initctx->oc = oc;
initctx->hd = hd;
initctx->cl = cl;

if (vdc->retval)
return (vdc->retval);

Expand All @@ -175,12 +186,15 @@ VDP_Push(VRT_CTX, struct vdp_ctx *vdc, struct ws *ws, const struct vdp *vdp,
VTAILQ_INSERT_TAIL(&vdc->vdp, vdpe, list);
vdc->nxt = VTAILQ_FIRST(&vdc->vdp);

if (vdc->nxt != vdpe)
initctx->oc = NULL;

AZ(vdc->retval);
if (vdpe->vdp->init == NULL)
return (vdc->retval);

vdc->retval = vdpe->vdp->init(ctx, vdc, &vdpe->priv,
vdpe == vdc->nxt ? vdc->req->objcore : NULL);
vdc->retval = 0;
else
vdc->retval = vdpe->vdp->init(ctx, vdc, &vdpe->priv, initctx);
initctx->oc = NULL;

if (vdc->retval > 0) {
VTAILQ_REMOVE(&vdc->vdp, vdpe, list);
Expand Down Expand Up @@ -254,7 +268,6 @@ VDP_DeliverObj(struct vdp_ctx *vdc, struct objcore *oc)
CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
CHECK_OBJ_NOTNULL(vdc->wrk, WORKER_MAGIC);
AN(vdc->vsl);
vdc->req = NULL;
final = oc->flags & (OC_F_PRIVATE | OC_F_HFM | OC_F_HFP) ? 1 : 0;
r = ObjIterate(vdc->wrk, oc, vdc, vdp_objiterate, final);
if (r < 0)
Expand Down
68 changes: 42 additions & 26 deletions bin/varnishd/cache/cache_esi_deliver.c
Original file line number Diff line number Diff line change
Expand Up @@ -261,35 +261,43 @@ ved_decode_len(struct vsl_log *vsl, const uint8_t **pp)
*/

static int v_matchproto_(vdp_init_f)
ved_vdp_esi_init(VRT_CTX, struct vdp_ctx *vdc, void **priv, struct objcore *oc)
ved_vdp_esi_init(VRT_CTX, struct vdp_ctx *vdc, void **priv,
const struct vdp_init_ctx *initctx)
{
struct ecx *ecx;
struct req *req;

CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
CHECK_OBJ_ORNULL(ctx->req, REQ_MAGIC);
CHECK_OBJ_NOTNULL(vdc, VDP_CTX_MAGIC);
CHECK_OBJ_ORNULL(oc, OBJCORE_MAGIC);
if (oc == NULL || !ObjHasAttr(vdc->wrk, oc, OA_ESIDATA))
return (1);

req = vdc->req;
CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
CHECK_OBJ_NOTNULL(initctx, VDP_INIT_CTX_MAGIC);
CHECK_OBJ_ORNULL(initctx->oc, OBJCORE_MAGIC);
CHECK_OBJ_NOTNULL(initctx->hd, HTTP_MAGIC);
AN(initctx->cl);
AN(priv);

AZ(*priv);
if (initctx->oc == NULL || !ObjHasAttr(vdc->wrk, initctx->oc, OA_ESIDATA))
return (1);

if (ctx->req == NULL) {
VSLb(vdc->vsl, SLT_Error,
"esi can only be used on the client side");
return (1);
}

ALLOC_OBJ(ecx, ECX_MAGIC);
AN(ecx);
assert(sizeof gzip_hdr == 10);
ecx->preq = req;
ecx->preq = ctx->req;
*priv = ecx;
RFC2616_Weaken_Etag(req->resp);

req->res_mode |= RES_ESI;
if (req->resp_len != 0)
req->resp_len = -1;
if (req->esi_level > 0) {
assert(req->transport == &VED_transport);
CAST_OBJ_NOTNULL(ecx->pecx, req->transport_priv, ECX_MAGIC);
RFC2616_Weaken_Etag(initctx->hd);

ctx->req->res_mode |= RES_ESI;
if (*initctx->cl != 0)
*initctx->cl = -1;
if (ctx->req->esi_level > 0) {
assert(ctx->req->transport == &VED_transport);
CAST_OBJ_NOTNULL(ecx->pecx, ctx->req->transport_priv, ECX_MAGIC);
if (!ecx->pecx->isgzip)
ecx->pecx = NULL;
}
Expand Down Expand Up @@ -604,18 +612,19 @@ struct ved_foo {
};

static int v_matchproto_(vdp_init_f)
ved_gzgz_init(VRT_CTX, struct vdp_ctx *vdc, void **priv, struct objcore *oc)
ved_gzgz_init(VRT_CTX, struct vdp_ctx *vdc, void **priv,
const struct vdp_init_ctx *initctx)
{
ssize_t l;
const char *p;
struct ved_foo *foo;
struct req *req;

CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
CHECK_OBJ_NOTNULL(vdc, VDP_CTX_MAGIC);
(void)oc;
req = vdc->req;
CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
AN(priv);
CHECK_OBJ_NOTNULL(initctx, VDP_INIT_CTX_MAGIC);
CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);

CAST_OBJ_NOTNULL(foo, *priv, VED_FOO_MAGIC);
CHECK_OBJ_NOTNULL(foo->objcore, OBJCORE_MAGIC);

Expand Down Expand Up @@ -872,6 +881,8 @@ ved_deliver(struct req *req, struct boc *boc, int wantbody)
struct ecx *ecx;
struct ved_foo foo[1];
struct vrt_ctx ctx[1];
const struct vdp *vdp;
void *priv;

CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
CHECK_OBJ_ORNULL(boc, BOC_MAGIC);
Expand Down Expand Up @@ -924,16 +935,21 @@ ved_deliver(struct req *req, struct boc *boc, int wantbody)
INIT_OBJ(foo, VED_FOO_MAGIC);
foo->ecx = ecx;
foo->objcore = req->objcore;
i = VDP_Push(ctx, req->vdc, req->ws, &ved_gzgz, foo);

vdp = &ved_gzgz;
priv = foo;
} else if (ecx->isgzip && !i) {
/* Non-Gzip'ed include in gzip'ed parent */
i = VDP_Push(ctx, req->vdc, req->ws, &ved_pretend_gz, ecx);
vdp = &ved_pretend_gz;
priv = ecx;
} else {
/* Anything else goes straight through */
i = VDP_Push(ctx, req->vdc, req->ws, &ved_ved, ecx);
vdp = &ved_ved;
priv = ecx;
}

i = VDP_Push(ctx, req->vdc, req->ws, vdp, priv,
req->objcore, req->resp, &req->resp_len);

if (i == 0) {
i = VDP_DeliverObj(req->vdc, req->objcore);
} else {
Expand Down
13 changes: 11 additions & 2 deletions bin/varnishd/cache/cache_filter.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ struct req;
struct vfp_entry;
struct vfp_ctx;
struct vdp_ctx;
struct vdp_init_ctx;

/* Fetch processors --------------------------------------------------*/

Expand Down Expand Up @@ -104,8 +105,9 @@ enum vdp_action {
VDP_END, /* Last buffer or after, implies VDP_FLUSH */
};


typedef int vdp_init_f(VRT_CTX, struct vdp_ctx *, void **priv,
struct objcore *);
const struct vdp_init_ctx *);
/*
* Return value:
* negative: Error - abandon delivery
Expand Down Expand Up @@ -147,7 +149,14 @@ struct vdp_ctx {
struct vdp_entry *nxt;
struct worker *wrk;
struct vsl_log *vsl;
struct req *req;
};

struct vdp_init_ctx {
unsigned magic;
#define VDP_INIT_CTX_MAGIC 0x3b876157
struct objcore *oc; // Only first filter, if at all
struct http *hd;
intmax_t *cl;
};

int VDP_bytes(struct vdp_ctx *, enum vdp_action act, const void *, ssize_t);
Expand Down
26 changes: 14 additions & 12 deletions bin/varnishd/cache/cache_gzip.c
Original file line number Diff line number Diff line change
Expand Up @@ -288,21 +288,23 @@ VGZ_Gzip(struct vgz *vg, const void **pptr, ssize_t *plen, enum vgz_flag flags)
*/

static int v_matchproto_(vdp_init_f)
vdp_gunzip_init(VRT_CTX, struct vdp_ctx *vdc, void **priv, struct objcore *oc)
vdp_gunzip_init(VRT_CTX, struct vdp_ctx *vdc, void **priv,
const struct vdp_init_ctx *initctx)
{
struct vgz *vg;
struct boc *boc;
struct req *req;
enum boc_state_e bos;
const char *p;
ssize_t dl;
uint64_t u;

CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
CHECK_OBJ_NOTNULL(vdc, VDP_CTX_MAGIC);
CHECK_OBJ_ORNULL(oc, OBJCORE_MAGIC);
req = vdc->req;
CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
CHECK_OBJ_NOTNULL(initctx, VDP_INIT_CTX_MAGIC);
CHECK_OBJ_ORNULL(initctx->oc, OBJCORE_MAGIC);
CHECK_OBJ_NOTNULL(initctx->hd, HTTP_MAGIC);
AN(initctx->cl);
AN(priv);

vg = VGZ_NewGunzip(vdc->vsl, "U D -");
AN(vg);
Expand All @@ -314,27 +316,27 @@ vdp_gunzip_init(VRT_CTX, struct vdp_ctx *vdc, void **priv, struct objcore *oc)
VGZ_Obuf(vg, vg->m_buf, vg->m_sz);
*priv = vg;

http_Unset(req->resp, H_Content_Encoding);
http_Unset(initctx->hd, H_Content_Encoding);

req->resp_len = -1;
*initctx->cl = -1;

if (oc == NULL)
if (initctx->oc == NULL)
return (0);

boc = HSH_RefBoc(oc);
boc = HSH_RefBoc(initctx->oc);
if (boc != NULL) {
CHECK_OBJ(boc, BOC_MAGIC);
bos = boc->state;
HSH_DerefBoc(vdc->wrk, oc);
HSH_DerefBoc(vdc->wrk, initctx->oc);
if (bos < BOS_FINISHED)
return (0); /* OA_GZIPBITS is not stable yet */
}

p = ObjGetAttr(vdc->wrk, oc, OA_GZIPBITS, &dl);
p = ObjGetAttr(vdc->wrk, initctx->oc, OA_GZIPBITS, &dl);
if (p != NULL && dl == 32) {
u = vbe64dec(p + 24);
if (u != 0)
req->resp_len = u;
*initctx->cl = u;
}
return (0);
}
Expand Down
34 changes: 22 additions & 12 deletions bin/varnishd/cache/cache_range.c
Original file line number Diff line number Diff line change
Expand Up @@ -196,33 +196,43 @@ vrg_ifrange(struct req *req)
}

static int v_matchproto_(vdp_init_f)
vrg_range_init(VRT_CTX, struct vdp_ctx *vdc, void **priv, struct objcore *oc)
vrg_range_init(VRT_CTX, struct vdp_ctx *vdc, void **priv,
const struct vdp_init_ctx *initctx)
{
const char *err;
struct req *req;

CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
CHECK_OBJ_ORNULL(ctx->req, REQ_MAGIC);
CHECK_OBJ_NOTNULL(vdc, VDP_CTX_MAGIC);
(void)oc;
req = vdc->req;
CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
if (!vrg_ifrange(req)) // rfc7233,l,455,456
AN(priv);
CHECK_OBJ_NOTNULL(initctx, VDP_INIT_CTX_MAGIC);

if (ctx->req == NULL) {
VSLb(vdc->vsl, SLT_Error,
"range can only be used on the client side");
return (1);
}

// not using initctx->{hd,cl}, because range needs req anyway for
// Req_Fail()

if (!vrg_ifrange(ctx->req)) // rfc7233,l,455,456
return (1);
err = vrg_dorange(req, priv);
err = vrg_dorange(ctx->req, priv);
if (err == NULL)
return (*priv == NULL ? 1 : 0);

VSLb(vdc->vsl, SLT_Debug, "RANGE_FAIL %s", err);
if (req->resp_len >= 0)
http_PrintfHeader(req->resp,
if (ctx->req->resp_len >= 0)
http_PrintfHeader(ctx->req->resp,
"Content-Range: bytes */%jd",
(intmax_t)req->resp_len);
http_PutResponse(req->resp, "HTTP/1.1", 416, NULL);
(intmax_t)ctx->req->resp_len);
http_PutResponse(ctx->req->resp, "HTTP/1.1", 416, NULL);
/*
* XXX: We ought to produce a body explaining things.
* XXX: That really calls for us to hit vcl_synth{}
*/
req->resp_len = 0;
ctx->req->resp_len = 0;
return (1);
}

Expand Down
5 changes: 3 additions & 2 deletions bin/varnishd/cache/cache_req_fsm.c
Original file line number Diff line number Diff line change
Expand Up @@ -460,11 +460,12 @@ cnt_transmit(struct worker *wrk, struct req *req)
sendbody = 1;
}

VDP_Init(req->vdc, req->wrk, req->vsl, req);
VDP_Init(req->vdc, req->wrk, req->vsl);
if (req->vdp_filter_list == NULL)
req->vdp_filter_list = resp_Get_Filter_List(req);
if (req->vdp_filter_list == NULL ||
VCL_StackVDP(req, req->vcl, req->vdp_filter_list)) {
VCL_StackVDP(req->vdc, req->vcl, req->vdp_filter_list,
req, NULL, &req->resp_len)) {
VSLb(req->vsl, SLT_Error, "Failure to push processors");
req->doclose = SC_OVERLOAD;
req->acct.resp_bodybytes +=
Expand Down
10 changes: 5 additions & 5 deletions bin/varnishd/cache/cache_varnishd.h
Original file line number Diff line number Diff line change
Expand Up @@ -188,12 +188,11 @@ void VDI_Init(void);

/* cache_deliver_proc.c */
void VDP_Fini(const struct vdp_ctx *vdc);
void VDP_Init(struct vdp_ctx *vdc, struct worker *wrk, struct vsl_log *vsl,
struct req *req);
void VDP_Init(struct vdp_ctx *vdc, struct worker *wrk, struct vsl_log *vsl);
uint64_t VDP_Close(struct vdp_ctx *, struct objcore *, struct boc *);
void VDP_Panic(struct vsb *vsb, const struct vdp_ctx *vdc);
int VDP_Push(VRT_CTX, struct vdp_ctx *, struct ws *, const struct vdp *,
void *priv);
int VDP_Push(VRT_CTX, struct vdp_ctx *vdc, struct ws *ws, const struct vdp *vdp,
void *priv, struct objcore *oc, struct http *hd, intmax_t *cl);
int VDP_DeliverObj(struct vdp_ctx *vdc, struct objcore *oc);
extern const struct vdp VDP_gunzip;
extern const struct vdp VDP_esi;
Expand Down Expand Up @@ -507,7 +506,8 @@ void pan_privs(struct vsb *, const struct vrt_privs *);

/* cache_vrt_filter.c */
int VCL_StackVFP(struct vfp_ctx *, const struct vcl *, const char *);
int VCL_StackVDP(struct req *, const struct vcl *, const char *);
int VCL_StackVDP(struct vdp_ctx *vdc, const struct vcl *vcl, const char *fl,
struct req *req, struct busyobj *bo, intmax_t *cl);
const char *resp_Get_Filter_List(struct req *req);
void VCL_VRT_Init(void);

Expand Down
Loading

0 comments on commit e38c0f7

Please sign in to comment.