Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
libvmod-hoailona
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
uplex-varnish
libvmod-hoailona
Commits
f2dded65
Commit
f2dded65
authored
Jan 16, 2017
by
Geoff Simmons
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
implement the hosts.explain() method
parent
ae0c7084
Pipeline
#114
skipped
Changes
4
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
287 additions
and
43 deletions
+287
-43
README.rst
README.rst
+29
-19
explain.vtc
src/tests/explain.vtc
+116
-0
vmod_hoailona.c
src/vmod_hoailona.c
+113
-5
vmod_hoailona.vcc
src/vmod_hoailona.vcc
+29
-19
No files found.
README.rst
View file @
f2dded65
...
@@ -225,24 +225,6 @@ subroutines, subsequent calls to ``.token()`` and ``.secret()`` in the
...
@@ -225,24 +225,6 @@ subroutines, subsequent calls to ``.token()`` and ``.secret()`` in the
same backend transaction are based on the policy that was determined
same backend transaction are based on the policy that was determined
by that call.
by that call.
Diagnosis and logging
---------------------
To understand the policy that was determined for a host and path by
the ``.policy()`` method, the ``.explain()`` method can be used to
generate a string that contains:
* The name of the policy object that was determined
* The hostname that matched
* If applicable, the path pattern that matched
The ``.explain()`` method also has task scope, meaning that it refers
to the most recent invocation of ``.policy()`` in the same client or
backend transaction. The string that it returns can then, for example,
be entered into the Varnish log, or assigned to a debugging header.
XXX: ``.explain()`` is not implemented yet.
CONTENTS
CONTENTS
========
========
...
@@ -617,6 +599,7 @@ Examples::
...
@@ -617,6 +599,7 @@ Examples::
# a query string or cookie contents, as required for
# a query string or cookie contents, as required for
# authorization at the Akamai server (for example by
# authorization at the Akamai server (for example by
# constructing a redirect response in VCL).
# constructing a redirect response in VCL).
}
}
}
.. _func_hosts.explain:
.. _func_hosts.explain:
...
@@ -628,7 +611,34 @@ hosts.explain
...
@@ -628,7 +611,34 @@ hosts.explain
STRING hosts.explain(PRIV_TASK)
STRING hosts.explain(PRIV_TASK)
**XXX NOT IMPLEMENTED YET**
Returns a string describing the policy that was determined for a host
and path by the most recent invocation of ``.policy()`` in the current
task scope (client or backend context), suitable for diagnosis or
logging. The returned string contains:
* The name of the policy object that was determined
* The hostname that matched
* If applicable, the path pattern that matched
If description strings were provided in the declaration of the policy
and/or in the ``.add()`` method call that assigned the policy, then
these are included in the string.
The ``.explain()`` method MAY NOT be called in ``vcl_init``; if it is,
then the VCL load fails. If ``.policy()`` was not called previously in
the current task scope, then an error message is emitted to the
Varnish log with the ``VCL_Error`` tag, and the method returns NULL.
Example::
import std;
sub vcl_recv {
if (config.policy(req.http.Host, req.url) == 2) {
# [...]
}
std.log("Policy determination: " + config.explain());
}
.. _func_version:
.. _func_version:
...
...
src/tests/explain.vtc
0 → 100644
View file @
f2dded65
# looks like -*- vcl -*-
varnishtest "hosts.explain()"
varnish v1 -vcl {
import hoailona from "${vmod_topbuild}/src/.libs/libvmod_hoailona.so";
backend b { .host = "${bad_ip}"; }
sub vcl_init {
new p1 = hoailona.policy(TOKEN, 1h);
new p2 = hoailona.policy(OPEN, 1h, description="open");
new h = hoailona.hosts();
h.add("example.com", "p1");
h.add("example.org", "p2");
h.add("*.example.com", "p1", "/foo/...");
h.add("*.example.org", "p2", "/bar/...");
h.add("example.net", "p1", description="net");
h.add("example.edu", "p2", description="edu");
h.add("*.example.net", "p1", "/baz/...", description="sub net");
h.add("*.example.edu", "p2", "/baz/...", description="sub edu");
}
sub vcl_recv {
return(synth(200));
}
sub vcl_synth {
set resp.http.p1 = h.policy("example.com", "/foo/bar");
set resp.http.e1 = h.explain();
set resp.http.p2 = h.policy("example.org", "/foo/bar");
set resp.http.e2 = h.explain();
set resp.http.p3 = h.policy("foo.example.com", "/foo/bar");
set resp.http.e3 = h.explain();
set resp.http.p4 = h.policy("foo.example.org", "/bar/baz");
set resp.http.e4 = h.explain();
set resp.http.p5 = h.policy("example.net", "/foo/bar");
set resp.http.e5 = h.explain();
set resp.http.p6 = h.policy("example.edu", "/foo/bar");
set resp.http.e6 = h.explain();
set resp.http.p7 = h.policy("foo.example.net", "/baz/quux");
set resp.http.e7 = h.explain();
set resp.http.p8 = h.policy("foo.example.edu", "/baz/quux");
set resp.http.e8 = h.explain();
set resp.http.p9 = h.policy("foo.example.com", "/baz/quux");
set resp.http.e9 = h.explain();
}
} -start
client c1 {
txreq
rxresp
expect resp.status == 200
expect resp.http.p1 == "2"
expect resp.http.e1 == "Matched host example.com for global policy p1"
expect resp.http.p2 == "1"
expect resp.http.e2 == "Matched host example.org for global policy p2 (open)"
expect resp.http.p3 == "2"
expect resp.http.e3 == "Matched host *.example.com and pattern /foo/... for policy p1"
expect resp.http.p4 == "1"
expect resp.http.e4 == "Matched host *.example.org and pattern /bar/... for policy p2 (open)"
expect resp.http.p5 == "2"
expect resp.http.e5 == "Matched host example.net (net) for global policy p1"
expect resp.http.p6 == "1"
expect resp.http.e6 == "Matched host example.edu (edu) for global policy p2 (open)"
expect resp.http.p7 == "2"
expect resp.http.e7 == "Matched host *.example.net and pattern /baz/... (sub net) for policy p1"
expect resp.http.p8 == "1"
expect resp.http.e8 == "Matched host *.example.edu and pattern /baz/... (sub edu) for policy p2 (open)"
expect resp.http.p9 == "-1"
expect resp.http.e9 == "No policy was matched"
} -run
varnish v1 -errvcl {h.explain() may not be called in vcl_init} {
import hoailona from "${vmod_topbuild}/src/.libs/libvmod_hoailona.so";
backend b { .host = "${bad_ip}"; }
sub vcl_init {
new p = hoailona.policy(TOKEN, 1h);
new h = hoailona.hosts();
if (h.explain() ~ ".") {
return(fail);
}
}
}
varnish v1 -vcl {
import hoailona from "${vmod_topbuild}/src/.libs/libvmod_hoailona.so";
backend b { .host = "${bad_ip}"; }
sub vcl_init {
new p = hoailona.policy(TOKEN, 1h);
new h = hoailona.hosts();
h.add("example.com", "p");
}
sub vcl_recv {
return(synth(200));
}
sub vcl_synth {
set resp.http.e1 = h.explain();
}
}
client c1 {
txreq
rxresp
expect resp.status == 200
expect resp.http.e1 == ""
} -run
logexpect l1 -v v1 -d 1 -g vxid -q "VCL_Error" {
expect 0 * Begin req
expect * = VCL_Error "^vmod hoailona error: h.explain.. called before h.policy..$"
expect * = End
} -run
src/vmod_hoailona.c
View file @
f2dded65
...
@@ -694,13 +694,121 @@ vmod_hosts_secret(VRT_CTX, struct vmod_hoailona_hosts *hosts,
...
@@ -694,13 +694,121 @@ vmod_hosts_secret(VRT_CTX, struct vmod_hoailona_hosts *hosts,
VCL_STRING
VCL_STRING
vmod_hosts_explain
(
VRT_CTX
,
struct
vmod_hoailona_hosts
*
hosts
,
vmod_hosts_explain
(
VRT_CTX
,
struct
vmod_hoailona_hosts
*
hosts
,
struct
vmod_priv
*
task
)
struct
vmod_priv
*
priv_
task
)
{
{
(
void
)
ctx
;
struct
policy_task
*
task
;
(
void
)
hosts
;
struct
host
*
host
;
(
void
)
task
;
struct
vmod_hoailona_policy
*
policy
;
char
*
ret
=
NULL
;
CHECK_OBJ_NOTNULL
(
ctx
,
VRT_CTX_MAGIC
);
CHECK_OBJ_NOTNULL
(
ctx
->
ws
,
WS_MAGIC
);
CHECK_OBJ_NOTNULL
(
hosts
,
VMOD_HOAILONA_HOSTS_MAGIC
);
AN
(
priv_task
);
if
(
INIT
(
ctx
))
{
VERR
(
ctx
,
"%s.explain() may not be called in vcl_init"
,
hosts
->
vcl_name
);
return
NULL
;
}
if
(
priv_task
->
priv
==
NULL
)
{
VERR
(
ctx
,
"%s.explain() called before %s.policy()"
,
hosts
->
vcl_name
,
hosts
->
vcl_name
);
return
NULL
;
}
WS_Contains
(
ctx
->
ws
,
priv_task
->
priv
,
sizeof
(
struct
policy_task
));
CAST_OBJ
(
task
,
priv_task
->
priv
,
VMOD_HOAILONA_POLICY_TASK_MAGIC
);
host
=
task
->
host
;
if
(
task
->
policy
!=
NULL
)
{
CHECK_OBJ_NOTNULL
(
host
,
VMOD_HOAILONA_HOST_MAGIC
);
AN
(
host
->
name
);
CHECK_OBJ
(
task
->
policy
,
VMOD_HOAILONA_POLICY_MAGIC
);
AN
(
task
->
policy
->
vcl_name
);
policy
=
task
->
policy
;
if
(
policy
->
description
!=
NULL
)
{
if
(
host
->
description
!=
NULL
)
ret
=
WS_Printf
(
ctx
->
ws
,
"Matched host %s (%s) "
"for global policy %s (%s)"
,
host
->
name
,
host
->
description
,
policy
->
vcl_name
,
policy
->
description
);
else
ret
=
WS_Printf
(
ctx
->
ws
,
"Matched host %s "
"for global policy %s (%s)"
,
host
->
name
,
policy
->
vcl_name
,
policy
->
description
);
}
else
{
if
(
host
->
description
!=
NULL
)
ret
=
WS_Printf
(
ctx
->
ws
,
"Matched host %s (%s) "
"for global policy %s"
,
host
->
name
,
host
->
description
,
policy
->
vcl_name
);
else
ret
=
WS_Printf
(
ctx
->
ws
,
"Matched host %s "
"for global policy %s"
,
host
->
name
,
policy
->
vcl_name
);
}
}
else
if
(
task
->
assignment
!=
NULL
)
{
struct
assignment
*
a
;
CHECK_OBJ_NOTNULL
(
host
,
VMOD_HOAILONA_HOST_MAGIC
);
AN
(
host
->
name
);
CHECK_OBJ_NOTNULL
(
task
->
assignment
,
VMOD_HOAILONA_ASSIGNMENT_MAGIC
);
CHECK_OBJ_NOTNULL
(
task
->
assignment
->
policy
,
VMOD_HOAILONA_POLICY_MAGIC
);
CHECK_OBJ_NOTNULL
(
task
->
assignment
->
pattern
,
VMOD_HOAILONA_PATTERN_MAGIC
);
AN
(
task
->
assignment
->
policy
->
vcl_name
);
AN
(
task
->
assignment
->
pattern
->
path
);
AZ
(
host
->
description
);
a
=
task
->
assignment
;
policy
=
a
->
policy
;
if
(
policy
->
description
!=
NULL
)
{
if
(
a
->
description
!=
NULL
)
ret
=
WS_Printf
(
ctx
->
ws
,
"Matched host %s "
"and pattern %s (%s) "
"for policy %s (%s)"
,
host
->
name
,
a
->
pattern
->
path
,
a
->
description
,
policy
->
vcl_name
,
policy
->
description
);
else
ret
=
WS_Printf
(
ctx
->
ws
,
"Matched host %s "
"and pattern %s "
"for policy %s (%s)"
,
host
->
name
,
a
->
pattern
->
path
,
policy
->
vcl_name
,
policy
->
description
);
}
else
{
if
(
a
->
description
!=
NULL
)
ret
=
WS_Printf
(
ctx
->
ws
,
"Matched host %s "
"and pattern %s (%s) "
"for policy %s"
,
host
->
name
,
a
->
pattern
->
path
,
a
->
description
,
policy
->
vcl_name
);
else
ret
=
WS_Printf
(
ctx
->
ws
,
"Matched host %s "
"and pattern %s "
"for policy %s"
,
host
->
name
,
a
->
pattern
->
path
,
policy
->
vcl_name
);
}
}
else
ret
=
WS_Printf
(
ctx
->
ws
,
"%s"
,
"No policy was matched"
);
return
NULL
;
if
(
ret
==
NULL
)
VERRNOMEM
(
ctx
,
"in %s.explain()"
,
hosts
->
vcl_name
);
return
ret
;
}
}
/* Functions */
/* Functions */
...
...
src/vmod_hoailona.vcc
View file @
f2dded65
...
@@ -208,24 +208,6 @@ subroutines, subsequent calls to ``.token()`` and ``.secret()`` in the
...
@@ -208,24 +208,6 @@ subroutines, subsequent calls to ``.token()`` and ``.secret()`` in the
same backend transaction are based on the policy that was determined
same backend transaction are based on the policy that was determined
by that call.
by that call.
Diagnosis and logging
---------------------
To understand the policy that was determined for a host and path by
the ``.policy()`` method, the ``.explain()`` method can be used to
generate a string that contains:
* The name of the policy object that was determined
* The hostname that matched
* If applicable, the path pattern that matched
The ``.explain()`` method also has task scope, meaning that it refers
to the most recent invocation of ``.policy()`` in the same client or
backend transaction. The string that it returns can then, for example,
be entered into the Varnish log, or assigned to a debugging header.
XXX: ``.explain()`` is not implemented yet.
$Object policy(PRIV_TASK, ENUM {OPEN, DENY, TOKEN} type, DURATION ttl,
$Object policy(PRIV_TASK, ENUM {OPEN, DENY, TOKEN} type, DURATION ttl,
STRING description=0, BLOB secret=0, INT start_offset=0)
STRING description=0, BLOB secret=0, INT start_offset=0)
...
@@ -553,11 +535,39 @@ Examples::
...
@@ -553,11 +535,39 @@ Examples::
# a query string or cookie contents, as required for
# a query string or cookie contents, as required for
# authorization at the Akamai server (for example by
# authorization at the Akamai server (for example by
# constructing a redirect response in VCL).
# constructing a redirect response in VCL).
}
}
}
$Method STRING .explain(PRIV_TASK)
$Method STRING .explain(PRIV_TASK)
**XXX NOT IMPLEMENTED YET**
Returns a string describing the policy that was determined for a host
and path by the most recent invocation of ``.policy()`` in the current
task scope (client or backend context), suitable for diagnosis or
logging. The returned string contains:
* The name of the policy object that was determined
* The hostname that matched
* If applicable, the path pattern that matched
If description strings were provided in the declaration of the policy
and/or in the ``.add()`` method call that assigned the policy, then
these are included in the string.
The ``.explain()`` method MAY NOT be called in ``vcl_init``; if it is,
then the VCL load fails. If ``.policy()`` was not called previously in
the current task scope, then an error message is emitted to the
Varnish log with the ``VCL_Error`` tag, and the method returns NULL.
Example::
import std;
sub vcl_recv {
if (config.policy(req.http.Host, req.url) == 2) {
# [...]
}
std.log("Policy determination: " + config.explain());
}
$Function STRING version()
$Function STRING version()
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment