[master] 9ee9923 Fix a problem in http_CollectHdr() where it would overlook the second of two headers in a row.
Poul-Henning Kamp
phk at varnish-cache.org
Mon Apr 18 10:09:43 CEST 2011
commit 9ee99237d6a3d6b584d6b2e5af32006a2af06284
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date: Mon Apr 18 08:09:09 2011 +0000
Fix a problem in http_CollectHdr() where it would overlook
the second of two headers in a row.
Fixes #902
diff --git a/bin/varnishd/cache_http.c b/bin/varnishd/cache_http.c
index b8cdb3a..3a7935b 100644
--- a/bin/varnishd/cache_http.c
+++ b/bin/varnishd/cache_http.c
@@ -189,44 +189,44 @@ http_CollectHdr(struct http *hp, const char *hdr)
char *b = NULL, *e = NULL;
for (u = HTTP_HDR_FIRST; u < hp->nhd; u++) {
- Tcheck(hp->hd[u]);
- if (!http_IsHdr(&hp->hd[u], hdr))
- continue;
- if (f == 0) {
- /* Found first header, just record the fact */
- f = u;
- continue;
- }
- if (b == NULL) {
- /* Found second header */
- ml = WS_Reserve(hp->ws, 0);
- b = hp->ws->f;
- e = b + ml;
- x = Tlen(hp->hd[f]);
+ while (u < hp->nhd && http_IsHdr(&hp->hd[u], hdr)) {
+ Tcheck(hp->hd[u]);
+ if (f == 0) {
+ /* Found first header, just record the fact */
+ f = u;
+ break;
+ }
+ if (b == NULL) {
+ /* Found second header, start our collection */
+ ml = WS_Reserve(hp->ws, 0);
+ b = hp->ws->f;
+ e = b + ml;
+ x = Tlen(hp->hd[f]);
+ if (b + x < e) {
+ memcpy(b, hp->hd[f].b, x);
+ b += x;
+ } else
+ b = e;
+ }
+
+ AN(b);
+ AN(e);
+
+ /* Append the Nth header we found */
+ if (b < e)
+ *b++ = ',';
+ x = Tlen(hp->hd[u]) - *hdr;
if (b + x < e) {
- memcpy(b, hp->hd[f].b, x);
+ memcpy(b, hp->hd[u].b + *hdr, x);
b += x;
} else
b = e;
- }
- AN(b);
- AN(e);
-
- /* Append the Nth header we found */
- if (b < e)
- *b++ = ',';
- x = Tlen(hp->hd[u]) - *hdr;
- if (b + x < e) {
- memcpy(b, hp->hd[u].b + *hdr, x);
- b += x;
- } else
- b = e;
-
- /* Shift remaining headers up one slot */
- for (v = u; v < hp->nhd + 1; v++)
- hp->hd[v] = hp->hd[v + 1];
- hp->nhd--;
+ /* Shift remaining headers up one slot */
+ for (v = u; v < hp->nhd - 1; v++)
+ hp->hd[v] = hp->hd[v + 1];
+ hp->nhd--;
+ }
}
if (b == NULL)
diff --git a/bin/varnishtest/tests/r00902.vtc b/bin/varnishtest/tests/r00902.vtc
new file mode 100644
index 0000000..e082529
--- /dev/null
+++ b/bin/varnishtest/tests/r00902.vtc
@@ -0,0 +1,27 @@
+# $Id$
+
+test "Ticket #902 http_CollectHdr() failure on consequitive headers"
+
+server s1 {
+ rxreq
+ txresp \
+ -hdr "Server: Microsoft-IIS/5.0" \
+ -hdr "Cache-Control: A" \
+ -hdr "Cache-Control: B" \
+ -hdr "Cache-Control: C" \
+ -hdr "Cache-Control: D" \
+ -hdr "Foo: bar" \
+ -bodylen 5
+} -start
+
+varnish v1 -vcl+backend {
+} -start
+
+varnish v1 -cliok "param.set diag_bitmap 1"
+
+client c1 {
+ txreq -hdr "foo: /foo"
+ rxresp
+ expect resp.http.cache-control == "A, B, C, D"
+ expect resp.http.foo == "bar"
+} -run
More information about the varnish-commit
mailing list