[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