Mailing List Archive

[master] 4ddb72ca1 Parse Structured Fields (upcoming RFC) sf-binaries as static BLOBs in VCL.
commit 4ddb72ca18e9b090890493504f7cefac735ff0aa
Author: Poul-Henning Kamp <phk@FreeBSD.org>
Date: Fri Aug 7 08:36:02 2020 +0000

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

diff --git a/bin/varnishtest/tests/b00051.vtc b/bin/varnishtest/tests/b00051.vtc
index c6a012509..5b65e7590 100644
--- a/bin/varnishtest/tests/b00051.vtc
+++ b/bin/varnishtest/tests/b00051.vtc
@@ -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
diff --git a/bin/varnishtest/tests/i00000.vtc b/bin/varnishtest/tests/i00000.vtc
index 14849f336..4767205d4 100644
--- a/bin/varnishtest/tests/i00000.vtc
+++ b/bin/varnishtest/tests/i00000.vtc
@@ -1,10 +1,14 @@
-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==: } }
diff --git a/bin/varnishtest/tests/m00012.vtc b/bin/varnishtest/tests/m00012.vtc
deleted file mode 100644
index 33f25c7c6..000000000
--- a/bin/varnishtest/tests/m00012.vtc
+++ /dev/null
@@ -1,21 +0,0 @@
-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");
- }
-}
diff --git a/lib/libvcc/generate.py b/lib/libvcc/generate.py
index 86112f640..12b8c417e 100755
--- a/lib/libvcc/generate.py
+++ b/lib/libvcc/generate.py
@@ -73,8 +73,11 @@ tokens = {
"CNUM": None,
"FNUM": None,
"CSTR": None,
- "EOI": None,
"CSRC": None,
+ "CBLOB": None,
+
+ # End of token list
+ "EOI": None,
}

#######################################################################
diff --git a/lib/libvcc/vcc_expr.c b/lib/libvcc/vcc_expr.c
index 60a29b585..182cff8e1 100644
--- a/lib/libvcc/vcc_expr.c
+++ b/lib/libvcc/vcc_expr.c
@@ -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;
}
diff --git a/lib/libvcc/vcc_token.c b/lib/libvcc/vcc_token.c
index fa2d504cf..00e21b414 100644
--- a/lib/libvcc/vcc_token.c
+++ b/lib/libvcc/vcc_token.c
@@ -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) */
_______________________________________________
varnish-commit mailing list
varnish-commit@varnish-cache.org
https://www.varnish-cache.org/lists/mailman/listinfo/varnish-commit