Commit d1799b8f authored by Geoff Simmons's avatar Geoff Simmons

VMOD blob: use a DEFAULT value for the case ENUM.

DEFAULT is interpreted as LOWER for the HEX and URL encodings, and
is the only legal value for all other encodings.
parent 34ce7c8f
......@@ -54,13 +54,9 @@ varnish v1 -vcl {
blob.encode(IDENTITY,
blob=blob.decode(HEX, encoded="666f6f00626172"));
set resp.http.lc =
blob.encode(IDENTITY, LOWER, blob.decode(IDENTITY,
encoded="Don't care"));
set resp.http.uc =
blob.encode(IDENTITY, UPPER, blob.decode(IDENTITY,
encoded="Don't care"));
set resp.http.pos =
blob.encode(IDENTITY, DEFAULT, blob.decode(IDENTITY,
encoded="foobar"));
}
} -start
......@@ -76,6 +72,52 @@ client c1 {
expect resp.http.param == "The quick brown fox jumps over the lazy dog"
expect resp.http.paramlist == "/The quick brown fox jumps over the lazy dog/"
expect resp.http.truncated == "foo"
expect resp.http.lc == "Don't care"
expect resp.http.uc == "Don't care"
expect resp.http.pos == "foobar"
} -run
# Require case=DEFAULT
server s1 -repeat 2 {
rxreq
txresp
} -start
varnish v1 -vcl+backend {
import blob;
sub vcl_deliver {
if (req.url == "/lc") {
set resp.http.lc =
blob.encode(IDENTITY, LOWER, blob.decode(IDENTITY,
encoded="foobar"));
}
elsif (req.url == "/uc") {
set resp.http.uc =
blob.encode(IDENTITY, UPPER, blob.decode(IDENTITY,
encoded="foobar"));
}
}
}
client c1 {
txreq -url "/lc"
rxresp
expect resp.status == 503
expect resp.reason == "VCL failed"
expect resp.http.lc == <undef>
} -run
client c1 {
txreq -url "/uc"
rxresp
expect resp.status == 503
expect resp.reason == "VCL failed"
expect resp.http.uc == <undef>
} -run
logexpect l1 -v v1 -d 1 -g vxid -q "VCL_Error" {
expect * * VCL_Error "^vmod blob error: case LOWER is illegal with encoding IDENTITY$"
expect * * VCL_Error "^vmod blob error: case UPPER is illegal with encoding IDENTITY$"
} -start
logexpect l1 -wait
......@@ -21,13 +21,9 @@ varnish v1 -vcl {
blob.encode(BASE64, blob=blob.decode(IDENTITY, encoded=
req.http.pangram));
set resp.http.b64lc =
blob.encode(BASE64, LOWER, blob.decode(IDENTITY, encoded=
req.http.pangram));
set resp.http.b64uc =
blob.encode(BASE64, UPPER, blob.decode(IDENTITY, encoded=
req.http.pangram));
set resp.http.b64pos =
blob.encode(BASE64, DEFAULT, blob.decode(IDENTITY, encoded=
req.http.pangram));
set resp.http.b64hobbes =
blob.encode(BASE64, blob=blob.decode(IDENTITY, encoded=
......@@ -41,12 +37,8 @@ varnish v1 -vcl {
blob.encode(BASE64URL,
blob=blob.decode(IDENTITY, encoded=req.http.pangram));
set resp.http.b64urllc =
blob.encode(BASE64URL, LOWER,
blob.decode(IDENTITY, encoded=req.http.pangram));
set resp.http.b64urluc =
blob.encode(BASE64URL, UPPER,
set resp.http.b64urlpos =
blob.encode(BASE64URL, DEFAULT,
blob.decode(IDENTITY, encoded=req.http.pangram));
set resp.http.b64urlhobbes =
......@@ -61,12 +53,8 @@ varnish v1 -vcl {
blob.encode(BASE64URLNOPAD,
blob=blob.decode(IDENTITY, encoded=req.http.pangram));
set resp.http.b64urlnopadlc =
blob.encode(BASE64URLNOPAD, LOWER,
blob.decode(IDENTITY, encoded=req.http.pangram));
set resp.http.b64urlnopaduc =
blob.encode(BASE64URLNOPAD, UPPER,
set resp.http.b64urlnopadpos =
blob.encode(BASE64URLNOPAD, DEFAULT,
blob.decode(IDENTITY, encoded=req.http.pangram));
set resp.http.b64nopadhobbes =
......@@ -87,15 +75,15 @@ varnish v1 -vcl {
set resp.http.b64param =
blob.encode(blob=blob.decode(IDENTITY, encoded=req.http.pangram),
encoding=BASE64, case=LOWER);
encoding=BASE64, case=DEFAULT);
set resp.http.b64urlparam =
blob.encode(blob=blob.decode(IDENTITY, encoded=req.http.pangram),
encoding=BASE64URL, case=UPPER);
encoding=BASE64URL, case=DEFAULT);
set resp.http.b64urlnopadparam =
blob.encode(blob=blob.decode(IDENTITY, encoded=req.http.pangram),
encoding=BASE64URLNOPAD, case=LOWER);
encoding=BASE64URLNOPAD, case=DEFAULT);
set resp.http.b64xcode =
blob.transcode(IDENTITY, BASE64,
......@@ -115,18 +103,15 @@ client c1 {
txreq -url "/"
rxresp
expect resp.http.b64 == "VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZw=="
expect resp.http.b64lc == resp.http.b64
expect resp.http.b64uc == resp.http.b64
expect resp.http.b64pos == resp.http.b64
expect resp.http.b64hobbes == "TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlzIHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2YgdGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGludWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRoZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4="
expect resp.http.b64all == "//79/Pv6+fj39vX08/Lx8O/u7ezr6uno5+bl5OPi4eDf3t3c29rZ2NfW1dTT0tHQz87NzMvKycjHxsXEw8LBwL++vby7urm4t7a1tLOysbCvrq2sq6qpqKempaSjoqGgn56dnJuamZiXlpWUk5KRkI+OjYyLiomIh4aFhIOCgYB/fn18e3p5eHd2dXRzcnFwb25tbGtqaWhnZmVkY2JhYF9eXVxbWllYV1ZVVFNSUVBPTk1MS0pJSEdGRURDQkFAPz49PDs6OTg3NjU0MzIxMC8uLSwrKikoJyYlJCMiISAfHh0cGxoZGBcWFRQTEhEQDw4NDAsKCQgHBgUEAwIBAA=="
expect resp.http.b64url == "VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZw=="
expect resp.http.b64urllc == resp.http.b64url
expect resp.http.b64urluc == resp.http.b64url
expect resp.http.b64urlpos == resp.http.b64url
expect resp.http.b64urlhobbes == "TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlzIHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2YgdGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGludWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRoZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4="
expect resp.http.b64urlall == "__79_Pv6-fj39vX08_Lx8O_u7ezr6uno5-bl5OPi4eDf3t3c29rZ2NfW1dTT0tHQz87NzMvKycjHxsXEw8LBwL--vby7urm4t7a1tLOysbCvrq2sq6qpqKempaSjoqGgn56dnJuamZiXlpWUk5KRkI-OjYyLiomIh4aFhIOCgYB_fn18e3p5eHd2dXRzcnFwb25tbGtqaWhnZmVkY2JhYF9eXVxbWllYV1ZVVFNSUVBPTk1MS0pJSEdGRURDQkFAPz49PDs6OTg3NjU0MzIxMC8uLSwrKikoJyYlJCMiISAfHh0cGxoZGBcWFRQTEhEQDw4NDAsKCQgHBgUEAwIBAA=="
expect resp.http.b64urlnopad == "VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZw"
expect resp.http.b64urlnopadlc == resp.http.b64urlnopad
expect resp.http.b64urlnopaduc == resp.http.b64urlnopad
expect resp.http.b64urlnopadpos == resp.http.b64urlnopad
expect resp.http.b64nopadhobbes == "TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlzIHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2YgdGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGludWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRoZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4"
expect resp.http.b64nopadall == "__79_Pv6-fj39vX08_Lx8O_u7ezr6uno5-bl5OPi4eDf3t3c29rZ2NfW1dTT0tHQz87NzMvKycjHxsXEw8LBwL--vby7urm4t7a1tLOysbCvrq2sq6qpqKempaSjoqGgn56dnJuamZiXlpWUk5KRkI-OjYyLiomIh4aFhIOCgYB_fn18e3p5eHd2dXRzcnFwb25tbGtqaWhnZmVkY2JhYF9eXVxbWllYV1ZVVFNSUVBPTk1MS0pJSEdGRURDQkFAPz49PDs6OTg3NjU0MzIxMC8uLSwrKikoJyYlJCMiISAfHh0cGxoZGBcWFRQTEhEQDw4NDAsKCQgHBgUEAwIBAA"
expect resp.http.b64empty == ""
......@@ -339,3 +324,102 @@ logexpect l1 -v v1 -d 1 -g vxid -q "VCL_Error" {
expect * * VCL_Error {^vmod blob error: cannot decode, illegal encoding beginning with "././"$}
expect * * VCL_Error {^vmod blob error: cannot decode, illegal encoding beginning with "TWFu"$}
} -run
# Require case=DEFAULT
server s1 -repeat 6 {
rxreq
txresp
} -start
varnish v1 -vcl+backend {
import blob;
sub vcl_deliver {
if (req.url == "/b64lc") {
set resp.http.b64lc =
blob.encode(BASE64, LOWER, blob.decode(IDENTITY, encoded=""));
}
elsif (req.url == "/b64uc") {
set resp.http.b64uc =
blob.encode(BASE64, UPPER, blob.decode(IDENTITY, encoded=""));
}
elsif (req.url == "/b64urllc") {
set resp.http.b64urllc =
blob.encode(BASE64URL, LOWER, blob.decode(IDENTITY, encoded=""));
}
elsif (req.url == "/b64urluc") {
set resp.http.b64urluc =
blob.encode(BASE64URL, UPPER, blob.decode(IDENTITY, encoded=""));
}
elsif (req.url == "/b64urlnopadlc") {
set resp.http.b64urlnopadlc =
blob.encode(BASE64URLNOPAD, LOWER, blob.decode(IDENTITY,
encoded=""));
}
elsif (req.url == "/b64urlnopaduc") {
set resp.http.b64urlnopaduc =
blob.encode(BASE64URLNOPAD, UPPER, blob.decode(IDENTITY,
encoded=""));
}
}
}
client c1 {
txreq -url "/b64lc"
rxresp
expect resp.status == 503
expect resp.reason == "VCL failed"
expect resp.http.b64lc == <undef>
} -run
client c1 {
txreq -url "/b64uc"
rxresp
expect resp.status == 503
expect resp.reason == "VCL failed"
expect resp.http.b64uc == <undef>
} -run
client c1 {
txreq -url "/b64urllc"
rxresp
expect resp.status == 503
expect resp.reason == "VCL failed"
expect resp.http.b64urllc == <undef>
} -run
client c1 {
txreq -url "/b64urluc"
rxresp
expect resp.status == 503
expect resp.reason == "VCL failed"
expect resp.http.b64urluc == <undef>
} -run
client c1 {
txreq -url "/b64urlnopadlc"
rxresp
expect resp.status == 503
expect resp.reason == "VCL failed"
expect resp.http.b64urlnopadlc == <undef>
} -run
client c1 {
txreq -url "/b64urlnopaduc"
rxresp
expect resp.status == 503
expect resp.reason == "VCL failed"
expect resp.http.b64urlnopaduc == <undef>
} -run
logexpect l1 -v v1 -d 1 -g vxid -q "VCL_Error" {
expect * * VCL_Error "^vmod blob error: case LOWER is illegal with encoding BASE64"
expect * * VCL_Error "^vmod blob error: case UPPER is illegal with encoding BASE64"
expect * * VCL_Error "^vmod blob error: case LOWER is illegal with encoding BASE64URL"
expect * * VCL_Error "^vmod blob error: case UPPER is illegal with encoding BASE64URL"
expect * * VCL_Error "^vmod blob error: case LOWER is illegal with encoding BASE64URLNOPAD"
expect * * VCL_Error "^vmod blob error: case UPPER is illegal with encoding BASE64URLNOPAD"
} -start
logexpect l1 -wait
varnishtest "VMOD blob blob object interface"
server s1 {} -start
varnish v1 -arg "-i serverid" -vcl+backend {
varnish v1 -arg "-i serverid" -vcl {
import blob;
backend b { .host = "${bad_ip}"; }
sub vcl_init {
new id = blob.blob(IDENTITY,
......@@ -93,8 +92,9 @@ client c1 {
# run twice to test retrieving cached encodings
client c1 -run
varnish v1 -vcl+backend {
varnish v1 -vcl {
import blob;
backend b { .host = "${bad_ip}"; }
sub vcl_init {
new idempty = blob.blob(IDENTITY, "");
......@@ -165,8 +165,9 @@ client c1 {
# run twice to test retrieving cached encodings
client c1 -run
varnish v1 -vcl+backend {
varnish v1 -vcl {
import blob;
backend b { .host = "${bad_ip}"; }
sub vcl_init {
new b64 = blob.blob(BASE64, "L0hlbGxvIHdvcmxkLw==");
......@@ -254,8 +255,9 @@ client c2 {
# run twice
client c2 -run
varnish v1 -vcl+backend {
varnish v1 -vcl {
import blob;
backend b { .host = "${bad_ip}"; }
sub vcl_init {
new id = blob.blob(IDENTITY,
......@@ -332,6 +334,125 @@ client c3 -run
varnish v1 -cliok "vcl.discard vcl1"
varnish v1 -cliok "vcl.discard vcl2"
# Require case=DEFAULT in the .encode() method where necessary
server s1 -repeat 8 {
rxreq
txresp
} -start
varnish v1 -vcl+backend {
import blob;
sub vcl_init {
new b = blob.blob(IDENTITY, "");
}
sub vcl_deliver {
if (req.url == "/idlc") {
set resp.http.idlc = b.encode(IDENTITY, LOWER);
}
elsif (req.url == "/iduc") {
set resp.http.iduc = b.encode(IDENTITY, UPPER);
}
if (req.url == "/b64lc") {
set resp.http.b64lc = b.encode(BASE64, LOWER);
}
elsif (req.url == "/b64uc") {
set resp.http.b64uc = b.encode(BASE64, UPPER);
}
elsif (req.url == "/b64urllc") {
set resp.http.b64urllc = b.encode(BASE64URL, LOWER);
}
elsif (req.url == "/b64urluc") {
set resp.http.b64urluc = b.encode(BASE64URL, UPPER);
}
elsif (req.url == "/b64urlnopadlc") {
set resp.http.b64urlnopadlc = b.encode(BASE64URLNOPAD, LOWER);
}
elsif (req.url == "/b64urlnopaduc") {
set resp.http.b64urlnopaduc = b.encode(BASE64URLNOPAD, UPPER);
}
}
}
client c1 {
txreq -url "/idlc"
rxresp
expect resp.status == 503
expect resp.reason == "VCL failed"
expect resp.http.idlc == <undef>
} -run
client c1 {
txreq -url "/iduc"
rxresp
expect resp.status == 503
expect resp.reason == "VCL failed"
expect resp.http.iduc == <undef>
} -run
client c1 {
txreq -url "/b64lc"
rxresp
expect resp.status == 503
expect resp.reason == "VCL failed"
expect resp.http.b64lc == <undef>
} -run
client c1 {
txreq -url "/b64uc"
rxresp
expect resp.status == 503
expect resp.reason == "VCL failed"
expect resp.http.b64uc == <undef>
} -run
client c1 {
txreq -url "/b64urllc"
rxresp
expect resp.status == 503
expect resp.reason == "VCL failed"
expect resp.http.b64urllc == <undef>
} -run
client c1 {
txreq -url "/b64urluc"
rxresp
expect resp.status == 503
expect resp.reason == "VCL failed"
expect resp.http.b64urluc == <undef>
} -run
client c1 {
txreq -url "/b64urlnopadlc"
rxresp
expect resp.status == 503
expect resp.reason == "VCL failed"
expect resp.http.b64urlnopadlc == <undef>
} -run
client c1 {
txreq -url "/b64urlnopaduc"
rxresp
expect resp.status == 503
expect resp.reason == "VCL failed"
expect resp.http.b64urlnopaduc == <undef>
} -run
logexpect l1 -v v1 -d 1 -g vxid -q "VCL_Error" {
expect * * VCL_Error "^vmod blob error: case LOWER is illegal with encoding IDENTITY$"
expect * * VCL_Error "^vmod blob error: case UPPER is illegal with encoding IDENTITY$"
expect * * VCL_Error "^vmod blob error: case LOWER is illegal with encoding BASE64$"
expect * * VCL_Error "^vmod blob error: case UPPER is illegal with encoding BASE64$"
expect * * VCL_Error "^vmod blob error: case LOWER is illegal with encoding BASE64URL$"
expect * * VCL_Error "^vmod blob error: case UPPER is illegal with encoding BASE64URL$"
expect * * VCL_Error "^vmod blob error: case LOWER is illegal with encoding BASE64URLNOPAD$"
expect * * VCL_Error "^vmod blob error: case UPPER is illegal with encoding BASE64URLNOPAD$"
} -start
logexpect l1 -wait
varnish v1 -errvcl {vmod blob error: cannot create blob err, illegal encoding beginning with "g"} {
import blob;
backend b { .host="${bad_ip}"; }
......
......@@ -94,16 +94,19 @@ Empty strings are decoded into a "null blob" (of length 0),
and conversely a null blob is encoded as the empty string.
For encodings with ``HEX`` or ``URL``, you may also specify a ``case``
ENUM with one of the values ``LOWER`` or ``UPPER`` to produce a string
with lower- or uppercase hex digits (in ``[a-f]`` or ``[A-F]``),
respectively. The default value for ``case`` is ``LOWER``.
ENUM with one of the values ``LOWER``, ``UPPER`` or ``DEFAULT`` to
produce a string with lower- or uppercase hex digits (in ``[a-f]`` or
``[A-F]``). The default value for ``case`` is ``DEFAULT``, which for
``HEX`` and ``URL`` means the same as ``LOWER``.
The ``case`` ENUM is not relevant for decodings; ``HEX`` or ``URL``
strings to be decoded as BLOBs may have hex digits in either case, or
in mixed case. The ``case`` ENUM is also ignored for all other
encodings. You cannot, for example, produce an uppercase string by
using the IDENTITY scheme with ``case=UPPER``. To change the case of a
string, use the ``toupper`` or ``tolower`` functions from
in mixed case.
The ``case`` ENUM MUST be set to ``DEFAULT`` for the other encodings
(BASE64* and IDENTITY). You cannot, for example, produce an uppercase
string by using the IDENTITY scheme with ``case=UPPER``. To change the
case of a string, use the ``toupper`` or ``tolower`` functions from
:ref:`vmod_std(3)`.
IDENTITY
......@@ -133,7 +136,7 @@ be written as::
set resp.http.Trunced-Foo2
= blob.encode(blob=blob.decode(HEX, encoded="666f6f00626172"));
The ``case`` ENUM is ignored for ``IDENTITY`` encodings.
The ``case`` ENUM MUST be set to ``DEFAULT`` for ``IDENTITY`` encodings.
BASE64*
-------
......@@ -155,16 +158,17 @@ The ``BASE64URLNOPAD`` encoding uses the same alphabet as
``BASE6URL``, but leaves out the padding. Thus the length of an
encoding with this scheme is not necessarily a mutltiple of four.
The ``case`` ENUM is ignored for for all of the ``BASE64*`` encodings.
The ``case`` ENUM MUST be set to ``DEFAULT`` for for all of the
``BASE64*`` encodings.
HEX
---
The ``HEX`` encoding scheme converts hex strings into blobs and vice
versa. For encodings, you may use the ``case`` ENUM to specify upper-
or lowercase hex digits ``A`` through ``f`` (default ``LOWER``). A
prefix such as ``0x`` is not used for an encoding and is illegal for a
decoding.
or lowercase hex digits ``A`` through ``f`` (default ``DEFAULT``,
which means the same as ``LOWER``). A prefix such as ``0x`` is not
used for an encoding and is illegal for a decoding.
If a hex string to be decoded has an odd number of digits, it is
decoded as if a ``0`` is prepended to it; that is, the first digit is
......@@ -214,13 +218,15 @@ Example::
$Function STRING encode(ENUM {IDENTITY, BASE64, BASE64URL, BASE64URLNOPAD,
HEX, URL} encoding="IDENTITY",
ENUM {LOWER, UPPER} case="LOWER", BLOB blob)
ENUM {LOWER, UPPER, DEFAULT} case="DEFAULT", BLOB blob)
Returns a string representation of the BLOB ``blob`` as specifed by
``encoding``. ``case`` determines the case of hex digits for the
``HEX`` and ``URL`` encodings, and is ignored for the other encodings.
``encoding`` defaults to IDENTITY, and ``case`` defaults to LOWER.
``encoding`` defaults to IDENTITY, and ``case`` defaults to DEFAULT.
DEFAULT is interpreted as LOWER for the HEX and URL encodings, and is
the required value for the other encodings.
Example::
......@@ -242,8 +248,8 @@ $Function STRING transcode(ENUM {IDENTITY, BASE64, BASE64URL, BASE64URLNOPAD,
HEX, URL} decoding="IDENTITY",
ENUM {IDENTITY, BASE64, BASE64URL, BASE64URLNOPAD,
HEX, URL} encoding="IDENTITY",
ENUM {LOWER, UPPER} case="LOWER", INT length=0,
STRING_LIST encoded)
ENUM {LOWER, UPPER, DEFAULT} case="DEFAULT",
INT length=0, STRING_LIST encoded)
Translates from one encoding to another, by first decoding the string
``encoded`` according to the scheme ``decoding``, and then returning
......@@ -256,7 +262,8 @@ As with ``decode()``: If ``length`` > 0, only decode the first
entire string. The default value of ``length`` is 0.
``decoding`` and ``encoding`` default to IDENTITY, and ``case``
defaults to LOWER.
defaults to DEFAULT. DEFAULT is interpreted as LOWER for the HEX and
URL encodings, and is the required value for the other encodings.
Example::
......@@ -343,12 +350,12 @@ Example::
$Method STRING .encode(ENUM {IDENTITY, BASE64, BASE64URL, BASE64URLNOPAD, HEX,
URL} encoding="IDENTITY",
ENUM {LOWER, UPPER} case="LOWER")
ENUM {LOWER, UPPER, DEFAULT} case="DEFAULT")
Returns an encoding of BLOB created by the constructor, according to
the scheme ``encoding``. ``case`` determines the case of hex digits
for the ``HEX`` and ``URL`` encodings, and is ignored for other
encodings.
for the ``HEX`` and ``URL`` encodings, and MUST be set to ``DEFAULT``
for the other encodings.
Example::
......@@ -378,10 +385,11 @@ not known until runtime.
ERRORS
======
The encoders, decoders and ``sub()`` may fail if there is
insufficient space to create the new blob or string. Decoders may also
fail if the encoded string is an illegal format for the decoding
scheme.
The encoders, decoders and ``sub()`` may fail if there is insufficient
space to create the new blob or string. Decoders may also fail if the
encoded string is an illegal format for the decoding scheme. Encoders
will fail for the ``IDENTITY`` and ``BASE64*`` encoding schemes if the
``case`` ENUM is not set to ``DEFAULT``.
If any of the VMOD's methods, functions or constructor fail, then VCL
failure is invoked, just as if ``return(fail)`` had been called in the
......
......@@ -159,6 +159,9 @@ static inline enum case_e
parse_case(VCL_ENUM case_s)
{
switch(*case_s) {
case 'D':
AZ(strcmp(case_s + 1, "EFAULT"));
return DEFAULT;
case 'L':
AZ(strcmp(case_s + 1, "OWER"));
return LOWER;
......@@ -170,6 +173,25 @@ parse_case(VCL_ENUM case_s)
}
}
static inline int
encodes_hex(enum encoding enc)
{
return (enc == HEX || enc == URL);
}
/* Require case DEFAULT for all encodings besides HEX and URL. */
static inline int
check_enc_case(VRT_CTX, VCL_ENUM encs, VCL_ENUM case_s, enum encoding enc,
enum case_e kase)
{
if (!encodes_hex(enc) && kase != DEFAULT) {
VERR(ctx, "case %s is illegal with encoding %s", case_s, encs);
return 0;
}
return 1;
}
/* Objects */
VCL_VOID __match_proto__(td_blob_blob__init)
......@@ -250,8 +272,12 @@ vmod_blob_encode(VRT_CTX, struct vmod_blob_blob *b, VCL_ENUM encs,
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
CHECK_OBJ_NOTNULL(b, VMOD_BLOB_MAGIC);
if (!check_enc_case(ctx, encs, case_s, enc, kase))
return NULL;
if (b->blob.len == 0)
return "";
if (kase == DEFAULT)
kase = LOWER;
if (b->encoding[enc][kase] == NULL) {
AZ(pthread_mutex_lock(&b->lock));
......@@ -396,7 +422,6 @@ encode(VRT_CTX, enum encoding enc, enum case_e kase, VCL_BLOB b)
struct wb_s wb;
ssize_t len;
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
AENC(enc);
if (b == NULL)
......@@ -429,13 +454,11 @@ vmod_encode(VRT_CTX, VCL_ENUM encs, VCL_ENUM case_s, VCL_BLOB b)
{
enum encoding enc = parse_encoding(encs);
enum case_e kase = parse_case(case_s);
return encode(ctx, enc, kase, b);
}
static inline int
encodes_hex(enum encoding enc)
{
return (enc == HEX || enc == URL);
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
if (!check_enc_case(ctx, encs, case_s, enc, kase))
return NULL;
return encode(ctx, enc, kase, b);
}
VCL_STRING __match_proto__(td_blob_transcode)
......@@ -455,6 +478,9 @@ vmod_transcode(VRT_CTX, VCL_ENUM decs, VCL_ENUM encs, VCL_ENUM case_s,
AENC(dec);
AENC(enc);
if (!check_enc_case(ctx, encs, case_s, enc, kase))
return NULL;
/*
* Allocate space for the decoded blob on the stack
* ignoring the limitation imposed by n
......
......@@ -34,9 +34,14 @@
#define AENC(enc) assert((enc) > _INVALID && (enc) < __MAX_ENCODING)
/*
* The enums MUST appear in this order, since LOWER and UPPER are used to
* index the array of cached encodings for the blob object.
*/
enum case_e {
LOWER,
UPPER,
DEFAULT,
};
/*
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment