Commit 4ddb72ca authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Parse Structured Fields (upcoming RFC) sf-binaries as static BLOBs in VCL.

parent d044efa1
......@@ -13,6 +13,7 @@ varnish v1 -vcl+backend {
}
sub vcl_deliver {
set resp.http.req_hash = blob.encode(HEX, blob=req.hash);
set resp.http.req_hash-sf = req.hash;
}
} -start
......@@ -21,4 +22,5 @@ client c1 {
rxresp
expect resp.http.req_hash ~ "[[:xdigit:]]{64}"
expect resp.http.req_hash == resp.http.bereq_hash
expect resp.http.req_hash-sf == ":d9gz676uHvX8wU6y/pTPI6fRK/XVgpJuGZtogIxniLA=:"
} -run
varnishtest "SF-blob parsing in VCL"
varnishtest "SF-binary/BLOB parsing in VCL"
varnish v1 -errvcl "BLOB must have n*3 base64 characters" { sub vcl_recv { :a: } }
varnish v2 -errvcl "BLOB must have n*3 base64 characters" { sub vcl_recv { :aa: } }
varnish v3 -errvcl "Illegal BLOB character:" { sub vcl_recv { :aa?: } }
varnish v4 -errvcl "BLOB must have n*3 base64 characters" { sub vcl_recv { :aaaa: } }
varnish v5 -errvcl "Wrong padding ('=') in BLOB" { sub vcl_recv { :aaa=aa: } }
varnish v6 -errvcl "Wrong padding ('=') in BLOB" { sub vcl_recv { :aaa==a: } }
varnish v7 -errvcl "Wrong padding ('=') in BLOB" { sub vcl_recv { :aaaa=a: } }
varnish v8 -errvcl "BLOB is not supported yet" { sub vcl_recv { :aaaa==: } }
varnish v1 -errvcl "BLOB must have n*4 base64 characters" { sub vcl_recv { :a: } }
varnish v1 -errvcl "BLOB must have n*4 base64 characters" { sub vcl_recv { :bbbbaa: } }
varnish v1 -errvcl "BLOB must have n*4 base64 characters" { sub vcl_recv { :bbbbccccaaa: } }
varnish v1 -errvcl "Illegal BLOB character:" { sub vcl_recv { :aa?: } }
varnish v1 -errvcl "Wrong padding ('=') in BLOB" { sub vcl_recv { :aaaa=aa: } }
varnish v1 -errvcl "Wrong padding ('=') in BLOB" { sub vcl_recv { :aaaa==a: } }
varnish v1 -errvcl "Wrong padding ('=') in BLOB" { sub vcl_recv { :aaaaa=a: } }
varnish v1 -errvcl "Missing colon at end of BLOB" " sub vcl_recv { :aaaa"
varnish v1 -errvcl "Missing colon at end of BLOB" " sub vcl_recv { :"
# hint: the 'B' leaves bits in the second output byte
varnish v1 -errvcl "Illegal BLOB character:" { sub vcl_recv { :AB==: } }
varnishtest "Test VMOD BLOBS"
varnish v1 -errvcl {BLOBs can only be used as arguments to VMOD functions.} {
backend b1 {.host = "${bad_backend}";}
sub vcl_deliver {
set resp.http.foo = req.hash;
}
}
varnish v1 -errvcl {Expression has type STRING, expected BLOB} {
backend b1 {.host = "${bad_backend}";}
import blob;
sub vcl_deliver {
blob.encode(blob = "blob");
}
}
......@@ -73,8 +73,11 @@ tokens = {
"CNUM": None,
"FNUM": None,
"CSTR": None,
"EOI": None,
"CSRC": None,
"CBLOB": None,
# End of token list
"EOI": None,
}
#######################################################################
......
......@@ -825,6 +825,15 @@ vcc_expr5(struct vcc *tl, struct expr **e, vcc_type_t fmt)
e1->constant = EXPR_CONST;
*e = e1;
return;
case CBLOB:
e1 = vcc_new_expr(BLOB);
VSB_printf(e1->vsb, "%s", tl->t->dec);
AZ(VSB_finish(e1->vsb));
e1->constant |= EXPR_STR_CONST;
e1->t1 = tl->t;
vcc_NextToken(tl);
*e = e1;
return;
default:
break;
}
......
......@@ -36,7 +36,9 @@
#include "vcc_compile.h"
#include "venc.h"
#include "vct.h"
#include "vsb.h"
/*--------------------------------------------------------------------*/
......@@ -390,6 +392,8 @@ vcc_Lexer(struct vcc *tl, const struct source *sp, int eoi)
{
const char *p, *q, *r;
unsigned u;
struct vsb *vsb;
char namebuf[40];
for (p = sp->b; p < sp->e; ) {
......@@ -485,45 +489,64 @@ vcc_Lexer(struct vcc *tl, const struct source *sp, int eoi)
/* Recognize BLOB (= SF-binary) */
if (*p == ':') {
r = NULL;
for (q = p + 1; q < sp->e && vct_isbase64(*q); q++) {
if (r == NULL && *q == '=')
r = q;
}
if (q == sp->e || *q != ':') {
vsb = VSB_new_auto();
AN(vsb);
q = sp->e;
q -= (q - (p + 1)) % 4;
assert(q > p);
r = VENC_Decode_Base64(vsb, p + 1, q);
if (r == NULL) {
vcc_addtoken(tl, CBLOB, sp, p, q + 1);
VSB_cat(tl->sb,
"Illegal BLOB character:\n");
vcc_addtoken(tl, EOI, sp, q, q+1);
"Missing colon at end of BLOB:\n");
vcc_ErrWhere(tl, tl->t);
VSB_destroy(&vsb);
return;
}
if ((q - p) % 3 != 1) {
u = ((q - 1) - p) / 3;
vcc_addtoken(tl, EOI, sp, p + u * 3 + 1, q);
vcc_addtoken(tl, CBLOB, sp, p, r + 1);
if (*r == ':' && ((r - p) % 4) != 1) {
VSB_cat(tl->sb,
"BLOB must have n*3 base64 characters\n");
"BLOB must have n*4 base64 characters\n");
vcc_ErrWhere(tl, tl->t);
VSB_destroy(&vsb);
return;
}
if (r == NULL) {
/* No padding; */
} else if (r + 1 == q) {
/* One pad char */
} else if (r + 2 == q && r[1] == '=') {
/* Two (valid) pad chars */
} else {
if (*r == '=') {
VSB_cat(tl->sb,
"Wrong padding ('=') in BLOB:\n");
vcc_addtoken(tl, EOI, sp, r, r+1);
vcc_ErrWhere(tl, tl->t);
VSB_destroy(&vsb);
return;
}
p = q + 1;
vcc_addtoken(tl, EOI, sp, p, q);
VSB_cat(tl->sb,
"BLOB is not supported yet.\n");
vcc_ErrWhere(tl, tl->t);
return;
if (*r != ':') {
VSB_cat(tl->sb, "Illegal BLOB character:\n");
vcc_ErrWhere(tl, tl->t);
VSB_destroy(&vsb);
return;
}
r++;
AZ(VSB_finish(vsb));
bprintf(namebuf, "blob_%u", tl->unique++);
Fh(tl, 0, "\nconst unsigned char %s_data[%zd] = {\n",
namebuf, VSB_len(vsb));
for (u = 0; u < VSB_len(vsb); u++) {
Fh(tl, 0, "\t0x%02x,", VSB_data(vsb)[u] & 0xff);
if ((u & 7) == 7)
Fh(tl, 0, "\n");
}
if ((u & 7) != 7)
Fh(tl, 0, "\n");
Fh(tl, 0, "};\n");
Fh(tl, 0, "\nconst struct vrt_blob %s[1] = {{\n",
namebuf);
Fh(tl, 0, "\t.len =\t%zd,\n", VSB_len(vsb));
Fh(tl, 0, "\t.blob =\t%s_data,\n", namebuf);
Fh(tl, 0, "}};\n");
REPLACE(tl->t->dec, namebuf);
VSB_destroy(&vsb);
p = r;
continue;
}
/* Match for the fixed tokens (see generate.py) */
......
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