[master] 7078960 Introduce VCL_BLOB type which VMOD functions can use to pass random bits of memory to each other.
Poul-Henning Kamp
phk at FreeBSD.org
Fri Dec 13 13:23:28 CET 2013
commit 70789601e2246ceead87f62c17cd1eb8bdb9025d
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date: Fri Dec 13 12:21:45 2013 +0000
Introduce VCL_BLOB type which VMOD functions can use to pass
random bits of memory to each other.
I have added a "len" field to the vmod_priv structure and used that
for BLOB's.
We may need some memory-mgt beauty/convenience functions for this.
diff --git a/bin/varnishtest/tests/m00012.vtc b/bin/varnishtest/tests/m00012.vtc
new file mode 100644
index 0000000..ef07f90
--- /dev/null
+++ b/bin/varnishtest/tests/m00012.vtc
@@ -0,0 +1,44 @@
+varnishtest "Test VMOD BLOBS"
+
+server s1 {
+ rxreq
+ txresp
+} -start
+
+varnish v1 -vcl+backend {
+ import ${vmod_debug};
+
+ sub vcl_deliver {
+ set resp.http.foo = debug.blob2hex(debug.str2blob("gunk"));
+ }
+} -start
+
+client c1 {
+ txreq
+ rxresp
+ expect resp.http.foo == 67756e6b
+} -run
+
+delay .1
+
+varnish v1 -errvcl {BLOBs can only be used as arguments to VMOD functions.} {
+
+ backend b1 {.host = "127.0.0.1";}
+
+ import ${vmod_debug};
+
+ sub vcl_deliver {
+ set resp.http.foo = debug.str2blob("gunk");
+ }
+}
+
+varnish v1 -errvcl {Wrong argument type. Expected BLOB. Got STRING.} {
+
+ backend b1 {.host = "127.0.0.1";}
+
+ import ${vmod_debug};
+
+ sub vcl_deliver {
+ set resp.http.foo = debug.blob2hex("gunk");
+ }
+}
diff --git a/include/vrt.h b/include/vrt.h
index 6dfefee..ecf0831 100644
--- a/include/vrt.h
+++ b/include/vrt.h
@@ -61,6 +61,7 @@ typedef double VCL_REAL;
typedef const char * VCL_STRING;
typedef double VCL_TIME;
typedef void VCL_VOID;
+typedef const struct vmod_priv * VCL_BLOB;
/***********************************************************************
* This is the composite argument we pass to compiled VCL and VRT
@@ -238,6 +239,7 @@ struct vmod_priv;
typedef void vmod_priv_free_f(void *);
struct vmod_priv {
void *priv;
+ int len;
vmod_priv_free_f *free;
};
diff --git a/lib/libvcc/vcc_expr.c b/lib/libvcc/vcc_expr.c
index c868656..f9c5a83 100644
--- a/lib/libvcc/vcc_expr.c
+++ b/lib/libvcc/vcc_expr.c
@@ -392,7 +392,7 @@ vcc_arg_type(const char **p)
*/
static void
-vcc_expr_tostring(struct expr **e, enum var_type fmt)
+vcc_expr_tostring(struct vcc *tl, struct expr **e, enum var_type fmt)
{
const char *p;
uint8_t constant = EXPR_VAR;
@@ -423,6 +423,13 @@ vcc_expr_tostring(struct expr **e, enum var_type fmt)
case STRING:
case STRING_LIST:
break;
+ case BLOB:
+ VSB_printf(tl->sb,
+ "Wrong use of BLOB value.\n"
+ "BLOBs can only be used as arguments to VMOD"
+ " functions.\n");
+ vcc_ErrWhere2(tl, (*e)->t1, tl->t);
+ return;
default:
INCOMPL();
break;
@@ -451,8 +458,10 @@ vcc_Eval_Regsub(struct vcc *tl, struct expr **e, const struct symbol *sym)
vcc_expr0(tl, &e2, STRING);
if (e2 == NULL)
return;
- if (e2->fmt != STRING)
- vcc_expr_tostring(&e2, STRING);
+ if (e2->fmt != STRING) {
+ vcc_expr_tostring(tl, &e2, STRING);
+ ERRCHK(tl);
+ }
SkipToken(tl, ',');
ExpectErr(tl, CSTR);
@@ -466,8 +475,10 @@ vcc_Eval_Regsub(struct vcc *tl, struct expr **e, const struct symbol *sym)
vcc_expr0(tl, &e2, STRING);
if (e2 == NULL)
return;
- if (e2->fmt != STRING)
- vcc_expr_tostring(&e2, STRING);
+ if (e2->fmt != STRING) {
+ vcc_expr_tostring(tl, &e2, STRING);
+ ERRCHK(tl);
+ }
*e = vcc_expr_edit(STRING, "\v1,\n\v2)\v-", *e, e2);
SkipToken(tl, ')');
}
@@ -817,8 +828,10 @@ vcc_expr_string_add(struct vcc *tl, struct expr **e)
vcc_NextToken(tl);
vcc_expr_mul(tl, &e2, STRING);
ERRCHK(tl);
- if (e2->fmt != STRING && e2->fmt != STRING_LIST)
- vcc_expr_tostring(&e2, f2);
+ if (e2->fmt != STRING && e2->fmt != STRING_LIST) {
+ vcc_expr_tostring(tl, &e2, f2);
+ ERRCHK(tl);
+ }
ERRCHK(tl);
assert(e2->fmt == STRING || e2->fmt == STRING_LIST);
@@ -857,7 +870,8 @@ vcc_expr_add(struct vcc *tl, struct expr **e, enum var_type fmt)
/* Unless we specifically ask for a HEADER, fold them to string here */
if (fmt != HEADER && f2 == HEADER) {
- vcc_expr_tostring(e, STRING);
+ vcc_expr_tostring(tl, e, STRING);
+ ERRCHK(tl);
f2 = (*e)->fmt;
assert(f2 == STRING);
}
@@ -1184,8 +1198,11 @@ vcc_Expr(struct vcc *tl, enum var_type fmt)
t1 = tl->t;
vcc_expr0(tl, &e, fmt);
ERRCHK(tl);
- if (fmt == STRING || fmt == STRING_LIST)
- vcc_expr_tostring(&e, fmt);
+ e->t1 = t1;
+ if (fmt == STRING || fmt == STRING_LIST) {
+ vcc_expr_tostring(tl, &e, fmt);
+ ERRCHK(tl);
+ }
if (!tl->err && fmt != e->fmt) {
VSB_printf(tl->sb, "Expression has type %s, expected %s\n",
vcc_Type(e->fmt), vcc_Type(fmt));
diff --git a/lib/libvcc/vmodtool.py b/lib/libvcc/vmodtool.py
index af52ec5..6249b36 100755
--- a/lib/libvcc/vmodtool.py
+++ b/lib/libvcc/vmodtool.py
@@ -60,6 +60,7 @@ ctypes = {
'STRING_LIST': "const char *, ...",
'TIME': "VCL_TIME",
'VOID': "VCL_VOID",
+ 'BLOB': "VCL_BLOB",
}
#######################################################################
@@ -381,7 +382,7 @@ class func(object):
fo.write(s + ")\n")
for i in self.doc_str:
fo.write(i + "\n")
-
+
#######################################################################
diff --git a/lib/libvmod_debug/vmod.vcc b/lib/libvmod_debug/vmod.vcc
index 69bfb38..f24c302 100644
--- a/lib/libvmod_debug/vmod.vcc
+++ b/lib/libvmod_debug/vmod.vcc
@@ -53,6 +53,14 @@ $Function VOID test_priv_vcl(PRIV_VCL)
Test function for VCL private pointers
+$Function BLOB str2blob(STRING)
+
+Turn a string into a blob
+
+$Function STRING blob2hex(BLOB)
+
+Hexdump a blob
+
$Object obj(STRING)
Test object
diff --git a/lib/libvmod_debug/vmod_debug.c b/lib/libvmod_debug/vmod_debug.c
index e864880..4031e6e 100644
--- a/lib/libvmod_debug/vmod_debug.c
+++ b/lib/libvmod_debug/vmod_debug.c
@@ -29,6 +29,7 @@
#include "config.h"
#include <stdlib.h>
+#include <stdio.h>
#include "cache/cache.h"
@@ -94,3 +95,38 @@ vmod_test_priv_vcl(const struct vrt_ctx *ctx, struct vmod_priv *priv)
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
assert(!strcmp(priv->priv, "FOO"));
}
+
+VCL_BLOB
+vmod_str2blob(const struct vrt_ctx *ctx, VCL_STRING s)
+{
+ struct vmod_priv *p;
+
+ CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
+ p = (void*)WS_Alloc(ctx->ws, sizeof *p);
+ AN(p);
+ memset(p, 0, sizeof *p);
+ p->len = strlen(s);
+ p->priv = WS_Copy(ctx->ws, s, -1);
+ return (p);
+}
+
+VCL_STRING
+vmod_blob2hex(const struct vrt_ctx *ctx, VCL_BLOB b)
+{
+ char *s, *p;
+ uint8_t *q;
+ int i;
+
+ s = WS_Alloc(ctx->ws, b->len * 2 + 2);
+ AN(s);
+ p = s;
+ q = b->priv;
+ for (i = 0; i < b->len; i++) {
+ sprintf(p, "%02x", *q);
+ p += 2;
+ q += 1;
+ }
+ vmod_priv_fini(b);
+ return (s);
+}
+
More information about the varnish-commit
mailing list