[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