[master] 5969b8a Optimize VRT_String() to not copy if the result is already present in the desired workspace.

Poul-Henning Kamp phk at FreeBSD.org
Thu Feb 8 10:12:07 UTC 2018


commit 5969b8adc213864d5ef3ae241d4d1459250f1db3
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Thu Feb 8 10:09:33 2018 +0000

    Optimize VRT_String() to not copy if the result is already
    present in the desired workspace.
    
    I'm a little bit uneasy about the tacit assumption that arguments
    to VRT_String() now belong to VRT_String(), but we'll see how it
    goes.
    
    Fixes: #2132

diff --git a/bin/varnishd/cache/cache_vrt.c b/bin/varnishd/cache/cache_vrt.c
index cbb4f88..296fa45 100644
--- a/bin/varnishd/cache/cache_vrt.c
+++ b/bin/varnishd/cache/cache_vrt.c
@@ -252,11 +252,51 @@ const char *
 VRT_String(struct ws *ws, const char *h, const char *p, va_list ap)
 {
 	char *b, *e;
+	const char *q;
 	unsigned u, x;
+	va_list aq;
 
 	u = WS_Reserve(ws, 0);
 	e = b = ws->f;
 	e += u;
+
+	va_copy(aq, ap);
+	do
+		q = va_arg(aq, const char *);
+	while (q == NULL || (q != vrt_magic_string_end && *q == '\0'));
+
+	if (h != NULL && p == NULL && q == vrt_magic_string_end &&
+	    WS_Inside(ws, h, NULL)) {
+		va_end(aq);
+		WS_Release(ws, 0);
+		return (h);
+	}
+
+	if (h == NULL && p != NULL && q == vrt_magic_string_end &&
+	    WS_Inside(ws, p, NULL)) {
+		va_end(aq);
+		WS_Release(ws, 0);
+		return (p);
+	}
+
+	if (h == NULL && p == NULL) {
+		if (q == vrt_magic_string_end) {
+			va_end(aq);
+			WS_Release(ws, 0);
+			return ("");
+		}
+		do
+			p = va_arg(aq, const char *);
+		while (p == NULL || (p != vrt_magic_string_end && *p == '\0'));
+		if (p == vrt_magic_string_end && WS_Inside(ws, q, NULL)) {
+			va_end(aq);
+			WS_Release(ws, 0);
+			return (q);
+		}
+		p = NULL;
+		va_end(aq);
+	}
+
 	if (h != NULL) {
 		x = strlen(h);
 		if (b + x < e)
diff --git a/bin/varnishtest/tests/c00074.vtc b/bin/varnishtest/tests/c00074.vtc
index abf886a..2231ba1 100644
--- a/bin/varnishtest/tests/c00074.vtc
+++ b/bin/varnishtest/tests/c00074.vtc
@@ -16,6 +16,10 @@ varnish v1 -vcl+backend {
 		vtc.workspace_snapshot(session);
 		vtc.workspace_reset(session);
 		set req.http.ws-free3 = vtc.workspace_free(session);
+
+		# Cover an obscure case in VRT_String() while here
+		set req.http.bar = vtc.typesize(
+			req.http.h1 + req.http.h2 + req.http.h3);
 	}
 } -start
 
@@ -26,7 +30,7 @@ logexpect l1 -v v1 -g request {
 } -start
 
 client c1 {
-	txreq -url /foo
+	txreq -url /foo -hdr "h3: dd"
 	rxresp
 	expect resp.status == 200
 } -run
diff --git a/bin/varnishtest/tests/r00781.vtc b/bin/varnishtest/tests/r00781.vtc
index 2c3562a..0660583 100644
--- a/bin/varnishtest/tests/r00781.vtc
+++ b/bin/varnishtest/tests/r00781.vtc
@@ -9,12 +9,24 @@ varnish v1 -vcl+backend {
 	sub vcl_recv {
 		set req.url = req.http.foo;
 	}
+} -start
+
+client c1 {
+	txreq
+	rxresp
+	expect resp.status == 503
+	expect resp.reason == "VCL failed"
+} -run
+
+varnish v1 -vcl+backend {
 	sub vcl_backend_fetch {
 		set bereq.url = bereq.http.foo;
 	}
-} -start
+}
 
 client c1 {
 	txreq
 	rxresp
+	expect resp.status == 503
+	expect resp.reason == "Service Unavailable"
 } -run


More information about the varnish-commit mailing list