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
c2372a13
Commit
c2372a13
authored
May 23, 2017
by
Geoff Simmons
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add function subblob().
Also removed assertions that BLOBs are not NULL, cannot be guaranteed.
parent
8826e917
Pipeline
#222
skipped
Changes
4
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
228 additions
and
10 deletions
+228
-10
README.rst
README.rst
+28
-0
01blob.vtc
src/tests/01blob.vtc
+114
-1
vmod_blob.c
src/vmod_blob.c
+66
-9
vmod_blob.vcc
src/vmod_blob.vcc
+20
-0
No files found.
README.rst
View file @
c2372a13
...
...
@@ -51,6 +51,7 @@ CONTENTS
* BOOL equal(BLOB, BLOB)
* INT length(BLOB)
* INT integer(BLOB, ENUM {LPAD,RPAD})
* BLOB subblob(BLOB, BYTES, BYTES)
* STRING version()
.. _func_same:
...
...
@@ -125,6 +126,25 @@ 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_subblob:
subblob
-------
::
BLOB subblob(BLOB, BYTES length, BYTES offset=0)
Returns a new BLOB formed from ``length`` bytes of the BLOB argument
starting at ``offset`` bytes from the start of its memory region. The
default value of ``offset`` is 0B.
``subblob()`` fails and returns NULL if the BLOB argument is empty, or
if ``offset + length`` requires more bytes than are available in the
BLOB. If either case, an error message is written to the Varnish log
with the ``VCL_Error`` tag. If the function fails in ``vcl_init``,
then the VCL will fail to load.
.. _func_version:
version
...
...
@@ -145,6 +165,14 @@ INSTALLATION
See `INSTALL.rst <INSTALL.rst>`_ in the source repository.
LIMITATIONS
===========
``subblob()`` obtains space for the newly created BLOB in Varnish
workspaces. If ``subblob()`` fails with "out of space" message in the
Varnish log, you may have to increase the varnishd parameters
``workspace_client`` and/or ``workspace_backend``.
SEE ALSO
========
...
...
src/tests/01blob.vtc
View file @
c2372a13
# looks like -*- vcl -*-
varnishtest "same(), equal()
and length
()"
varnishtest "same(), equal()
, length(), integer(), subblob
()"
# VMOD blobcode must be installed
...
...
@@ -288,3 +288,116 @@ varnish v1 -errvcl {vmod blob error: blob is empty in blob.integer()} {
}
}
}
# subblob()
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 0 up to 7
new up07 = blobcode.blob(BASE64, "AAECAwQFBgc=");
# Byte values 7 down to 0
new down07 = blobcode.blob(BASE64, "BwYFBAMCAQA=");
new empty = blobcode.blob(IDENTITY, "");
}
sub vcl_recv {
return(synth(200));
}
sub vcl_synth {
set resp.http.up03
= blobcode.encode(BASE64, blob.subblob(up07.get(), 4B));
set resp.http.down07060504
= blobcode.encode(BASE64, blob.subblob(down07.get(), 4B));
set resp.http.up04050607
= blobcode.encode(BASE64, blob.subblob(up07.get(), 4B, 4B));
set resp.http.down03
= blobcode.encode(BASE64, blob.subblob(down07.get(), 4B, 4B));
set resp.http.up07
= blobcode.encode(BASE64, blob.subblob(up07.get(), 8B));
set resp.http.down07
= blobcode.encode(BASE64, blob.subblob(down07.get(), 8B));
set resp.http.zerobytes
= blobcode.encode(BASE64, blob.subblob(down07.get(), 0B));
set resp.http.zerolen
= blob.length(blob.subblob(down07.get(), 0B));
set resp.http.empty
= blobcode.encode(BASE64, blob.subblob(empty.get(), 1B));
set resp.http.toolong
= blobcode.encode(BASE64, blob.subblob(up07.get(), 9B));
set resp.http.badoffset
= blobcode.encode(BASE64, blob.subblob(up07.get(), 4B, 5B));
}
}
logexpect l1 -v v1 -d 0 -g vxid -q "VCL_Error" {
expect 0 * Begin req
expect * = VCL_Error "^vmod blob error: blob is empty in blob.subblob..$"
expect * = VCL_Error "^vmod blob error: size 9 from offset 0 requires more bytes than blob length 8 in blob.subblob..$"
expect * = VCL_Error "^vmod blob error: size 4 from offset 5 requires more bytes than blob length 8 in blob.subblob..$"
expect * = End
} -start
client c1 {
txreq
rxresp
expect resp.status == 200
expect resp.http.up03 == "AAECAw=="
expect resp.http.down07060504 == "BwYFBA=="
expect resp.http.up04050607 == "BAUGBw=="
expect resp.http.down03 == "AwIBAA=="
expect resp.http.up07 == "AAECAwQFBgc="
expect resp.http.down07 == "BwYFBAMCAQA="
expect resp.http.zerobytes == ""
expect resp.http.zerolen == "0"
expect resp.http.empty == ""
expect resp.http.toolong == ""
expect resp.http.badoffset == ""
} -run
logexpect l1 -wait
# VCL load failures from subblob()
varnish v1 -errvcl {vmod blob error: blob is empty in blob.subblob()} {
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.same(empty.get(), blob.subblob(empty.get(), 0B))) {
new B = blobcode.blob(IDENTITY, "b");
}
}
}
varnish v1 -errvcl {vmod blob error: size 9 from offset 0 requires more bytes than blob length 8 in blob.subblob()} {
import blob from "${vmod_topbuild}/src/.libs/libvmod_blob.so";
import blobcode;
backend b { .host = "${bad_ip}"; }
sub vcl_init {
new up07 = blobcode.blob(BASE64, "AAECAwQFBgc=");
if (blob.same(up07.get(), blob.subblob(up07.get(), 9B))) {
new B = blobcode.blob(IDENTITY, "b");
}
}
}
varnish v1 -errvcl {vmod blob error: size 4 from offset 5 requires more bytes than blob length 8 in blob.subblob()} {
import blob from "${vmod_topbuild}/src/.libs/libvmod_blob.so";
import blobcode;
backend b { .host = "${bad_ip}"; }
sub vcl_init {
new up07 = blobcode.blob(BASE64, "AAECAwQFBgc=");
if (blob.same(up07.get(), blob.subblob(up07.get(), 4B, 5B))) {
new B = blobcode.blob(IDENTITY, "b");
}
}
}
src/vmod_blob.c
View file @
c2372a13
...
...
@@ -44,6 +44,21 @@
#define VERR(ctx, fmt, ...) \
errmsg((ctx), "vmod blob error: " fmt, __VA_ARGS__)
#define ERRNOMEM(ctx, msg) \
ERR((ctx), msg ", out of space")
#define VERRNOMEM(ctx, fmt, ...) \
VERR((ctx), fmt ", out of space", __VA_ARGS__)
static
const
struct
vmod_priv
null_blob
[
1
]
=
{
{
.
priv
=
""
,
.
len
=
0
,
.
free
=
NULL
}
};
static
void
errmsg
(
VRT_CTX
,
const
char
*
fmt
,
...)
{
...
...
@@ -68,17 +83,20 @@ errmsg(VRT_CTX, const char *fmt, ...)
VCL_BOOL
vmod_same
(
VRT_CTX
__attribute__
((
unused
)),
VCL_BLOB
b1
,
VCL_BLOB
b2
)
{
AN
(
b1
);
AN
(
b2
);
if
(
b1
==
NULL
&&
b2
==
NULL
)
return
1
;
if
(
b1
==
NULL
||
b2
==
NULL
)
return
0
;
return
b1
->
len
==
b2
->
len
&&
b1
->
priv
==
b2
->
priv
;
}
VCL_BOOL
vmod_equal
(
VRT_CTX
__attribute__
((
unused
)),
VCL_BLOB
b1
,
VCL_BLOB
b2
)
{
AN
(
b1
);
AN
(
b2
);
if
(
b1
==
NULL
&&
b2
==
NULL
)
return
1
;
if
(
b1
==
NULL
||
b2
==
NULL
)
return
0
;
if
(
b1
->
len
!=
b2
->
len
)
return
0
;
if
(
b1
->
priv
==
b2
->
priv
)
...
...
@@ -91,7 +109,8 @@ vmod_equal(VRT_CTX __attribute__((unused)), VCL_BLOB b1, VCL_BLOB b2)
VCL_INT
vmod_length
(
VRT_CTX
__attribute__
((
unused
)),
VCL_BLOB
b
)
{
AN
(
b
);
if
(
b
==
NULL
)
return
0
;
return
b
->
len
;
}
...
...
@@ -101,13 +120,12 @@ vmod_integer(VRT_CTX, VCL_BLOB b, VCL_ENUM padding)
VCL_INT
i
=
0
;
CHECK_OBJ_NOTNULL
(
ctx
,
VRT_CTX_MAGIC
);
AN
(
b
);
assert
(
b
->
len
>=
0
);
if
(
b
->
len
==
0
||
b
->
priv
==
NULL
)
{
if
(
b
==
NULL
||
b
->
len
==
0
||
b
->
priv
==
NULL
)
{
ERR
(
ctx
,
"blob is empty in blob.integer()"
);
return
0
;
}
assert
(
b
->
len
>=
0
);
if
((
unsigned
)
b
->
len
>=
sizeof
(
VCL_INT
))
return
*
((
VCL_INT
*
)
b
->
priv
);
...
...
@@ -118,6 +136,45 @@ vmod_integer(VRT_CTX, VCL_BLOB b, VCL_ENUM padding)
return
i
;
}
VCL_BLOB
vmod_subblob
(
VRT_CTX
,
VCL_BLOB
b
,
VCL_BYTES
n
,
VCL_BYTES
off
)
{
uintptr_t
snap
;
struct
vmod_priv
*
sub
;
CHECK_OBJ_NOTNULL
(
ctx
,
VRT_CTX_MAGIC
);
assert
(
n
>=
0
);
assert
(
off
>=
0
);
if
(
b
==
NULL
||
b
->
len
==
0
||
b
->
priv
==
NULL
)
{
ERR
(
ctx
,
"blob is empty in blob.subblob()"
);
return
NULL
;
}
assert
(
b
->
len
>=
0
);
if
(
off
+
n
>
b
->
len
)
{
VERR
(
ctx
,
"size %d from offset %d requires more bytes than "
"blob length %d in blob.subblob()"
,
n
,
off
,
b
->
len
);
return
NULL
;
}
if
(
n
==
0
)
return
null_blob
;
snap
=
WS_Snapshot
(
ctx
->
ws
);
if
((
sub
=
WS_Alloc
(
ctx
->
ws
,
sizeof
(
*
sub
)))
==
NULL
)
{
ERRNOMEM
(
ctx
,
"Allocating BLOB result in blob.subblob()"
);
return
NULL
;
}
if
((
sub
->
priv
=
WS_Alloc
(
ctx
->
ws
,
n
))
==
NULL
)
{
VERRNOMEM
(
ctx
,
"Allocating %d bytes in blob.subblob()"
,
n
);
WS_Reset
(
ctx
->
ws
,
snap
);
return
NULL
;
}
memcpy
(
sub
->
priv
,
b
->
priv
+
off
,
n
);
sub
->
len
=
n
;
return
sub
;
}
VCL_STRING
vmod_version
(
VRT_CTX
__attribute__
((
unused
)))
{
...
...
src/vmod_blob.vcc
View file @
c2372a13
...
...
@@ -73,6 +73,18 @@ 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 BLOB subblob(BLOB, BYTES length, BYTES offset = 0)
Returns a new BLOB formed from ``length`` bytes of the BLOB argument
starting at ``offset`` bytes from the start of its memory region. The
default value of ``offset`` is 0B.
``subblob()`` fails and returns NULL if the BLOB argument is empty, or
if ``offset + length`` requires more bytes than are available in the
BLOB. If either case, an error message is written to the Varnish log
with the ``VCL_Error`` tag. If the function fails in ``vcl_init``,
then the VCL will fail to load.
$Function STRING version()
Returns the version string for this VMOD.
...
...
@@ -86,6 +98,14 @@ INSTALLATION
See `INSTALL.rst <INSTALL.rst>`_ in the source repository.
LIMITATIONS
===========
``subblob()`` obtains space for the newly created BLOB in Varnish
workspaces. If ``subblob()`` fails with "out of space" message in the
Varnish log, you may have to increase the varnishd parameters
``workspace_client`` and/or ``workspace_backend``.
SEE ALSO
========
...
...
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