Updated.

On Mon, Apr 20, 2015 at 9:33 PM, Poul-Henning Kamp <[email protected]>
wrote:

> --------
> In message <
> cajv_h0bcyloktmbeg8xm35z3ep_lrmwk4smdyvuuhn-nnm5...@mail.gmail.com>
> , Federico Schwindt writes:
>
> >Duh! New diff attached. Documentation and tests remaining. Something like
> >this?
>
> I would prefer to put it in vmod_std, rather than special-case
> it in VCC...
>
> >Should we keep hash_data() or rename it to hash_string() or something
> >similar?
>
> I would just leave that alone, and add std.hash_blob() for the special
> use-cases.
>
> --
> Poul-Henning Kamp       | UNIX since Zilog Zeus 3.20
> [email protected]         | TCP/IP since RFC 956
> FreeBSD committer       | BSD since 4.3-tahoe
> Never attribute to malice what can adequately be explained by incompetence.
>
diff --git a/bin/varnishd/cache/cache_hash.c b/bin/varnishd/cache/cache_hash.c
index 8a15757..9ce66ae 100644
--- a/bin/varnishd/cache/cache_hash.c
+++ b/bin/varnishd/cache/cache_hash.c
@@ -61,6 +61,7 @@
 #include "hash/hash_slinger.h"
 #include "vsha256.h"
 #include "vtim.h"
+#include "vrt.h"
 
 static const struct hash_slinger *hash;
 static struct objhead *private_oh;
@@ -199,6 +200,19 @@ HSH_AddString(struct req *req, const char *str)
 		SHA256_Update(req->sha256ctx, &str, sizeof str);
 }
 
+void
+HSH_AddBlob(struct req *req, const struct vmod_priv *priv)
+{
+
+	CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
+	AN(req->sha256ctx);
+	if (priv != NULL) {
+		SHA256_Update(req->sha256ctx, priv->priv, priv->len);
+		VSLb(req->vsl, SLT_Hash, "%.*s", priv->len, priv->priv);
+	} else
+		SHA256_Update(req->sha256ctx, &priv, sizeof priv);
+}
+
 /*---------------------------------------------------------------------
  * This is a debugging hack to enable testing of boundary conditions
  * in the hash algorithm.
diff --git a/bin/varnishd/hash/hash_slinger.h b/bin/varnishd/hash/hash_slinger.h
index 6f546ff..59acf3c 100644
--- a/bin/varnishd/hash/hash_slinger.h
+++ b/bin/varnishd/hash/hash_slinger.h
@@ -34,6 +34,7 @@ struct objcore;
 struct busyobj;
 struct worker;
 struct object;
+struct vmod_priv;
 
 typedef void hash_init_f(int ac, char * const *av);
 typedef void hash_start_f(void);
@@ -67,6 +68,7 @@ enum lookup_e HSH_Lookup(struct req *, struct objcore **, struct objcore **,
     int wait_for_busy, int always_insert);
 void HSH_Ref(struct objcore *o);
 void HSH_Init(const struct hash_slinger *slinger);
+void HSH_AddBlob(struct req *, const struct vmod_priv *);
 void HSH_AddString(struct req *, const char *str);
 void HSH_Insert(struct worker *, const void *hash, struct objcore *);
 void HSH_Purge(struct worker *, struct objhead *, double ttl, double grace,
diff --git a/bin/varnishtest/tests/m00022.vtc b/bin/varnishtest/tests/m00022.vtc
new file mode 100644
index 0000000..9c83751
--- /dev/null
+++ b/bin/varnishtest/tests/m00022.vtc
@@ -0,0 +1,28 @@
+varnishtest "Test std.hash_blob()"
+
+server s1 {
+	rxreq
+	txresp
+} -start
+
+varnish v1 -arg "-p vsl_mask=+Hash" -vcl+backend {
+	import ${vmod_debug};
+	import ${vmod_std};
+
+	sub vcl_hash {
+		std.hash_blob(debug.str2blob("gunk"));
+	}
+} -start
+
+logexpect l1 -v v1 {
+	expect * 1001 Hash "gunk"
+	expect 0 1001 Hash "/"
+	expect 0 1001 Hash "127.0.0.1"
+} -start
+
+client c1 {
+	txreq
+	rxresp
+} -run
+
+logexpect l1 -wait
diff --git a/lib/libvmod_std/vmod.vcc b/lib/libvmod_std/vmod.vcc
index 288a1ed..08e5198 100644
--- a/lib/libvmod_std/vmod.vcc
+++ b/lib/libvmod_std/vmod.vcc
@@ -256,6 +256,13 @@ Example
 	|     ...
 	| }
 
+$Function VOID hash_blob(BLOB blob)
+
+Description
+	Adds a blob to the hash input.  Available in vcl_hash.
+Example
+	hash_blob(req.body);
+
 
 SEE ALSO
 ========
diff --git a/lib/libvmod_std/vmod_std.c b/lib/libvmod_std/vmod_std.c
index 097cd45..c9fe19b 100644
--- a/lib/libvmod_std/vmod_std.c
+++ b/lib/libvmod_std/vmod_std.c
@@ -37,6 +37,7 @@
 #include <stdlib.h>
 #include <syslog.h>
 
+#include "vcl.h"
 #include "vrt.h"
 #include "vtcp.h"
 #include "vsa.h"
@@ -45,6 +46,8 @@
 #include "cache/cache.h"
 #include "cache/cache_director.h"
 
+#include "hash/hash_slinger.h"
+
 #include "vcc_if.h"
 
 VCL_VOID __match_proto__(td_std_set_ip_tos)
@@ -248,3 +251,21 @@ vmod_strstr(VRT_CTX, VCL_STRING s1, VCL_STRING s2)
 	return (strstr(s1, s2));
 }
 
+VCL_VOID __match_proto__(td_std_hash_blob)
+vmod_hash_blob(VRT_CTX, VCL_BLOB blob)
+{
+
+	CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
+	CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
+	if (ctx->method != VCL_MET_HASH) {
+		VSLb(ctx->vsl, SLT_VCL_Error,
+		    "std.hash_body() can only be called in vcl_hash{}");
+		return;
+	}
+	HSH_AddBlob(ctx->req, blob);
+	/*
+	 * Add a 'field-separator' to make it more difficult to
+	 * manipulate the hash.
+	 */
+	HSH_AddString(ctx->req, NULL);
+}
_______________________________________________
varnish-dev mailing list
[email protected]
https://www.varnish-cache.org/lists/mailman/listinfo/varnish-dev

Reply via email to