Commit b9e6d624 authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

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

parent 70b1004c
......@@ -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 */
......
......@@ -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);
......
......@@ -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)
......@@ -638,6 +636,30 @@ http_FilterResp(const struct http *fm, struct http *to, unsigned how)
http_filterfields(to, fm, 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.
......
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
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment