Commit aacdd6de authored by Nils Goroll's avatar Nils Goroll

Add PRIV_TOP for per "top request" / req->top state

parent 43135bde
......@@ -122,6 +122,22 @@ VRT_priv_task(VRT_CTX, void *vmod_id)
return (VRT_priv_dynamic(ctx, id, (uintptr_t)vmod_id));
}
struct vmod_priv *
VRT_priv_top(VRT_CTX, void *vmod_id)
{
uintptr_t id;
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
if (ctx->req) {
CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
CHECK_OBJ_NOTNULL(ctx->req->top, REQ_MAGIC);
id = (uintptr_t)&ctx->req->top->top;
} else {
return NULL;
}
return (VRT_priv_dynamic(ctx, id, (uintptr_t)vmod_id));
}
/*--------------------------------------------------------------------
*/
......
......@@ -160,6 +160,7 @@ http1_cleanup(struct sess *sp, struct worker *wrk, struct req *req)
req->restarts = 0;
AZ(req->esi_level);
assert(req->top == req);
if (req->vcl != NULL) {
if (wrk->vcl != NULL)
......@@ -169,6 +170,8 @@ http1_cleanup(struct sess *sp, struct worker *wrk, struct req *req)
}
VRTPRIV_dynamic_kill(sp->privs, (uintptr_t)req);
VRTPRIV_dynamic_kill(sp->privs, (uintptr_t)&req->top);
/* Charge and log byte counters */
AN(req->vsl->wid);
CNT_AcctLogCharge(wrk->stats, req);
......
varnishtest "Test PRIV_TOP"
# same as v00042.vtc, but the priv remains the same across esi includes
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 == "/a0"
expect req.http.x1 == "/a0"
txresp -body {
<html>
<esi:include src="/bar"/>
}
rxreq
expect req.url == "/bar"
expect req.http.x0 == "/a0"
expect req.http.x1 == "/a0"
txresp
rxreq
expect req.url == "/b"
expect req.http.x0 == "/b0"
expect req.http.x1 == "/b0"
txresp
} -start
varnish v1 -cliok "param.set debug +syncvsl" -vcl+backend {
import ${vmod_debug};
sub vcl_recv {
set req.http.x0 = debug.test_priv_top(req.url + req.esi_level);
}
sub vcl_miss {
set req.http.x1 = debug.test_priv_top("");
}
sub vcl_backend_response {
set beresp.do_esi = true;
}
sub vcl_deliver {
set resp.http.x1 = debug.test_priv_top("");
}
} -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
......@@ -197,6 +197,9 @@ PRIV_CALL
PRIV_TASK
See below
PRIV_TOP
See below
VOID
C-type: ``void``
......@@ -254,6 +257,11 @@ The VCL compiler supports the following private pointers:
``vcl_backend_*`` will yield a different private pointer from the
one used on the client side.
* ``PRIV_TOP`` "per top-request" private pointers live for the
duration of one request and all its ESI-includes. They are only
defined for the client side. When used from backend VCL subs, a NULL
pointer will be passed.
The way it works in the vmod code, is that a ``struct vmod_priv *`` is
passed to the functions where one of the ``PRIV_*`` argument types is
specified.
......
......@@ -259,6 +259,7 @@ 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_task(VRT_CTX, void *vmod_id);
struct vmod_priv *VRT_priv_top(VRT_CTX, void *vmod_id);
/* Stevedore related functions */
int VRT_Stv(const char *nm);
......
......@@ -557,6 +557,12 @@ vcc_priv_arg(struct vcc *tl, const char *p, const char *name)
e2 = vcc_mk_expr(VOID,
"VRT_priv_task(ctx, &VGC_vmod_%.*s)",
(int) (r - name), name);
} else if (!strcmp(p, "PRIV_TOP")) {
r = strchr(name, '.');
AN(r);
e2 = vcc_mk_expr(VOID,
"VRT_priv_top(ctx, &VGC_vmod_%.*s)",
(int) (r - name), name);
} else {
WRONG("Wrong PRIV_ type");
}
......
......@@ -59,6 +59,7 @@ ctypes = {
'PRIV_CALL': "struct vmod_priv *",
'PRIV_VCL': "struct vmod_priv *",
'PRIV_TASK': "struct vmod_priv *",
'PRIV_TOP': "struct vmod_priv *",
'REAL': "VCL_REAL",
'STRING': "VCL_STRING",
'STRING_LIST': "const char *, ...",
......
......@@ -55,6 +55,10 @@ $Function STRING test_priv_task(PRIV_TASK, STRING)
Test function for TASK private pointers
$Function STRING test_priv_top(PRIV_TOP, STRING)
Test function for TOP private pointers
$Function BLOB str2blob(STRING src="foo")
Turn a string into a blob
......
......@@ -97,6 +97,18 @@ vmod_test_priv_task(VRT_CTX, struct vmod_priv *priv, VCL_STRING s)
return (priv->priv);
}
VCL_STRING __match_proto__(td_debug_test_priv_top)
vmod_test_priv_top(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_VOID __match_proto__(td_debug_test_priv_vcl)
vmod_test_priv_vcl(VRT_CTX, struct vmod_priv *priv)
{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment