[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