Hi again Here's a new set of patches, following the discussion at VDD14Q4 (https://www.varnish-cache.org/trac/wiki/VDD14Q4#Notestakenduringthemeeting)
To summarize the changes, - PRIV_SESS is dropped. - PRIV_REQ is reintroduced as PRIV_TASK, which is also available as a separate priv pointer in vcl_backend_*. regards, Dag On Thu, Nov 20, 2014 at 9:07 AM, Dag Haavi Finstad <[email protected]> wrote: > Hi > > Here's a suggestion (and a set of patches) for what PRIV_REQ/SESS > could look like in vcl_backend_*, mostly based around IRC discussion. > > The idea is to make PRIV_REQ available also in vcl_backend_*, and then > give a separate priv object from the one used on the client side. > Realizing this could lead to confusion, it was suggested to rename it > PRIV_XID. The priv object will however survive a VCL restart/retry, so > the name is not completely honest in that it is not restricted to a > single XID. I think this is the behavior that makes the most sense, > but I'm not super excited about the name. > > A second point is regarding PRIV_SESS. A concern with PRIV_SESS is > that the remote Varnish is talking to very often tends to be not the > client itself, but rather a load balancer dispatching requests from a > bunch of clients over the same persistent connections. So if you were > to introduce a priv_sess vmod that handles some sort of client state > in such a scenario, you will very quickly shoot yourself in the foot > and leak state across clients unless you know what you are doing. I > think the problems solved by PRIV_SESS are typically solved much safer > via PRIV_REQ. > > A point brought up by Tollef on IRC is that PRIV_SESS lets you share > state between a request and its ESI subrequests, something that has > legitimate use cases. Patch #5 (attached) drops PRIV_SESS and > introduces PRIV_ESI, which restricts the scope to a request and its > client-side subrequests. > > Feedback/comments/complaints very welcome. :-) > > regards, > Dag > > -- > Dag Haavi Finstad > Software Developer | Varnish Software > Mobile: +47 476 64 134 > We Make Websites Fly! -- Dag Haavi Finstad Software Developer | Varnish Software Mobile: +47 476 64 134 We Make Websites Fly!
From 36e2b7adf82c28b05ca010c9fed5d44bb4f6ad76 Mon Sep 17 00:00:00 2001 From: Dag Haavi Finstad <[email protected]> Date: Tue, 25 Nov 2014 14:10:37 +0100 Subject: [PATCH 1/3] Drop PRIV_SESS, as agreed on VDD14Q4. --- bin/varnishd/cache/cache_session.c | 2 +- bin/varnishd/cache/cache_vrt_priv.c | 8 -------- bin/varnishtest/tests/v00041.vtc | 9 +-------- include/vrt.h | 1 - lib/libvcc/vcc_expr.c | 6 ------ lib/libvcc/vmodtool.py | 1 - lib/libvmod_debug/vmod.vcc | 4 ---- lib/libvmod_debug/vmod_debug.c | 12 ------------ 8 files changed, 2 insertions(+), 41 deletions(-) diff --git a/bin/varnishd/cache/cache_session.c b/bin/varnishd/cache/cache_session.c index 7749216..724b1a0 100644 --- a/bin/varnishd/cache/cache_session.c +++ b/bin/varnishd/cache/cache_session.c @@ -300,7 +300,7 @@ SES_Delete(struct sess *sp, enum sess_close reason, double now) now = VTIM_real(); AZ(isnan(sp->t_open)); - VRTPRIV_dynamic_kill(sp, 0); + assert(VTAILQ_EMPTY(&sp->privs)); VSL(SLT_SessClose, sp->vxid, "%s %.3f", sess_close_2str(sp->reason, 0), now - sp->t_open); VSL(SLT_End, sp->vxid, "%s", ""); diff --git a/bin/varnishd/cache/cache_vrt_priv.c b/bin/varnishd/cache/cache_vrt_priv.c index 4998e74..482e34d 100644 --- a/bin/varnishd/cache/cache_vrt_priv.c +++ b/bin/varnishd/cache/cache_vrt_priv.c @@ -89,8 +89,6 @@ VRTPRIV_dynamic_kill(struct sess *sp, uintptr_t id) FREE_OBJ(vps); } } - if (id == 0) - assert(VTAILQ_EMPTY(&sp->privs)); } struct vmod_priv * @@ -99,12 +97,6 @@ VRT_priv_req(VRT_CTX, void *vmod_id) return (VRT_priv_dynamic(ctx, (uintptr_t)ctx->req, (uintptr_t)vmod_id)); } -struct vmod_priv * -VRT_priv_sess(VRT_CTX, void *vmod_id) -{ - return (VRT_priv_dynamic(ctx, (uintptr_t)NULL, (uintptr_t)vmod_id)); -} - /*-------------------------------------------------------------------- */ diff --git a/bin/varnishtest/tests/v00041.vtc b/bin/varnishtest/tests/v00041.vtc index af951f9..2be9f8a 100644 --- a/bin/varnishtest/tests/v00041.vtc +++ b/bin/varnishtest/tests/v00041.vtc @@ -1,4 +1,4 @@ -varnishtest "Test priv_sess and priv_req" +varnishtest "Test priv_req" server s1 { rxreq @@ -12,14 +12,11 @@ varnish v1 -vcl+backend { sub vcl_recv { set req.http.x0 = debug.test_priv_req(req.url); - set req.http.y0 = debug.test_priv_sess(req.url); } sub vcl_deliver { set resp.http.x0 = req.http.x0; set resp.http.x1 = debug.test_priv_req(""); - set resp.http.y0 = req.http.y0; - set resp.http.y1 = debug.test_priv_sess(""); } } -start @@ -29,13 +26,9 @@ client c1 { rxresp expect resp.http.x0 == /foobar expect resp.http.x1 == /foobar - expect resp.http.y0 == /foobar - expect resp.http.y1 == /foobar txreq -url /snafu rxresp expect resp.http.x0 == /snafu expect resp.http.x1 == /snafu - expect resp.http.y0 == /foobar - expect resp.http.y1 == /foobar } -run diff --git a/include/vrt.h b/include/vrt.h index f9624a6..78cf479 100644 --- a/include/vrt.h +++ b/include/vrt.h @@ -246,7 +246,6 @@ struct vmod_priv { typedef int vmod_init_f(struct vmod_priv *, const struct VCL_conf *); void VRT_priv_fini(const struct vmod_priv *p); -struct vmod_priv *VRT_priv_sess(VRT_CTX, void *vmod_id); struct vmod_priv *VRT_priv_req(VRT_CTX, void *vmod_id); /* Stevedore related functions */ diff --git a/lib/libvcc/vcc_expr.c b/lib/libvcc/vcc_expr.c index 2eb9e73..72d8386 100644 --- a/lib/libvcc/vcc_expr.c +++ b/lib/libvcc/vcc_expr.c @@ -557,12 +557,6 @@ vcc_priv_arg(struct vcc *tl, const char *p, const char *name) e2 = vcc_mk_expr(VOID, "VRT_priv_req(ctx, &VGC_vmod_%.*s)", (int) (r - name), name); - } else if (!strcmp(p, "PRIV_SESS")) { - r = strchr(name, '.'); - AN(r); - e2 = vcc_mk_expr(VOID, - "VRT_priv_sess(ctx, &VGC_vmod_%.*s)", - (int) (r - name), name); } else { WRONG("Wrong PRIV_ type"); } diff --git a/lib/libvcc/vmodtool.py b/lib/libvcc/vmodtool.py index 2d335fc..ef6ea2c 100755 --- a/lib/libvcc/vmodtool.py +++ b/lib/libvcc/vmodtool.py @@ -58,7 +58,6 @@ ctypes = { 'IP': "VCL_IP", 'PRIV_CALL': "struct vmod_priv *", 'PRIV_VCL': "struct vmod_priv *", - 'PRIV_SESS': "struct vmod_priv *", 'PRIV_REQ': "struct vmod_priv *", 'REAL': "VCL_REAL", 'STRING': "VCL_STRING", diff --git a/lib/libvmod_debug/vmod.vcc b/lib/libvmod_debug/vmod.vcc index 468fc51..09e6c0b 100644 --- a/lib/libvmod_debug/vmod.vcc +++ b/lib/libvmod_debug/vmod.vcc @@ -55,10 +55,6 @@ $Function STRING test_priv_req(PRIV_REQ, STRING) Test function for REQ private pointers -$Function STRING test_priv_sess(PRIV_SESS, STRING) - -Test function for SESS private pointers - $Function BLOB str2blob(STRING src) Turn a string into a blob diff --git a/lib/libvmod_debug/vmod_debug.c b/lib/libvmod_debug/vmod_debug.c index 08b5aa8..d8077ce 100644 --- a/lib/libvmod_debug/vmod_debug.c +++ b/lib/libvmod_debug/vmod_debug.c @@ -88,18 +88,6 @@ vmod_test_priv_call(VRT_CTX, struct vmod_priv *priv) } } -VCL_STRING __match_proto__(td_debug_test_priv_sess) -vmod_test_priv_sess(VRT_CTX, struct vmod_priv *priv, VCL_STRING s) -{ - - CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); - if (priv->priv == NULL) { - priv->priv = strdup(s); - priv->free = free; - } - return (priv->priv); -} - VCL_STRING __match_proto__(td_debug_test_priv_req) vmod_test_priv_req(VRT_CTX, struct vmod_priv *priv, VCL_STRING s) { -- 2.1.3
From 97d06747cc605efd6ee70067dbff93a1c8bc03ad Mon Sep 17 00:00:00 2001 From: Dag Haavi Finstad <[email protected]> Date: Tue, 25 Nov 2014 14:26:28 +0100 Subject: [PATCH 2/3] Make the VRTPRIV_* interface slightly more generic to let us use it without needing a req/sess pointer. --- bin/varnishd/cache/cache.h | 15 +++++++-- bin/varnishd/cache/cache_session.c | 4 +-- bin/varnishd/cache/cache_vrt_priv.c | 62 +++++++++++++++++++++--------------- bin/varnishd/http1/cache_http1_fsm.c | 2 +- 4 files changed, 51 insertions(+), 32 deletions(-) diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h index d8007c8..d69b4bd 100644 --- a/bin/varnishd/cache/cache.h +++ b/bin/varnishd/cache/cache.h @@ -119,7 +119,7 @@ struct sess; struct sesspool; struct vbc; struct vrt_backend; -struct vrt_privs; +struct vrt_priv; struct vsb; struct waitinglist; struct worker; @@ -299,6 +299,14 @@ struct vxid_pool { /*--------------------------------------------------------------------*/ +struct vrt_privs { + unsigned magic; +#define VRT_PRIVS_MAGIC 0x03ba7501 + VTAILQ_HEAD(,vrt_priv) privs; +}; + +/*--------------------------------------------------------------------*/ + struct wrk_accept { unsigned magic; #define WRK_ACCEPT_MAGIC 0x8c4b4d59 @@ -663,7 +671,7 @@ struct sess { double t_open; /* fd accepted */ double t_idle; /* fd accepted or resp sent */ - VTAILQ_HEAD(,vrt_privs) privs; + struct vrt_privs privs[1]; #if defined(HAVE_EPOLL_CTL) struct epoll_event ev; @@ -1046,7 +1054,8 @@ const char *VCL_Method_Name(unsigned); */ const char *VRT_String(struct ws *ws, const char *h, const char *p, va_list ap); char *VRT_StringList(char *d, unsigned dl, const char *p, va_list ap); -void VRTPRIV_dynamic_kill(struct sess *sp, uintptr_t id); +void VRTPRIV_init(struct vrt_privs *privs); +void VRTPRIV_dynamic_kill(struct vrt_privs *privs, uintptr_t id); void ESI_Deliver(struct req *); void ESI_DeliverChild(struct req *, struct busyobj *); diff --git a/bin/varnishd/cache/cache_session.c b/bin/varnishd/cache/cache_session.c index 724b1a0..60c893e 100644 --- a/bin/varnishd/cache/cache_session.c +++ b/bin/varnishd/cache/cache_session.c @@ -91,7 +91,7 @@ ses_new(struct sesspool *pp) sp->t_open = NAN; sp->t_idle = NAN; - VTAILQ_INIT(&sp->privs); + VRTPRIV_init(sp->privs); Lck_New(&sp->mtx, lck_sess); CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); return (sp); @@ -300,7 +300,7 @@ SES_Delete(struct sess *sp, enum sess_close reason, double now) now = VTIM_real(); AZ(isnan(sp->t_open)); - assert(VTAILQ_EMPTY(&sp->privs)); + assert(VTAILQ_EMPTY(&sp->privs->privs)); VSL(SLT_SessClose, sp->vxid, "%s %.3f", sess_close_2str(sp->reason, 0), now - sp->t_open); VSL(SLT_End, sp->vxid, "%s", ""); diff --git a/bin/varnishd/cache/cache_vrt_priv.c b/bin/varnishd/cache/cache_vrt_priv.c index 482e34d..1819364 100644 --- a/bin/varnishd/cache/cache_vrt_priv.c +++ b/bin/varnishd/cache/cache_vrt_priv.c @@ -40,10 +40,10 @@ #include "vcl.h" #include "vrt.h" -struct vrt_privs { +struct vrt_priv { unsigned magic; -#define VRT_PRIVS_MAGIC 0x24157a52 - VTAILQ_ENTRY(vrt_privs) list; +#define VRT_PRIV_MAGIC 0x24157a52 + VTAILQ_ENTRY(vrt_priv) list; struct vmod_priv priv[1]; const struct VCL_conf *vcl; uintptr_t id; @@ -53,40 +53,51 @@ struct vrt_privs { /*-------------------------------------------------------------------- */ +void +VRTPRIV_init(struct vrt_privs *privs) +{ + privs->magic = VRT_PRIVS_MAGIC; + VTAILQ_INIT(&privs->privs); +} + static struct vmod_priv * VRT_priv_dynamic(VRT_CTX, uintptr_t id, uintptr_t vmod_id) { - struct vrt_privs *vps; + struct vrt_priv *vp; CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); - VTAILQ_FOREACH(vps, &ctx->req->sp->privs, list) { - CHECK_OBJ_NOTNULL(vps, VRT_PRIVS_MAGIC); - if (vps->vcl == ctx->vcl && vps->id == id - && vps->vmod_id == vmod_id) - return (vps->priv); + CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC); + CHECK_OBJ_NOTNULL(ctx->req->sp, SESS_MAGIC); + CHECK_OBJ_NOTNULL(ctx->req->sp->privs, VRT_PRIVS_MAGIC); + + VTAILQ_FOREACH(vp, &ctx->req->sp->privs->privs, list) { + CHECK_OBJ_NOTNULL(vp, VRT_PRIV_MAGIC); + if (vp->vcl == ctx->vcl && vp->id == id + && vp->vmod_id == vmod_id) + return (vp->priv); } - ALLOC_OBJ(vps, VRT_PRIVS_MAGIC); - AN(vps); - vps->vcl = ctx->vcl; - vps->id = id; - vps->vmod_id = vmod_id; - VTAILQ_INSERT_TAIL(&ctx->req->sp->privs, vps, list); - return (vps->priv); + ALLOC_OBJ(vp, VRT_PRIV_MAGIC); + AN(vp); + vp->vcl = ctx->vcl; + vp->id = id; + vp->vmod_id = vmod_id; + VTAILQ_INSERT_TAIL(&ctx->req->sp->privs->privs, vp, list); + return (vp->priv); } void -VRTPRIV_dynamic_kill(struct sess *sp, uintptr_t id) +VRTPRIV_dynamic_kill(struct vrt_privs *privs, uintptr_t id) { - struct vrt_privs *vps, *vps1; + struct vrt_priv *vp, *vp1; - CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); + CHECK_OBJ_NOTNULL(privs, VRT_PRIVS_MAGIC); - VTAILQ_FOREACH_SAFE(vps, &sp->privs, list, vps1) { - CHECK_OBJ_NOTNULL(vps, VRT_PRIVS_MAGIC); - if (id == vps->id) { - VTAILQ_REMOVE(&sp->privs, vps, list); - VRT_priv_fini(vps->priv); - FREE_OBJ(vps); + VTAILQ_FOREACH_SAFE(vp, &privs->privs, list, vp1) { + CHECK_OBJ_NOTNULL(vp, VRT_PRIV_MAGIC); + if (id == vp->id) { + VTAILQ_REMOVE(&privs->privs, vp, list); + VRT_priv_fini(vp->priv); + FREE_OBJ(vp); } } } @@ -107,4 +118,3 @@ VRT_priv_fini(const struct vmod_priv *p) if (p->priv != (void*)0 && p->free != (void*)0) p->free(p->priv); } - diff --git a/bin/varnishd/http1/cache_http1_fsm.c b/bin/varnishd/http1/cache_http1_fsm.c index a7ca699..29bd789 100644 --- a/bin/varnishd/http1/cache_http1_fsm.c +++ b/bin/varnishd/http1/cache_http1_fsm.c @@ -166,7 +166,7 @@ http1_cleanup(struct sess *sp, struct worker *wrk, struct req *req) req->vcl = NULL; } - VRTPRIV_dynamic_kill(sp, (uintptr_t)req); + VRTPRIV_dynamic_kill(sp->privs, (uintptr_t)req); /* Charge and log byte counters */ AN(req->vsl->wid); CNT_AcctLogCharge(wrk->stats, req); -- 2.1.3
From 13be7999ee2a6fff0516f947ad5aa3fa1a6b0b17 Mon Sep 17 00:00:00 2001 From: Dag Haavi Finstad <[email protected]> Date: Tue, 25 Nov 2014 14:40:13 +0100 Subject: [PATCH 3/3] Reintroduce PRIV_REQ as PRIV_TASK. PRIV_TASK is available (as separate priv pointers) both in the client side and the backend side VCL functions. --- bin/varnishd/cache/cache.h | 1 + bin/varnishd/cache/cache_busyobj.c | 5 +++ bin/varnishd/cache/cache_esi_deliver.c | 1 + bin/varnishd/cache/cache_vrt_priv.c | 30 +++++++++++---- bin/varnishtest/tests/r01038.vtc | 2 +- bin/varnishtest/tests/v00041.vtc | 22 +++++++++-- bin/varnishtest/tests/v00042.vtc | 68 ++++++++++++++++++++++++++++++++++ doc/sphinx/reference/vmod.rst | 18 +++++++-- include/vrt.h | 2 +- lib/libvcc/vcc_expr.c | 4 +- lib/libvcc/vmodtool.py | 2 +- lib/libvmod_debug/vmod.vcc | 4 +- lib/libvmod_debug/vmod_debug.c | 4 +- 13 files changed, 140 insertions(+), 23 deletions(-) create mode 100644 bin/varnishtest/tests/v00042.vtc diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h index d69b4bd..5ad4519 100644 --- a/bin/varnishd/cache/cache.h +++ b/bin/varnishd/cache/cache.h @@ -525,6 +525,7 @@ struct busyobj { struct vsb *synth_body; uint8_t digest[DIGEST_LEN]; + struct vrt_privs privs[1]; }; diff --git a/bin/varnishd/cache/cache_busyobj.c b/bin/varnishd/cache/cache_busyobj.c index ad31e11..16c67f2 100644 --- a/bin/varnishd/cache/cache_busyobj.c +++ b/bin/varnishd/cache/cache_busyobj.c @@ -154,6 +154,8 @@ VBO_GetBusyObj(struct worker *wrk, const struct req *req) memcpy(bo->digest, req->digest, sizeof bo->digest); + VRTPRIV_init(bo->privs); + return (bo); } @@ -190,6 +192,9 @@ VBO_DerefBusyObj(struct worker *wrk, struct busyobj **pbo) AZ(bo->htc); + VRTPRIV_dynamic_kill(bo->privs, (uintptr_t)bo); + assert(VTAILQ_EMPTY(&bo->privs->privs)); + VSLb(bo->vsl, SLT_BereqAcct, "%ju %ju %ju %ju %ju %ju", (uintmax_t)bo->acct.bereq_hdrbytes, (uintmax_t)bo->acct.bereq_bodybytes, diff --git a/bin/varnishd/cache/cache_esi_deliver.c b/bin/varnishd/cache/cache_esi_deliver.c index 3e6e9d3..39df537 100644 --- a/bin/varnishd/cache/cache_esi_deliver.c +++ b/bin/varnishd/cache/cache_esi_deliver.c @@ -147,6 +147,7 @@ ved_include(struct req *preq, const char *src, const char *host) (void)usleep(10000); } + VRTPRIV_dynamic_kill(req->sp->privs, (uintptr_t)req); CNT_AcctLogCharge(wrk->stats, req); VSL_End(req->vsl); diff --git a/bin/varnishd/cache/cache_vrt_priv.c b/bin/varnishd/cache/cache_vrt_priv.c index 1819364..a0a5185 100644 --- a/bin/varnishd/cache/cache_vrt_priv.c +++ b/bin/varnishd/cache/cache_vrt_priv.c @@ -63,14 +63,20 @@ VRTPRIV_init(struct vrt_privs *privs) static struct vmod_priv * VRT_priv_dynamic(VRT_CTX, uintptr_t id, uintptr_t vmod_id) { + struct vrt_privs *vps; struct vrt_priv *vp; CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); - CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC); - CHECK_OBJ_NOTNULL(ctx->req->sp, SESS_MAGIC); - CHECK_OBJ_NOTNULL(ctx->req->sp->privs, VRT_PRIVS_MAGIC); + if (ctx->req) { + CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC); + CHECK_OBJ_NOTNULL(ctx->req->sp, SESS_MAGIC); + CAST_OBJ_NOTNULL(vps, ctx->req->sp->privs, VRT_PRIVS_MAGIC); + } else { + CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC); + CAST_OBJ_NOTNULL(vps, ctx->bo->privs, VRT_PRIVS_MAGIC); + } - VTAILQ_FOREACH(vp, &ctx->req->sp->privs->privs, list) { + VTAILQ_FOREACH(vp, &vps->privs, list) { CHECK_OBJ_NOTNULL(vp, VRT_PRIV_MAGIC); if (vp->vcl == ctx->vcl && vp->id == id && vp->vmod_id == vmod_id) @@ -81,7 +87,7 @@ VRT_priv_dynamic(VRT_CTX, uintptr_t id, uintptr_t vmod_id) vp->vcl = ctx->vcl; vp->id = id; vp->vmod_id = vmod_id; - VTAILQ_INSERT_TAIL(&ctx->req->sp->privs->privs, vp, list); + VTAILQ_INSERT_TAIL(&vps->privs, vp, list); return (vp->priv); } @@ -103,9 +109,19 @@ VRTPRIV_dynamic_kill(struct vrt_privs *privs, uintptr_t id) } struct vmod_priv * -VRT_priv_req(VRT_CTX, void *vmod_id) +VRT_priv_task(VRT_CTX, void *vmod_id) { - return (VRT_priv_dynamic(ctx, (uintptr_t)ctx->req, (uintptr_t)vmod_id)); + uintptr_t id; + + CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); + if (ctx->req) { + CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC); + id = (uintptr_t)ctx->req; + } else { + CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC); + id = (uintptr_t)ctx->bo; + } + return (VRT_priv_dynamic(ctx, id, (uintptr_t)vmod_id)); } /*-------------------------------------------------------------------- diff --git a/bin/varnishtest/tests/r01038.vtc b/bin/varnishtest/tests/r01038.vtc index bb57072..705e11c 100644 --- a/bin/varnishtest/tests/r01038.vtc +++ b/bin/varnishtest/tests/r01038.vtc @@ -45,7 +45,7 @@ server s1 { txresp -body "foo8" } -start -varnish v1 -arg "-p workspace_backend=9k" -vcl+backend { +varnish v1 -arg "-p workspace_backend=10k" -vcl+backend { sub vcl_backend_response { set beresp.do_esi = true; } diff --git a/bin/varnishtest/tests/v00041.vtc b/bin/varnishtest/tests/v00041.vtc index 2be9f8a..9604eb2 100644 --- a/bin/varnishtest/tests/v00041.vtc +++ b/bin/varnishtest/tests/v00041.vtc @@ -1,4 +1,4 @@ -varnishtest "Test priv_req" +varnishtest "Test priv_task" server s1 { rxreq @@ -9,14 +9,26 @@ server s1 { varnish v1 -vcl+backend { import ${vmod_debug}; + import ${vmod_std}; sub vcl_recv { - set req.http.x0 = debug.test_priv_req(req.url); + set req.http.x0 = debug.test_priv_task(req.url); } sub vcl_deliver { set resp.http.x0 = req.http.x0; - set resp.http.x1 = debug.test_priv_req(""); + set resp.http.x1 = debug.test_priv_task(""); + } + + sub vcl_backend_fetch { + std.log("foo"); + set bereq.http.bx0 = debug.test_priv_task(bereq.url); + std.log("bar"); + } + + sub vcl_backend_response { + set beresp.http.bx0 = bereq.http.bx0; + set beresp.http.bx1 = debug.test_priv_task(""); } } -start @@ -26,9 +38,13 @@ client c1 { rxresp expect resp.http.x0 == /foobar expect resp.http.x1 == /foobar + expect resp.http.bx0 == /foobar + expect resp.http.bx1 == /foobar txreq -url /snafu rxresp expect resp.http.x0 == /snafu expect resp.http.x1 == /snafu + expect resp.http.bx0 == /snafu + expect resp.http.bx1 == /snafu } -run diff --git a/bin/varnishtest/tests/v00042.vtc b/bin/varnishtest/tests/v00042.vtc new file mode 100644 index 0000000..1640f56 --- /dev/null +++ b/bin/varnishtest/tests/v00042.vtc @@ -0,0 +1,68 @@ +varnishtest "Make sure we also get separate PRIV_TASK contexts in ESI subrequests." + +server s1 { + rxreq + expect req.url == "/a" + expect req.http.x0 == "/a0" + expect req.http.x1 == "/a0" + txresp -body { + <html> + <esi:include src="/foo"/> + } + + rxreq + expect req.url == "/foo" + expect req.http.x0 == "/foo1" + expect req.http.x1 == "/foo1" + txresp -body { + <html> + <esi:include src="/bar"/> + } + + rxreq + expect req.url == "/bar" + expect req.http.x0 == "/bar2" + expect req.http.x1 == "/bar2" + txresp + + rxreq + expect req.url == "/b" + expect req.http.x0 == "/b0" + expect req.http.x1 == "/b0" + + txresp +} -start + +varnish v1 -vcl+backend { + import ${vmod_debug}; + + sub vcl_recv { + set req.http.x0 = debug.test_priv_task(req.url + req.esi_level); + } + + sub vcl_miss { + set req.http.x1 = debug.test_priv_task(""); + } + + sub vcl_backend_response { + set beresp.do_esi = true; + + } + + sub vcl_deliver { + set resp.http.x1 = debug.test_priv_task(""); + } +} -start + + +client c1 { + txreq -url /a + rxresp + expect resp.http.x1 == "/a0" + + txreq -url /b + rxresp + expect resp.http.x1 == "/b0" +} -run + +varnish v1 -expect s_req == 2 diff --git a/doc/sphinx/reference/vmod.rst b/doc/sphinx/reference/vmod.rst index 5ad685f..70f287e 100644 --- a/doc/sphinx/reference/vmod.rst +++ b/doc/sphinx/reference/vmod.rst @@ -194,6 +194,9 @@ PRIV_VCL PRIV_CALL See below +PRIV_TASK + See below + VOID C-type: ``void`` @@ -231,8 +234,8 @@ It is often useful for library functions to maintain local state, this can be anything from a precompiled regexp to open file descriptors and vast data structures. -The VCL compiler supports two levels of private pointers, "per call" -and "per VCL" +The VCL compiler supports three levels of private pointers, "per +call", "per VCL" and "per task". "per call" private pointers are useful to cache/store state relative to the specific call or its arguments, for instance a compiled regular @@ -243,9 +246,16 @@ last output of some expensive lookup. applies to all calls in this VCL, for instance flags that determine if regular expressions are case-sensitive in this vmod or similar. +"per task" private pointers are useful for state that applies to calls +for either a specific request or a backend request. For instance this +can be the result of a parsed cookie specific to a client. Note that +"per task" contexts are separate for the client side and the backend +side, so use in ``vcl_backend_*`` will yield a different private pointer +from the one used on the client side. + The way it works in the vmod code, is that a ``struct vmod_priv *`` is -passed to the functions where argument type PRIV_VCL or PRIV_CALL -is specified. +passed to the functions where argument type PRIV_VCL, PRIV_CALL or +PRIV_TASK is specified. This structure contains two members:: diff --git a/include/vrt.h b/include/vrt.h index 78cf479..9331600 100644 --- a/include/vrt.h +++ b/include/vrt.h @@ -246,7 +246,7 @@ struct vmod_priv { typedef int vmod_init_f(struct vmod_priv *, const struct VCL_conf *); void VRT_priv_fini(const struct vmod_priv *p); -struct vmod_priv *VRT_priv_req(VRT_CTX, void *vmod_id); +struct vmod_priv *VRT_priv_task(VRT_CTX, void *vmod_id); /* Stevedore related functions */ int VRT_Stv(const char *nm); diff --git a/lib/libvcc/vcc_expr.c b/lib/libvcc/vcc_expr.c index 72d8386..91c6a06 100644 --- a/lib/libvcc/vcc_expr.c +++ b/lib/libvcc/vcc_expr.c @@ -551,11 +551,11 @@ vcc_priv_arg(struct vcc *tl, const char *p, const char *name) Fh(tl, 0, "static struct vmod_priv %s;\n", buf); VSB_printf(ifp->fin, "\tVRT_priv_fini(&%s);", buf); e2 = vcc_mk_expr(VOID, "&%s", buf); - } else if (!strcmp(p, "PRIV_REQ")) { + } else if (!strcmp(p, "PRIV_TASK")) { r = strchr(name, '.'); AN(r); e2 = vcc_mk_expr(VOID, - "VRT_priv_req(ctx, &VGC_vmod_%.*s)", + "VRT_priv_task(ctx, &VGC_vmod_%.*s)", (int) (r - name), name); } else { WRONG("Wrong PRIV_ type"); diff --git a/lib/libvcc/vmodtool.py b/lib/libvcc/vmodtool.py index ef6ea2c..1501e31 100755 --- a/lib/libvcc/vmodtool.py +++ b/lib/libvcc/vmodtool.py @@ -58,7 +58,7 @@ ctypes = { 'IP': "VCL_IP", 'PRIV_CALL': "struct vmod_priv *", 'PRIV_VCL': "struct vmod_priv *", - 'PRIV_REQ': "struct vmod_priv *", + 'PRIV_TASK': "struct vmod_priv *", 'REAL': "VCL_REAL", 'STRING': "VCL_STRING", 'STRING_LIST': "const char *, ...", diff --git a/lib/libvmod_debug/vmod.vcc b/lib/libvmod_debug/vmod.vcc index 09e6c0b..1684230 100644 --- a/lib/libvmod_debug/vmod.vcc +++ b/lib/libvmod_debug/vmod.vcc @@ -51,9 +51,9 @@ $Function VOID test_priv_vcl(PRIV_VCL) Test function for VCL private pointers -$Function STRING test_priv_req(PRIV_REQ, STRING) +$Function STRING test_priv_task(PRIV_TASK, STRING) -Test function for REQ private pointers +Test function for TASK private pointers $Function BLOB str2blob(STRING src) diff --git a/lib/libvmod_debug/vmod_debug.c b/lib/libvmod_debug/vmod_debug.c index d8077ce..1701444 100644 --- a/lib/libvmod_debug/vmod_debug.c +++ b/lib/libvmod_debug/vmod_debug.c @@ -88,8 +88,8 @@ vmod_test_priv_call(VRT_CTX, struct vmod_priv *priv) } } -VCL_STRING __match_proto__(td_debug_test_priv_req) -vmod_test_priv_req(VRT_CTX, struct vmod_priv *priv, VCL_STRING s) +VCL_STRING __match_proto__(td_debug_test_priv_task) +vmod_test_priv_task(VRT_CTX, struct vmod_priv *priv, VCL_STRING s) { CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); -- 2.1.3
_______________________________________________ varnish-dev mailing list [email protected] https://www.varnish-cache.org/lists/mailman/listinfo/varnish-dev
