Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
libvmod-blob
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-blob
Commits
ba187152
Commit
ba187152
authored
May 23, 2017
by
Geoff Simmons
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add the integer() function.
parent
55575021
Pipeline
#218
skipped
Changes
4
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
241 additions
and
29 deletions
+241
-29
README.rst
README.rst
+40
-14
01blob.vtc
src/tests/01blob.vtc
+118
-0
vmod_blob.c
src/vmod_blob.c
+51
-1
vmod_blob.vcc
src/vmod_blob.vcc
+32
-14
No files found.
README.rst
View file @
ba187152
...
...
@@ -30,6 +30,7 @@ CONTENTS
* BOOL same(BLOB, BLOB)
* BOOL equal(BLOB, BLOB)
* INT length(BLOB)
* INT integer(BLOB, ENUM {LPAD,RPAD})
* STRING version()
.. _func_same:
...
...
@@ -41,10 +42,8 @@ same
BOOL same(BLOB, BLOB)
Description
Returns true if and only if the two BLOB arguments are the
same object, i.e. they specify exactly the same region of
memory.
Returns true if and only if the two BLOB arguments are the same
object, i.e. they specify exactly the same region of memory.
.. _func_equal:
...
...
@@ -55,9 +54,8 @@ equal
BOOL equal(BLOB, BLOB)
Description
Returns true if and only if the two BLOB arguments have equal
contents (possibly in different memory regions).
Returns true if and only if the two BLOB arguments have equal contents
(possibly in different memory regions).
.. _func_length:
...
...
@@ -68,8 +66,36 @@ length
INT length(BLOB)
Description
Returns the length of the BLOB.
Returns the length of the BLOB.
.. _func_integer:
integer
-------
::
INT integer(BLOB, ENUM {LPAD,RPAD} padding="LPAD")
Returns the initial bytes of the BLOB as an integer.
If the BLOB has fewer bytes than the size of an INT, then the return
value is padded with zeroes to the left if ``padding`` is ``LPAD``, or
to the right if ``padding`` is ``RPAD``. That is, when ``padding`` is
``RPAD``, then the initial bytes of the BLOB are bit-shifted to the
left so that the size of an INT is filled. ``padding`` is ``LPAD`` by
default.
The value of the returned integer results from the bytes from the BLOB
in ascending order of addresses interpreted according to the
endianness of the system on which Varnish is running.
If the length of the BLOB is 0, then ``integer()`` returns 0 and emits
an error message to the Varnish log using the ``VCL_Error`` tag. If
this happens when ``integer()`` is called in ``vcl_init``, then the
VCL load fails with the error message. If it happens in any other VCL
subroutine, then VCL processing continues. Since 0 can be a legitimate
return value, you should monitor the Varnish log for the error.
.. _func_version:
...
...
@@ -80,18 +106,18 @@ version
STRING version()
Description
Returns the version string for this VMOD.
Returns the version string for this VMOD.
Example::
Example
std.log("Using VMOD blob version " + blob.version());
std.log("Using VMOD blob version " + blob.version());
COPYRIGHT
=========
::
Copyright (c) 2016 UPLEX Nils Goroll Systemoptimierung
Copyright (c) 2016
-2017
UPLEX Nils Goroll Systemoptimierung
All rights reserved
Author: Geoffrey Simmons <geoffrey.simmons@uplex.de>
...
...
src/tests/01blob.vtc
View file @
ba187152
...
...
@@ -123,6 +123,9 @@ varnish v1 -vcl {
set resp.http.empty1len = blob.length(empty1.get());
set resp.http.empty2len = blob.length(empty2.get());
set resp.http.fooint = blob.integer(foo1.get());
set resp.http.hobbesint = blob.integer(hobbes1.get());
set resp.http.emptyint = blob.integer(empty1.get());
return(deliver);
}
} -start
...
...
@@ -170,3 +173,118 @@ client c1 {
expect resp.http.empty1len == "0"
expect resp.http.empty2len == "0"
} -run
# integer()
varnish v1 -vcl {
import blob from "${vmod_topbuild}/src/.libs/libvmod_blob.so";
import blobcode;
backend b { .host = "${bad_ip}"; }
sub vcl_init {
# Byte values 7 to 0 in descending order
# $ printf "\x7\x6\x5\x4\x3\x2\x1\x0" | base64
new down07 = blobcode.blob(BASE64, "BwYFBAMCAQA=");
# Byte values 0 to 7 in ascending order
# $ printf "\x0\x1\x2\x3\x4\x5\x6\x7" | base64
new up07 = blobcode.blob(BASE64, "AAECAwQFBgc=");
# Byte values f down to 0
new down0f = blobcode.blob(BASE64, "Dw4NDAsKCQgHBgUEAwIBAA==");
# Byte values 0 up to f
new up0f = blobcode.blob(BASE64, "AAECAwQFBgcICQoLDA0ODw==");
# Byte values 3 down to 0
new down03 = blobcode.blob(BASE64, "AwIBAA==");
# Byte values 0 up to 3
new up03 = blobcode.blob(BASE64, "AAECAw==");
# 16 x 0xff
new minusone = blobcode.blob(BASE64, "//////////8=");
# Byte value 0x7f
new onebyte = blobcode.blob(BASE64, "fw==");
# Byte values 2 down to 0
new down02 = blobcode.blob(BASE64, "AgEA");
# Byte values 0 up to 2
new up02 = blobcode.blob(BASE64, "AAEC");
new empty = blobcode.blob(IDENTITY, "");
}
sub vcl_recv {
return(synth(200));
}
sub vcl_synth {
set resp.http.down07 = blob.integer(down07.get());
set resp.http.up07 = blob.integer(up07.get());
set resp.http.down0f = blob.integer(down0f.get());
set resp.http.up0f = blob.integer(up0f.get());
set resp.http.down03 = blob.integer(down03.get());
set resp.http.up03 = blob.integer(up03.get());
set resp.http.minusone = blob.integer(minusone.get());
set resp.http.onebyte = blob.integer(onebyte.get());
set resp.http.onebyterpad = blob.integer(onebyte.get(), RPAD);
set resp.http.down0frpad = blob.integer(down0f.get(), RPAD);
set resp.http.up0frpad = blob.integer(up0f.get(), RPAD);
set resp.http.down02 = blob.integer(down02.get());
set resp.http.down02lpad = blob.integer(down02.get(), LPAD);
set resp.http.down02rpad = blob.integer(down02.get(), RPAD);
set resp.http.up02 = blob.integer(up02.get());
set resp.http.up02lpad = blob.integer(up02.get(), LPAD);
set resp.http.up02rpad = blob.integer(up02.get(), RPAD);
set resp.http.empty = blob.integer(empty.get());
}
}
# Check possible values for 8-, 4- and 2-byte INTs.
client c1 {
txreq
rxresp
expect resp.status == 200
expect resp.http.down07 ~ "^(283686952306183|117835012|1798)$"
expect resp.http.up07 ~ "^(506097522914230528|66051|1)$"
expect resp.http.down07 != resp.http.up07
expect resp.http.down0f ~ "^(579005069656919567|252579084|3854)$"
expect resp.http.up0f ~ "^(506097522914230528|66051|1)$"
expect resp.http.up0f != resp.http.down0f
expect resp.http.down03 ~ "^(50462976|770)$"
expect resp.http.up03 ~ "^(66051|1)$"
expect resp.http.minusone == "-1"
expect resp.http.onebyte == "127"
expect resp.http.onebyterpad ~ "^(9151314442816847872|2130706432|32512)$"
expect resp.http.down0frpad == resp.http.down0f
expect resp.http.up0frpad == resp.http.up0f
expect resp.http.down02 ~ "^(131328|513)$"
expect resp.http.down02lpad == resp.http.down02
expect resp.http.down02rpad ~ "^(144396663052566528|33619968|513)$"
expect resp.http.up02 ~ "^(258|1)$"
expect resp.http.up02lpad == resp.http.up02
expect resp.http.up02rpad ~ "^(283673999966208|66048|1)$"
expect resp.http.empty == "0"
} -run
logexpect l1 -v v1 -d 1 -g vxid -q "VCL_Error" {
expect 0 * Begin req
expect * = VCL_Error "^vmod blob error: blob length is 0 in blob.integer..$"
expect * = End
} -run
# VCL load fails if integer() is called for an empty blob in vcl_init
varnish v1 -errvcl {vmod blob error: blob length is 0 in blob.integer()} {
import blob from "${vmod_topbuild}/src/.libs/libvmod_blob.so";
import blobcode;
backend b { .host = "${bad_ip}"; }
sub vcl_init {
new empty = blobcode.blob(IDENTITY, "");
if (blob.integer(empty.get()) == 0) {
new B = blobcode.blob(IDENTITY, "b");
}
}
}
src/vmod_blob.c
View file @
ba187152
...
...
@@ -25,14 +25,46 @@
*
*/
#include "config.h"
#include <string.h>
#include "config.h"
#include "vcl.h"
#include "vas.h"
#include "vdef.h"
#include "vrt.h"
#include "cache/cache.h"
#include "vsb.h"
#include "vcc_if.h"
#define ERR(ctx, msg) \
errmsg((ctx), "vmod blob error: " msg)
#define VERR(ctx, fmt, ...) \
errmsg((ctx), "vmod blob error: " fmt, __VA_ARGS__)
static
void
errmsg
(
VRT_CTX
,
const
char
*
fmt
,
...)
{
va_list
args
;
va_start
(
args
,
fmt
);
if
(
ctx
->
vsl
)
VSLbv
(
ctx
->
vsl
,
SLT_VCL_Error
,
fmt
,
args
);
else
VSLv
(
SLT_VCL_Error
,
0
,
fmt
,
args
);
va_end
(
args
);
if
(
ctx
->
method
==
VCL_MET_INIT
)
{
AN
(
ctx
->
msg
);
va_start
(
args
,
fmt
);
VSB_vprintf
(
ctx
->
msg
,
fmt
,
args
);
va_end
(
args
);
VRT_handling
(
ctx
,
VCL_RET_FAIL
);
}
}
VCL_BOOL
vmod_same
(
VRT_CTX
__attribute__
((
unused
)),
VCL_BLOB
b1
,
VCL_BLOB
b2
)
{
...
...
@@ -55,6 +87,24 @@ vmod_length(VRT_CTX __attribute__((unused)), VCL_BLOB b)
return
b
->
len
;
}
VCL_INT
vmod_integer
(
VRT_CTX
,
VCL_BLOB
b
,
VCL_ENUM
padding
)
{
VCL_INT
i
=
0
;
if
(
b
->
len
>=
sizeof
(
VCL_INT
))
return
*
((
VCL_INT
*
)
b
->
priv
);
if
(
b
->
len
==
0
)
{
ERR
(
ctx
,
"blob length is 0 in blob.integer()"
);
return
0
;
}
for
(
int
j
=
0
;
j
<
b
->
len
;
j
++
)
i
|=
((
unsigned
char
*
)
b
->
priv
)[
j
]
<<
((
b
->
len
-
j
-
1
)
*
8
);
if
(
padding
[
0
]
==
'R'
)
i
<<=
(
sizeof
(
VCL_INT
)
-
b
->
len
)
*
8
;
return
i
;
}
VCL_STRING
vmod_version
(
VRT_CTX
__attribute__
((
unused
)))
{
...
...
src/vmod_blob.vcc
View file @
ba187152
#-
# Copyright (c) 2016 UPLEX Nils Goroll Systemoptimierung
# Copyright (c) 2016
-2017
UPLEX Nils Goroll Systemoptimierung
# All rights reserved
#
# Author: Geoffrey Simmons <geoffrey.simmons@uplex.de>
...
...
@@ -11,26 +11,44 @@ $Module blob 3 basic operations for the VCL blob type
$Function BOOL same(BLOB, BLOB)
Description
Returns true if and only if the two BLOB arguments are the
same object, i.e. they specify exactly the same region of
memory.
Returns true if and only if the two BLOB arguments are the same
object, i.e. they specify exactly the same region of memory.
$Function BOOL equal(BLOB, BLOB)
Description
Returns true if and only if the two BLOB arguments have equal
contents (possibly in different memory regions).
Returns true if and only if the two BLOB arguments have equal contents
(possibly in different memory regions).
$Function INT length(BLOB)
Description
Returns the length of the BLOB.
Returns the length of the BLOB.
$Function INT integer(BLOB, ENUM { LPAD, RPAD } padding="LPAD")
Returns the initial bytes of the BLOB as an integer.
If the BLOB has fewer bytes than the size of an INT, then the return
value is padded with zeroes to the left if ``padding`` is ``LPAD``, or
to the right if ``padding`` is ``RPAD``. That is, when ``padding`` is
``RPAD``, then the initial bytes of the BLOB are bit-shifted to the
left so that the size of an INT is filled. ``padding`` is ``LPAD`` by
default.
The value of the returned integer results from the bytes from the BLOB
in ascending order of addresses interpreted according to the
endianness of the system on which Varnish is running.
If the length of the BLOB is 0, then ``integer()`` returns 0 and emits
an error message to the Varnish log using the ``VCL_Error`` tag. If
this happens when ``integer()`` is called in ``vcl_init``, then the
VCL load fails with the error message. If it happens in any other VCL
subroutine, then VCL processing continues. Since 0 can be a legitimate
return value, you should monitor the Varnish log for the error.
$Function STRING version()
Description
Returns the version string for this VMOD.
Returns the version string for this VMOD.
Example::
Example
std.log("Using VMOD blob version " + blob.version());
std.log("Using VMOD blob version " + blob.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