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
f0654041
Commit
f0654041
authored
Oct 24, 2017
by
Geoff Simmons
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add the label object.
parent
35775ec4
Pipeline
#353
skipped
Changes
4
Pipelines
1
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
321 additions
and
1 deletion
+321
-1
README.rst
README.rst
+28
-0
label.vtc
src/tests/label.vtc
+145
-0
vmod_dispatch.c
src/vmod_dispatch.c
+142
-1
vmod_dispatch.vcc
src/vmod_dispatch.vcc
+6
-0
No files found.
README.rst
View file @
f0654041
...
...
@@ -39,8 +39,36 @@ Varnish Module (VMOD) for dispatching control to VCL labels or subroutines.
CONTENTS
========
* label()
* STRING version()
.. _obj_label:
label
-----
::
new OBJ = label()
.. _func_label.add:
label.add
---------
::
VOID label.add(INT n, STRING label)
.. _func_label.go:
label.go
--------
::
VOID label.go(INT)
.. _func_version:
version
...
...
src/tests/label.vtc
0 → 100644
View file @
f0654041
# looks like -*- vcl -*-
varnishtest "label object"
varnish v1 -vcl {
backend b { .host = "${bad_ip}"; }
sub vcl_recv {
set req.http.VCL = "1";
return(synth(200));
}
sub vcl_synth {
set resp.http.VCL = req.http.VCL;
return(deliver);
}
} -start
varnish v1 -vcl {
backend b { .host = "${bad_ip}"; }
sub vcl_recv {
set req.http.VCL = "2";
return(synth(200));
}
sub vcl_synth {
set resp.http.VCL = req.http.VCL;
return(deliver);
}
}
varnish v1 -cliok "vcl.label VCL1 vcl1"
varnish v1 -cliok "vcl.label VCL2 vcl2"
varnish v1 -vcl {
import ${vmod_dispatch};
backend b { .host = "${bad_ip}"; }
sub vcl_init {
new l = dispatch.label();
l.add(0, "VCL1");
l.add(1, "VCL2");
}
sub vcl_recv {
if (req.url == "/0") {
l.go(0);
}
if (req.url == "/1") {
l.go(1);
}
}
}
client c1 {
txreq -url "/0"
rxresp
expect resp.status == 200
expect resp.http.VCL == "1"
txreq -url "/1"
rxresp
expect resp.status == 200
expect resp.http.VCL == "2"
} -run
varnish v1 -cliok "vcl.list"
varnish v1 -errvcl {vmod dispatch error: l.add(-1, VCL1): n must be >= 0} {
import ${vmod_dispatch};
backend b { .host = "${bad_ip}"; }
sub vcl_init {
new l = dispatch.label();
l.add(-1, "VCL1");
}
}
varnish v1 -vcl {
import ${vmod_dispatch};
backend b { .host = "${bad_ip}"; }
sub vcl_init {
new l = dispatch.label();
l.add(0, "VCL1");
l.add(2, "VCL2");
}
sub vcl_recv {
if (req.url == "/negative") {
l.go(-1);
}
elsif (req.url == "/notset") {
l.go(1);
}
elsif (req.url == "/outofrange") {
l.go(3);
}
}
sub vcl_backend_fetch {
l.go(0);
}
}
client c1 {
txreq -url "/negative"
rxresp
expect resp.status == 503
expect resp.reason == "VCL failed"
expect resp.http.VCL == <undef>
} -run
client c1 {
txreq -url "/notset"
rxresp
expect resp.status == 503
expect resp.reason == "VCL failed"
expect resp.http.VCL == <undef>
} -run
client c1 {
txreq -url "/outofrange"
rxresp
expect resp.status == 503
expect resp.reason == "VCL failed"
expect resp.http.VCL == <undef>
} -run
client c1 {
txreq
rxresp
expect resp.status == 503
expect resp.reason == "Service Unavailable"
expect resp.http.VCL == <undef>
} -run
logexpect l1 -v v1 -d 1 -g vxid -q "VCL_Error" {
expect * * VCL_Error "^vmod dispatch error: l.go.-1.: n must be >= 0$"
expect * * VCL_Error "^vmod dispatch error: l.go.1.: label 1 was not added$"
expect * * VCL_Error "^vmod dispatch error: l.go.3.: highest label number is 2"
expect * * VCL_Error "^vmod dispatch error: l.go.0.: may only be called in client context, not in any vcl_backend_. subroutine$"
} -start
logexpect l1 -wait
src/vmod_dispatch.c
View file @
f0654041
...
...
@@ -26,12 +26,153 @@
* SUCH DAMAGE.
*/
/* for strdup() */
#define _POSIX_C_SOURCE 200809L
#include "config.h"
#include <stdlib.h>
#include <string.h>
#include "cache/cache.h"
#include "vcl.h"
#include "vbm.h"
#include "vcc_if.h"
#define ERR(ctx, msg) \
VRT_fail((ctx), "vmod dispatch error: " msg)
#define VERR(ctx, fmt, ...) \
VRT_fail((ctx), "vmod dispatch error: " fmt, __VA_ARGS__)
#define INIT_BITS (64)
struct
vmod_dispatch_label
{
unsigned
magic
;
#define VMOD_DISPATCH_LABEL_MAGIC 0x44515cd0
VCL_VCL
*
vcl
;
struct
vbitmap
*
bitmap
;
char
*
vcl_name
;
unsigned
nvcls
;
};
static
struct
vrt_ctx
dummy_ctx
=
{
.
magic
=
VRT_CTX_MAGIC
};
VCL_VOID
vmod_label__init
(
VRT_CTX
,
struct
vmod_dispatch_label
**
labelp
,
const
char
*
vcl_name
)
{
struct
vmod_dispatch_label
*
label
;
CHECK_OBJ_NOTNULL
(
ctx
,
VRT_CTX_MAGIC
);
AN
(
labelp
);
AZ
(
*
labelp
);
AN
(
vcl_name
);
ALLOC_OBJ
(
label
,
VMOD_DISPATCH_LABEL_MAGIC
);
AN
(
label
);
*
labelp
=
label
;
label
->
bitmap
=
vbit_new
(
INIT_BITS
);
AN
(
label
->
bitmap
);
label
->
vcl_name
=
strdup
(
vcl_name
);
AN
(
label
->
vcl_name
);
AZ
(
label
->
vcl
);
AZ
(
label
->
nvcls
);
}
VCL_VOID
vmod_label__fini
(
struct
vmod_dispatch_label
**
labelp
)
{
struct
vmod_dispatch_label
*
label
;
if
(
labelp
==
NULL
||
*
labelp
==
NULL
)
return
;
CHECK_OBJ
(
*
labelp
,
VMOD_DISPATCH_LABEL_MAGIC
);
label
=
*
labelp
;
*
labelp
=
NULL
;
for
(
unsigned
i
=
0
;
i
<
label
->
nvcls
;
i
++
)
if
(
vbit_test
(
label
->
bitmap
,
i
)
&&
label
->
vcl
[
i
]
!=
NULL
)
VRT_vcl_rel
(
&
dummy_ctx
,
label
->
vcl
[
i
]);
if
(
label
->
bitmap
!=
NULL
)
vbit_destroy
(
label
->
bitmap
);
if
(
label
->
vcl_name
!=
NULL
)
free
(
label
->
vcl_name
);
FREE_OBJ
(
label
);
}
VCL_VOID
vmod_label_add
(
VRT_CTX
,
struct
vmod_dispatch_label
*
label
,
VCL_INT
n
,
VCL_STRING
label_name
)
{
VCL_VCL
vcl
;
CHECK_OBJ_NOTNULL
(
ctx
,
VRT_CTX_MAGIC
);
CHECK_OBJ_NOTNULL
(
label
,
VMOD_DISPATCH_LABEL_MAGIC
);
if
((
ctx
->
method
&
VCL_MET_INIT
)
==
0
)
{
VERR
(
ctx
,
"%s.add(%ld, %s) may only be called in vcl_init"
,
label
->
vcl_name
,
n
,
label_name
);
return
;
}
if
(
n
<
0
)
{
VERR
(
ctx
,
"%s.add(%ld, %s): n must be >= 0"
,
label
->
vcl_name
,
n
,
label_name
);
return
;
}
if
((
vcl
=
VRT_vcl_get
(
ctx
,
label_name
))
==
NULL
)
{
/*
* XXX: currently doesn't work, VRT_vcl_get() internally
* has AN(vcl);
*/
VERR
(
ctx
,
"%s.add(%ld, %s): unknown label"
,
label
->
vcl_name
,
n
,
label_name
);
return
;
}
if
(
n
>=
label
->
nvcls
)
label
->
nvcls
=
n
+
1
;
label
->
vcl
=
realloc
(
label
->
vcl
,
label
->
nvcls
*
sizeof
(
vcl
));
if
(
label
->
vcl
==
NULL
)
{
VERR
(
ctx
,
"%s.add(%ld, %s): out of memory"
,
label
->
vcl_name
,
n
,
label_name
);
return
;
}
label
->
vcl
[
n
]
=
vcl
;
vbit_set
(
label
->
bitmap
,
n
);
}
VCL_VOID
vmod_label_go
(
VRT_CTX
,
struct
vmod_dispatch_label
*
label
,
VCL_INT
n
)
{
CHECK_OBJ_NOTNULL
(
ctx
,
VRT_CTX_MAGIC
);
CHECK_OBJ_NOTNULL
(
label
,
VMOD_DISPATCH_LABEL_MAGIC
);
if
(
ctx
->
req
==
NULL
)
{
VERR
(
ctx
,
"%s.go(%ld): may only be called in client context, "
"not in any vcl_backend_* subroutine"
,
label
->
vcl_name
,
n
);
return
;
}
if
(
n
<
0
)
{
VERR
(
ctx
,
"%s.go(%ld): n must be >= 0"
,
label
->
vcl_name
,
n
);
return
;
}
if
(
n
>=
label
->
nvcls
)
{
VERR
(
ctx
,
"%s.go(%ld): highest label number is %d"
,
label
->
vcl_name
,
n
,
label
->
nvcls
-
1
);
return
;
}
if
(
!
vbit_test
(
label
->
bitmap
,
n
))
{
VERR
(
ctx
,
"%s.go(%ld): label %ld was not added"
,
label
->
vcl_name
,
n
,
n
);
return
;
}
VRT_vcl_select
(
ctx
,
label
->
vcl
[
n
]);
VRT_handling
(
ctx
,
VCL_RET_VCL
);
}
VCL_STRING
vmod_version
(
const
struct
vrt_ctx
*
ctx
)
vmod_version
(
VRT_CTX
)
{
(
void
)
ctx
;
return
VERSION
;
...
...
src/vmod_dispatch.vcc
View file @
f0654041
...
...
@@ -21,6 +21,12 @@ Varnish Module (VMOD) for dispatching control to VCL labels or subroutines.
... XXX ...
$Object label()
$Method VOID .add(INT n, STRING label)
$Method VOID .go(INT)
$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