[4.0] b9e6d62 Add code to do the right "backwards" merge of IMS responses.

Poul-Henning Kamp phk at FreeBSD.org
Thu Mar 13 10:24:30 CET 2014


commit b9e6d624e0f07d1de469dcc7f9b1df385482c7c8
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Wed Mar 5 08:23:51 2014 +0000

    Add code to do the right "backwards" merge of IMS responses.

diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h
index 7c6079e..f18c69a 100644
--- a/bin/varnishd/cache/cache.h
+++ b/bin/varnishd/cache/cache.h
@@ -192,6 +192,7 @@ struct http {
 	txt			*hd;
 	unsigned char		*hdf;
 #define HDF_FILTER		(1 << 0)	/* Filtered by Connection */
+#define HDF_MARKER		(1 << 1)	/* Marker bit */
 	uint16_t		shd;		/* Size of hd space */
 	uint16_t		nhd;		/* Next free hd */
 	uint16_t		status;
@@ -997,6 +998,7 @@ void http_CopyHome(const struct http *hp);
 void http_Unset(struct http *hp, const char *hdr);
 void http_CollectHdr(struct http *hp, const char *hdr);
 void http_VSL_log(const struct http *hp);
+void http_Merge(const struct http *fm, struct http *to);
 
 /* cache_http1_proto.c */
 
diff --git a/bin/varnishd/cache/cache_fetch.c b/bin/varnishd/cache/cache_fetch.c
index 2d5f5ae..20b60fe 100644
--- a/bin/varnishd/cache/cache_fetch.c
+++ b/bin/varnishd/cache/cache_fetch.c
@@ -339,8 +339,7 @@ vbf_stp_startfetch(struct worker *wrk, struct busyobj *bo)
 
 	if (bo->ims_obj != NULL && bo->beresp->status == 304) {
 		bo->beresp->status = 200;
-		http_PrintfHeader(bo->beresp, "Content-Length: %jd",
-		    (intmax_t)bo->ims_obj->len);
+		http_Merge(bo->ims_obj->http, bo->beresp);
 		do_ims = 1;
 	} else
 		do_ims = 0;
@@ -567,7 +566,7 @@ vbf_stp_condfetch(struct worker *wrk, struct busyobj *bo)
 		l += vl;
 	} else
 		vl = 0;
-	l += http_EstimateWS(bo->ims_obj->http, 0, &nhttp);
+	l += http_EstimateWS(bo->beresp, 0, &nhttp);
 
 	obj = vbf_allocobj(bo, l, nhttp);
 	if (obj == NULL) {
@@ -603,7 +602,7 @@ vbf_stp_condfetch(struct worker *wrk, struct busyobj *bo)
 
 	obj->http->logtag = SLT_ObjMethod;
 	/* XXX: we should have our own HTTP_A_CONDFETCH */
-	http_FilterResp(bo->ims_obj->http, obj->http, HTTPH_A_INS);
+	http_FilterResp(bo->beresp, obj->http, HTTPH_A_INS);
 	http_CopyHome(obj->http);
 
 
diff --git a/bin/varnishd/cache/cache_http.c b/bin/varnishd/cache/cache_http.c
index ec28396..2a9b8de 100644
--- a/bin/varnishd/cache/cache_http.c
+++ b/bin/varnishd/cache/cache_http.c
@@ -254,7 +254,6 @@ http_CollectHdr(struct http *hp, const char *hdr)
 	WS_ReleaseP(hp->ws, b + 1);
 }
 
-
 /*--------------------------------------------------------------------*/
 
 static unsigned
@@ -300,7 +299,6 @@ http_GetHdr(const struct http *hp, const char *hdr, char **ptr)
 	return (1);
 }
 
-
 /*--------------------------------------------------------------------
  * Find a given data element in a header according to RFC2616's #rule
  * (section 2.1, p15)
@@ -639,6 +637,30 @@ http_FilterResp(const struct http *fm, struct http *to, unsigned how)
 }
 
 /*--------------------------------------------------------------------
+ * Merge two HTTP headers the "wrong" way.
+ */
+
+void
+http_Merge(const struct http *fm, struct http *to)
+{
+	unsigned u, v;
+	const char *p;
+
+	for (u = HTTP_HDR_FIRST; u < fm->nhd; u++)
+		fm->hdf[u] |= HDF_MARKER;
+	for (v = HTTP_HDR_FIRST; v < to->nhd; v++) {
+		p = strchr(to->hd[v].b, ':');
+		AN(p);
+		u = http_findhdr(fm, p - to->hd[v].b, to->hd[v].b);
+		if (u)
+			fm->hdf[u] &= ~HDF_MARKER;
+	}
+	for (u = HTTP_HDR_FIRST; u < fm->nhd; u++)
+		if (fm->hdf[u] & HDF_MARKER)
+			http_SetHeader(to, fm->hd[u].b);
+}
+
+/*--------------------------------------------------------------------
  * This function copies any header fields which reference foreign
  * storage into our own WS.
  */
diff --git a/bin/varnishtest/tests/c00060.vtc b/bin/varnishtest/tests/c00060.vtc
new file mode 100644
index 0000000..ece157e
--- /dev/null
+++ b/bin/varnishtest/tests/c00060.vtc
@@ -0,0 +1,45 @@
+varnishtest "IMS header merging"
+
+server s1 {
+	rxreq
+	txresp -hdr "Last-Modified: Thu, 26 Jun 2008 12:00:01 GMT" \
+		-hdr "Foobar: foo" \
+		-hdr "Snafu: 1" \
+		-bodylen 13
+	rxreq
+	expect req.http.if-modified-since == "Thu, 26 Jun 2008 12:00:01 GMT"
+	txresp -status "304" \
+		-hdr "Last-Modified: Thu, 26 Jun 2008 12:00:01 GMT" \
+		-hdr "Snafu: 2" \
+		-nolen
+
+} -start
+
+varnish v1 -vcl+backend {
+	sub vcl_backend_response {
+		set beresp.grace = 0s;
+		set beresp.keep = 60s;
+		set beresp.ttl = 1s;
+		if (beresp.http.foobar == "foo") {
+			set beresp.http.foobar = "foo0";
+		}
+		if (beresp.http.snafu == "2") {
+			set beresp.http.snafu = "2a";
+		}
+	}
+} -start
+
+client c1 {
+	txreq
+	rxresp
+	expect resp.bodylen == 13
+	expect resp.http.foobar == foo0
+	expect resp.http.snafu == 1
+	delay 3
+	txreq
+	rxresp
+	expect resp.bodylen == 13
+	expect resp.http.foobar == foo0
+	expect resp.http.snafu == 2a
+} -run
+



More information about the varnish-commit mailing list