Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
libvmod-dispatch
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
1
Issues
1
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-dispatch
Commits
1d3ad7af
Commit
1d3ad7af
authored
Oct 27, 2017
by
Geoff Simmons
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add the sub object.
parent
e7953f51
Pipeline
#355
skipped
Changes
4
Pipelines
1
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
326 additions
and
0 deletions
+326
-0
README.rst
README.rst
+28
-0
sub.vtc
src/tests/sub.vtc
+157
-0
vmod_dispatch.c
src/vmod_dispatch.c
+135
-0
vmod_dispatch.vcc
src/vmod_dispatch.vcc
+6
-0
No files found.
README.rst
View file @
1d3ad7af
...
...
@@ -40,6 +40,7 @@ CONTENTS
========
* label()
* sub()
* STRING version()
.. _obj_label:
...
...
@@ -69,6 +70,33 @@ label.go
VOID label.go(INT)
.. _obj_sub:
sub
---
::
new OBJ = sub()
.. _func_sub.add:
sub.add
-------
::
VOID sub.add(INT n, STRING sub)
.. _func_sub.call:
sub.call
--------
::
VOID sub.call(INT n)
.. _func_version:
version
...
...
src/tests/sub.vtc
0 → 100644
View file @
1d3ad7af
# looks like -*- vcl -*-
varnishtest "sub object"
varnish v1 -arg "-p vcc_err_unref=off" -vcl {
import ${vmod_dispatch};
backend b { .host = "${bad_ip}"; }
sub vcl_init {
new s = dispatch.sub();
s.add(0, "sub1");
s.add(1, "sub2");
}
sub sub1 {
set req.http.Sub = "sub1";
}
sub sub2 {
set req.http.Sub = "sub2";
}
sub vcl_recv {
if (req.url == "/0") {
s.call(0);
}
if (req.url == "/1") {
s.call(1);
}
return(synth(200));
}
sub vcl_synth {
set resp.http.Sub = req.http.Sub;
}
} -start
client c1 {
txreq -url "/0"
rxresp
expect resp.status == 200
expect resp.http.Sub == "sub1"
txreq -url "/1"
rxresp
expect resp.status == 200
expect resp.http.Sub == "sub2"
} -run
varnish v1 -errvcl {vmod dispatch error: s.add(0): subroutine name is empty} {
import ${vmod_dispatch};
backend b { .host = "${bad_ip}"; }
sub vcl_init {
new s = dispatch.sub();
s.add(0, "");
}
}
varnish v1 -errvcl {vmod dispatch error: s.add(-1, foo): n must be >= 0} {
import ${vmod_dispatch};
backend b { .host = "${bad_ip}"; }
sub vcl_init {
new s = dispatch.sub();
s.add(-1, "foo");
}
}
varnish v1 -errvcl {vmod dispatch error: s.add(0, foo): VCL subroutine not found} {
import ${vmod_dispatch};
backend b { .host = "${bad_ip}"; }
sub vcl_init {
new s = dispatch.sub();
s.add(0, "foo");
}
}
varnish v1 -vcl {
import ${vmod_dispatch};
backend b { .host = "${bad_ip}"; }
sub vcl_init {
new s = dispatch.sub();
s.add(0, "sub1");
s.add(2, "sub2");
}
sub vcl_recv {
if (req.url == "/negative") {
s.call(-1);
}
elsif (req.url == "/notset") {
s.call(1);
}
elsif (req.url == "/outofrange") {
s.call(3);
}
elsif (req.url == "/add") {
s.add(1, "sub1");
}
return(synth(200));
}
sub vcl_synth {
set resp.http.Sub = req.http.Sub;
}
sub sub1 {
set req.http.Sub = "sub1";
}
sub sub2 {
set req.http.Sub = "sub2";
}
}
client c1 {
txreq -url "/negative"
rxresp
expect resp.status == 503
expect resp.reason == "VCL failed"
expect resp.http.Sub == ""
} -run
client c1 {
txreq -url "/notset"
rxresp
expect resp.status == 503
expect resp.reason == "VCL failed"
expect resp.http.Sub == ""
} -run
client c1 {
txreq -url "/outofrange"
rxresp
expect resp.status == 503
expect resp.reason == "VCL failed"
expect resp.http.Sub == ""
} -run
client c1 {
txreq -url "/add"
rxresp
expect resp.status == 503
expect resp.reason == "VCL failed"
expect resp.http.Sub == ""
} -run
logexpect l1 -v v1 -d 1 -g vxid -q "VCL_Error" {
expect * * VCL_Error "^vmod dispatch error: s.call.-1.: n must be >= 0$"
expect * * VCL_Error "^vmod dispatch error: s.call.1.: sub 1 was not added$"
expect * * VCL_Error "^vmod dispatch error: s.call.3.: highest sub number is 2"
expect * * VCL_Error "^vmod dispatch error: s.add.1, sub1. may only be called in vcl_init$"
} -start
logexpect l1 -wait
src/vmod_dispatch.c
View file @
1d3ad7af
...
...
@@ -33,6 +33,7 @@
#include <stdlib.h>
#include <string.h>
#include <dlfcn.h>
#include "cache/cache.h"
#include "vcl.h"
...
...
@@ -57,6 +58,22 @@ struct vmod_dispatch_label {
unsigned
nvcls
;
};
struct
vmod_dispatch_sub
{
unsigned
magic
;
#define VMOD_DISPATCH_SUB_MAGIC 0x24a617ec
vcl_func_f
**
func
;
struct
vbitmap
*
bitmap
;
char
*
vcl_name
;
unsigned
nsubs
;
};
struct
vmod_dispatch_vcl
{
unsigned
magic
;
#define VMOD_DISPATCH_VCL_MAGIC 0x214188f2
VTAILQ_ENTRY
(
vcl
)
list
;
void
*
dlh
;
};
static
struct
vrt_ctx
dummy_ctx
=
{
.
magic
=
VRT_CTX_MAGIC
};
VCL_VOID
...
...
@@ -175,6 +192,124 @@ vmod_label_go(VRT_CTX, struct vmod_dispatch_label *label, VCL_INT n)
VRT_handling
(
ctx
,
VCL_RET_VCL
);
}
VCL_VOID
vmod_sub__init
(
VRT_CTX
,
struct
vmod_dispatch_sub
**
subp
,
const
char
*
vcl_name
)
{
struct
vmod_dispatch_sub
*
sub
;
CHECK_OBJ_NOTNULL
(
ctx
,
VRT_CTX_MAGIC
);
AN
(
subp
);
AZ
(
*
subp
);
AN
(
vcl_name
);
ALLOC_OBJ
(
sub
,
VMOD_DISPATCH_SUB_MAGIC
);
AN
(
sub
);
*
subp
=
sub
;
sub
->
bitmap
=
vbit_new
(
INIT_BITS
);
AN
(
sub
->
bitmap
);
sub
->
vcl_name
=
strdup
(
vcl_name
);
AN
(
sub
->
vcl_name
);
AZ
(
sub
->
func
);
AZ
(
sub
->
nsubs
);
}
VCL_VOID
vmod_sub__fini
(
struct
vmod_dispatch_sub
**
subp
)
{
struct
vmod_dispatch_sub
*
sub
;
if
(
subp
==
NULL
||
*
subp
==
NULL
)
return
;
CHECK_OBJ
(
*
subp
,
VMOD_DISPATCH_SUB_MAGIC
);
sub
=
*
subp
;
*
subp
=
NULL
;
if
(
sub
->
func
!=
NULL
)
free
(
sub
->
func
);
if
(
sub
->
bitmap
!=
NULL
)
vbit_destroy
(
sub
->
bitmap
);
if
(
sub
->
vcl_name
!=
NULL
)
free
(
sub
->
vcl_name
);
FREE_OBJ
(
sub
);
}
VCL_VOID
vmod_sub_add
(
VRT_CTX
,
struct
vmod_dispatch_sub
*
sub
,
VCL_INT
n
,
VCL_STRING
subname
)
{
uintptr_t
snap
;
struct
vmod_dispatch_vcl
*
vcl
;
char
*
funcname
;
vcl_func_f
*
vcl_func
;
CHECK_OBJ_NOTNULL
(
ctx
,
VRT_CTX_MAGIC
);
CHECK_OBJ_NOTNULL
(
sub
,
VMOD_DISPATCH_SUB_MAGIC
);
CAST_OBJ_NOTNULL
(
vcl
,
(
void
*
)
ctx
->
vcl
,
VMOD_DISPATCH_VCL_MAGIC
);
if
(
subname
==
NULL
||
*
subname
==
'\0'
)
{
VERR
(
ctx
,
"%s.add(%ld): subroutine name is empty"
,
sub
->
vcl_name
,
n
);
return
;
}
if
((
ctx
->
method
&
VCL_MET_INIT
)
==
0
)
{
VERR
(
ctx
,
"%s.add(%ld, %s) may only be called in vcl_init"
,
sub
->
vcl_name
,
n
,
subname
);
return
;
}
if
(
n
<
0
)
{
VERR
(
ctx
,
"%s.add(%ld, %s): n must be >= 0"
,
sub
->
vcl_name
,
n
,
subname
);
return
;
}
snap
=
WS_Snapshot
(
ctx
->
ws
);
if
((
funcname
=
WS_Printf
(
ctx
->
ws
,
"VGC_function_%s"
,
subname
))
==
NULL
)
{
VERR
(
ctx
,
"%s.add(%ld, %s): insufficient workspace for "
"internal C function name"
,
sub
->
vcl_name
,
n
,
subname
);
return
;
}
vcl_func
=
dlsym
(
vcl
->
dlh
,
funcname
);
WS_Reset
(
ctx
->
ws
,
snap
);
if
(
vcl_func
==
NULL
)
{
VERR
(
ctx
,
"%s.add(%ld, %s): VCL subroutine not found: %s"
,
sub
->
vcl_name
,
n
,
subname
,
dlerror
());
return
;
}
if
(
n
>=
sub
->
nsubs
)
sub
->
nsubs
=
n
+
1
;
if
((
sub
->
func
=
realloc
(
sub
->
func
,
sub
->
nsubs
*
sizeof
(
vcl_func
)))
==
NULL
)
{
VERR
(
ctx
,
"%s.add(%ld, %s): out of memory"
,
sub
->
vcl_name
,
n
,
subname
);
return
;
}
sub
->
func
[
n
]
=
vcl_func
;
vbit_set
(
sub
->
bitmap
,
n
);
}
VCL_VOID
vmod_sub_call
(
VRT_CTX
,
struct
vmod_dispatch_sub
*
sub
,
VCL_INT
n
)
{
CHECK_OBJ_NOTNULL
(
ctx
,
VRT_CTX_MAGIC
);
CHECK_OBJ_NOTNULL
(
sub
,
VMOD_DISPATCH_SUB_MAGIC
);
if
(
n
<
0
)
{
VERR
(
ctx
,
"%s.call(%ld): n must be >= 0"
,
sub
->
vcl_name
,
n
);
return
;
}
if
(
n
>=
sub
->
nsubs
)
{
VERR
(
ctx
,
"%s.call(%ld): highest sub number is %d"
,
sub
->
vcl_name
,
n
,
sub
->
nsubs
-
1
);
return
;
}
if
(
!
vbit_test
(
sub
->
bitmap
,
n
))
{
VERR
(
ctx
,
"%s.call(%ld): sub %ld was not added"
,
sub
->
vcl_name
,
n
,
n
);
return
;
}
AN
(
sub
->
func
[
n
]);
sub
->
func
[
n
](
ctx
);
}
VCL_STRING
vmod_version
(
VRT_CTX
)
{
...
...
src/vmod_dispatch.vcc
View file @
1d3ad7af
...
...
@@ -27,6 +27,12 @@ $Method VOID .add(INT n, STRING label)
$Method VOID .go(INT)
$Object sub()
$Method VOID .add(INT n, STRING sub)
$Method VOID .call(INT n)
$Function STRING version()
Return the version string for this VMOD.
...
...
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