[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