Commit a145d1de authored by Geoff Simmons's avatar Geoff Simmons

add the .encode() method to the blob object interface

parent 1aa6c288
......@@ -41,6 +41,34 @@ varnish v1 -arg "-i serverid" -vcl+backend {
set resp.http.hexmix = convert.encode(IDENTITY, hexmix.get());
set resp.http.b64 = convert.encode(IDENTITY, b64.get());
set resp.http.b64nopad = convert.encode(IDENTITY, b64nopad.get());
set resp.http.id2id = id.encode(IDENTITY);
set resp.http.id2b64 = id.encode(BASE64);
set resp.http.id2b64url = id.encode(BASE64URL);
set resp.http.id2b64urlnopad = id.encode(BASE64URLNOPAD);
set resp.http.id2hexuc = id.encode(HEXUC);
set resp.http.id2hexlc = id.encode(HEXLC);
set resp.http.emptyid = idempty.encode(IDENTITY);
set resp.http.emptyb64 = idempty.encode(BASE64);
set resp.http.emptyb64url = idempty.encode(BASE64URL);
set resp.http.emptyb64urlnopad = idempty.encode(BASE64URLNOPAD);
set resp.http.emptyhexuc = idempty.encode(HEXUC);
set resp.http.emptyhexlc = idempty.encode(HEXLC);
set resp.http.hexuc2id = hexuc.encode(IDENTITY);
set resp.http.hexuc2b64 = hexuc.encode(BASE64);
set resp.http.hexuc2b64url = hexuc.encode(BASE64URL);
set resp.http.hexuc2b64nopad = hexuc.encode(BASE64URLNOPAD);
set resp.http.hexuc2hexuc = hexuc.encode(HEXUC);
set resp.http.hexuc2hexlc = hexuc.encode(HEXLC);
set resp.http.hexlc2id = hexlc.encode(IDENTITY);
set resp.http.hexlc2b64 = hexlc.encode(BASE64);
set resp.http.hexlc2b64url = hexlc.encode(BASE64URL);
set resp.http.hexlc2b64nopad = hexlc.encode(BASE64URLNOPAD);
set resp.http.hexlc2hexuc = hexlc.encode(HEXUC);
set resp.http.hexlc2hexlc = hexlc.encode(HEXLC);
}
} -start
......@@ -56,10 +84,104 @@ client c1 {
expect resp.http.hexmix == "foo bar baz quux"
expect resp.http.b64 == "/Hello world/"
expect resp.http.b64nopad == "/Hello world/"
}
expect resp.http.id2id == "The quick brown fox jumps over the lazy dog"
expect resp.http.id2b64 == "VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZw=="
expect resp.http.id2b64url == "VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZw=="
expect resp.http.id2b64urlnopad == "VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZw"
expect resp.http.id2hexuc == "54686520717569636B2062726F776E20666F78206A756D7073206F76657220746865206C617A7920646F67"
expect resp.http.id2hexlc == "54686520717569636b2062726f776e20666f78206a756d7073206f76657220746865206c617a7920646f67"
expect resp.http.emptyid == ""
expect resp.http.emptyb64 == ""
expect resp.http.emptyb64url == ""
expect resp.http.emptyb64urlnopad == ""
expect resp.http.emptyhexuc == ""
expect resp.http.emptyhexlc == ""
expect resp.http.hexuc2id == "foo bar baz quux"
expect resp.http.hexuc2b64 == "Zm9vIGJhciBiYXogcXV1eA=="
expect resp.http.hexuc2b64url == "Zm9vIGJhciBiYXogcXV1eA=="
expect resp.http.hexuc2b64nopad == "Zm9vIGJhciBiYXogcXV1eA"
expect resp.http.hexuc2hexuc == "666F6F206261722062617A2071757578"
expect resp.http.hexuc2hexlc == "666f6f206261722062617a2071757578"
expect resp.http.hexlc2id == "foo bar baz quux"
expect resp.http.hexlc2b64 == "Zm9vIGJhciBiYXogcXV1eA=="
expect resp.http.hexlc2b64url == "Zm9vIGJhciBiYXogcXV1eA=="
expect resp.http.hexlc2b64nopad == "Zm9vIGJhciBiYXogcXV1eA"
expect resp.http.hexlc2hexuc == "666F6F206261722062617A2071757578"
expect resp.http.hexlc2hexlc == "666f6f206261722062617a2071757578"
} -run
# run twice to test retrieving cached encodings
client c1 -run
varnish v1 -vcl+backend {
import convert from "${vmod_topbuild}/src/.libs/libvmod_convert.so";
sub vcl_init {
new b64 = convert.blob(BASE64, "L0hlbGxvIHdvcmxkLw==");
new b64url = convert.blob(BASE64URL, "L0hlbGxvIHdvcmxkLw==");
new b64nopad = convert.blob(BASE64URLNOPAD, "L0hlbGxvIHdvcmxkLw");
}
sub vcl_recv {
return(synth(200));
}
sub vcl_synth {
set resp.http.b642id = b64.encode(IDENTITY);
set resp.http.b642b64 = b64.encode(BASE64);
set resp.http.b642b64url = b64.encode(BASE64URL);
set resp.http.b642b64nopad = b64.encode(BASE64URLNOPAD);
set resp.http.b642hexuc = b64.encode(HEXUC);
set resp.http.b642hexlc = b64.encode(HEXLC);
set resp.http.b64url2id = b64url.encode(IDENTITY);
set resp.http.b64url2b64 = b64url.encode(BASE64);
set resp.http.b64url2b64url = b64url.encode(BASE64URL);
set resp.http.b64url2b64nopad = b64url.encode(BASE64URLNOPAD);
set resp.http.b64url2hexuc = b64url.encode(HEXUC);
set resp.http.b64url2hexlc = b64url.encode(HEXLC);
set resp.http.b64nopad2id = b64nopad.encode(IDENTITY);
set resp.http.b64nopad2b64 = b64nopad.encode(BASE64);
set resp.http.b64nopad2b64url = b64nopad.encode(BASE64URL);
set resp.http.b64nopad2b64nopad = b64nopad.encode(BASE64URLNOPAD);
set resp.http.b64nopad2hexuc = b64nopad.encode(HEXUC);
set resp.http.b64nopad2hexlc = b64nopad.encode(HEXLC);
}
}
client c2 {
txreq
rxresp
expect resp.http.b642id == "/Hello world/"
expect resp.http.b642b64 == "L0hlbGxvIHdvcmxkLw=="
expect resp.http.b642b64url == "L0hlbGxvIHdvcmxkLw=="
expect resp.http.b642b64nopad == "L0hlbGxvIHdvcmxkLw"
expect resp.http.b642hexuc == "2F48656C6C6F20776F726C642F"
expect resp.http.b642hexlc == "2f48656c6c6f20776f726c642f"
expect resp.http.b64url2id == "/Hello world/"
expect resp.http.b64url2b64 == "L0hlbGxvIHdvcmxkLw=="
expect resp.http.b64url2b64url == "L0hlbGxvIHdvcmxkLw=="
expect resp.http.b64url2b64nopad == "L0hlbGxvIHdvcmxkLw"
expect resp.http.b64url2hexuc == "2F48656C6C6F20776F726C642F"
expect resp.http.b64url2hexlc == "2f48656c6c6f20776f726c642f"
expect resp.http.b64nopad2id == "/Hello world/"
expect resp.http.b64nopad2b64 == "L0hlbGxvIHdvcmxkLw=="
expect resp.http.b64nopad2b64url == "L0hlbGxvIHdvcmxkLw=="
expect resp.http.b64nopad2b64nopad == "L0hlbGxvIHdvcmxkLw"
expect resp.http.b64nopad2hexuc == "2F48656C6C6F20776F726C642F"
expect resp.http.b64nopad2hexlc == "2f48656c6c6f20776f726c642f"
} -run
# run twice
client c2 -run
varnish v1 -errvcl {vmod convert error: cannot create blob err, illegal encoding beginning with "g"} {
import convert from "${vmod_topbuild}/src/.libs/libvmod_convert.so";
backend b { .host="${bad_ip}"; }
......
......@@ -27,6 +27,7 @@
*/
#include <errno.h>
#include <pthread.h>
#include "vcl.h"
#include "vrt.h"
......@@ -39,6 +40,8 @@ struct vmod_convert_blob {
unsigned magic;
#define VMOD_CONVERT_BLOB_MAGIC 0xfade4fa9
struct vmod_priv blob;
const char *encoding[__MAX_ENCODING];
pthread_mutex_t lock;
};
#define ERR(ctx, msg) \
......@@ -204,6 +207,7 @@ vmod_blob__init(VRT_CTX, struct vmod_convert_blob **blobp, const char *vcl_name,
AN(b);
*blobp = b;
b->blob.free = NULL;
AZ(pthread_mutex_init(&b->lock, NULL));
va_start(ap, p);
len = decode_l_va(dec, p, ap);
......@@ -229,6 +233,7 @@ vmod_blob__init(VRT_CTX, struct vmod_convert_blob **blobp, const char *vcl_name,
assert(errno == EINVAL);
free(b->blob.priv);
b->blob.priv = NULL;
AZ(pthread_mutex_destroy(&b->lock));
VERR(ctx, "cannot create blob %s, illegal encoding beginning "
"with \"%s\"", vcl_name, p);
return;
......@@ -250,6 +255,64 @@ vmod_blob_get(VRT_CTX, struct vmod_convert_blob *b)
return &b->blob;
}
VCL_STRING
vmod_blob_encode(VRT_CTX, struct vmod_convert_blob *b, VCL_ENUM encs)
{
enum encoding enc = parse_encoding(encs);
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
CHECK_OBJ_NOTNULL(b, VMOD_CONVERT_BLOB_MAGIC);
if (b->blob.len == 0)
return "";
if (b->encoding[enc] == NULL) {
AZ(pthread_mutex_lock(&b->lock));
if (b->encoding[enc] == NULL) {
ssize_t len;
switch(enc) {
case IDENTITY:
len = b->blob.len + 1;
break;
case HEXUC:
case HEXLC:
len = hex_encode_l(b->blob.len);
break;
case BASE64:
case BASE64URL:
len = base64_encode_l(b->blob.len);
break;
case BASE64URLNOPAD:
len = base64nopad_encode_l(b->blob.len);
break;
default:
WRONG("Illegal encoding");
}
assert(len >= 0);
if (len == 0)
b->encoding[enc] = "";
else {
b->encoding[enc] = malloc(len);
if (b->encoding[enc] == NULL)
ERRNOMEM(ctx, "cannot encode");
else {
len = encode(enc,
(void *) b->encoding[enc],
len, b->blob.priv,
b->blob.len);
assert(len >= 0);
if (len == 0) {
free((void *) b->encoding[enc]);
b->encoding[enc] = "";
}
}
}
}
AZ(pthread_mutex_unlock(&b->lock));
}
return b->encoding[enc];
}
VCL_VOID __match_proto__(td_convert_blob__fini)
vmod_blob__fini(struct vmod_convert_blob **blobp)
{
......@@ -259,8 +322,16 @@ vmod_blob__fini(struct vmod_convert_blob **blobp)
b = *blobp;
*blobp = NULL;
CHECK_OBJ_NOTNULL(b, VMOD_CONVERT_BLOB_MAGIC);
if (b->blob.priv != NULL)
if (b->blob.priv != NULL) {
free(b->blob.priv);
b->blob.priv = NULL;
}
for (int i = 0; i < __MAX_ENCODING; i++)
if (b->encoding[i] != NULL && b->encoding[i][0] != '\0') {
free((void *) b->encoding[i]);
b->encoding[i] = NULL;
}
AZ(pthread_mutex_destroy(&b->lock));
FREE_OBJ(b);
}
......
......@@ -18,6 +18,8 @@ $Object blob(ENUM { IDENTITY, BASE64, BASE64URL, BASE64URLNOPAD, HEX} decoding,
$Method BLOB .get()
$Method STRING .encode(ENUM { IDENTITY, BASE64, BASE64URL, BASE64URLNOPAD, HEXUC, HEXLC} encoding)
$Function BLOB decode(ENUM { IDENTITY, BASE64, BASE64URL, BASE64URLNOPAD, HEX} decoding, STRING_LIST encoded)
XXX DOC
$Function STRING encode(ENUM { IDENTITY, BASE64, BASE64URL, BASE64URLNOPAD, HEXUC, HEXLC} encoding, BLOB blob)
......
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