[master] 989cd35 Renovate how we VSL log HTTP headers, so that all changes, including unsets are logged.

Poul-Henning Kamp phk at FreeBSD.org
Wed Jan 8 11:49:47 CET 2014


commit 989cd35232fa33f42e6214ce553c00a0e9ce0a4f
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Wed Jan 8 10:49:11 2014 +0000

    Renovate how we VSL log HTTP headers, so that all changes, including
    unsets are logged.

diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h
index 58c1b3c..236ca87 100644
--- a/bin/varnishd/cache/cache.h
+++ b/bin/varnishd/cache/cache.h
@@ -991,6 +991,7 @@ void http_FilterReq(struct http *to, const struct http *fm, unsigned how);
 void http_FilterResp(const struct http *fm, struct http *to, unsigned how);
 void http_PutProtocol(const struct http *to, const char *protocol);
 void http_PutStatus(struct http *to, uint16_t status);
+void http_ForceHeader(struct http *to, const char *hdr, const char *val);
 void http_PutResponse(const struct http *to, const char *response);
 void http_PrintfHeader(struct http *to, const char *fmt, ...)
     __printflike(2, 3);
@@ -1013,7 +1014,7 @@ enum sess_close http_DoConnection(const struct http *);
 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_VSLH(const struct http *hp, unsigned hdr);
+void http_VSL_log(const struct http *hp);
 
 /* cache_http1_proto.c */
 
diff --git a/bin/varnishd/cache/cache_fetch.c b/bin/varnishd/cache/cache_fetch.c
index f261f70..088e0f1 100644
--- a/bin/varnishd/cache/cache_fetch.c
+++ b/bin/varnishd/cache/cache_fetch.c
@@ -84,8 +84,7 @@ vbf_stp_mkbereq(const struct worker *wrk, struct busyobj *bo)
 			 * client doesn't grok it.  We will uncompress for
 			 * the minority of clients which don't.
 			 */
-			http_Unset(bo->bereq0, H_Accept_Encoding);
-			http_SetHeader(bo->bereq0, "Accept-Encoding: gzip");
+			http_ForceHeader(bo->bereq0, H_Accept_Encoding, "gzip");
 		}
 	}
 	if (bo->ims_obj != NULL) {
@@ -196,6 +195,8 @@ vbf_stp_fetchhdr(struct worker *wrk, struct busyobj *bo)
 		AN(bo->vbc);
 	}
 
+	http_VSL_log(bo->beresp);
+
 	/*
 	 * These two headers can be spread over multiple actual headers
 	 * and we rely on their content outside of VCL, so collect them
diff --git a/bin/varnishd/cache/cache_http.c b/bin/varnishd/cache/cache_http.c
index 97abe39..711ea2b 100644
--- a/bin/varnishd/cache/cache_http.c
+++ b/bin/varnishd/cache/cache_http.c
@@ -41,6 +41,8 @@
 #include "tbl/http_headers.h"
 #undef HTTPH
 
+/*--------------------------------------------------------------------*/
+
 static const enum VSL_tag_e foo[] = {
 	[HTTP_Method]	= SLT_ReqMethod,
 	[HTTP_Resp]	= SLT_RespMethod,
@@ -61,13 +63,35 @@ http2shmlog(const struct http *hp, int t)
 	return ((enum VSL_tag_e)(foo[hp->logtag] + t));
 }
 
-void
+static void
 http_VSLH(const struct http *hp, unsigned hdr)
 {
 
-	AN(hp->vsl);
-	AN(hp->vsl->wid & (VSL_CLIENTMARKER|VSL_BACKENDMARKER));
-	VSLbt(hp->vsl, http2shmlog(hp, hdr), hp->hd[hdr]);
+	if (hp->vsl != NULL) {
+		AN(hp->vsl->wid & (VSL_CLIENTMARKER|VSL_BACKENDMARKER));
+		VSLbt(hp->vsl, http2shmlog(hp, hdr), hp->hd[hdr]);
+	}
+}
+
+static void
+http_VSLH_del(const struct http *hp, unsigned hdr)
+{
+
+	if (hp->vsl != NULL) {
+		AN(hp->vsl->wid & (VSL_CLIENTMARKER|VSL_BACKENDMARKER));
+		VSLbt(hp->vsl, ((enum VSL_tag_e)(http2shmlog(hp, hdr) + 1)),
+		    hp->hd[hdr]);
+	}
+}
+
+void
+http_VSL_log(const struct http *hp)
+{
+	unsigned u;
+
+	for (u = 0; u < hp->nhd; u++)
+		if (hp->hd[u].b != NULL)
+			http_VSLH(hp, u);
 }
 
 /*--------------------------------------------------------------------*/
@@ -488,6 +512,7 @@ http_SetH(const struct http *to, unsigned n, const char *fm)
 	to->hd[n].b = TRUST_ME(fm);
 	to->hd[n].e = strchr(to->hd[n].b, '\0');
 	to->hdf[n] = 0;
+	http_VSLH(to, n);
 }
 
 static void
@@ -498,6 +523,7 @@ http_linkh(const struct http *to, const struct http *fm, unsigned n)
 	Tcheck(fm->hd[n]);
 	to->hd[n] = fm->hd[n];
 	to->hdf[n] = fm->hdf[n];
+	http_VSLH(to, n);
 }
 
 void
@@ -574,6 +600,7 @@ http_filterfields(struct http *to, const struct http *fm, unsigned how)
 		if (to->nhd < to->shd) {
 			to->hd[to->nhd] = fm->hd[u];
 			to->hdf[to->nhd] = 0;
+			http_VSLH(to, to->nhd);
 			to->nhd++;
 		} else  {
 			VSC_C_main->losthdr++;
@@ -629,13 +656,11 @@ http_CopyHome(const struct http *hp)
 		if (hp->hd[u].b == NULL)
 			continue;
 		if (hp->hd[u].b >= hp->ws->s && hp->hd[u].e <= hp->ws->e) {
-			http_VSLH(hp, u);
 			continue;
 		}
 		l = Tlen(hp->hd[u]);
 		p = WS_Copy(hp->ws, hp->hd[u].b, l + 1L);
 		if (p != NULL) {
-			http_VSLH(hp, u);
 			hp->hd[u].b = p;
 			hp->hd[u].e = p + l;
 		} else {
@@ -679,6 +704,19 @@ http_SetHeader(struct http *to, const char *hdr)
 
 /*--------------------------------------------------------------------*/
 
+void
+http_ForceHeader(struct http *to, const char *hdr, const char *val)
+{
+
+	CHECK_OBJ_NOTNULL(to, HTTP_MAGIC);
+	if (http_HdrIs(to, hdr, val))
+		return;
+	http_Unset(to, hdr);
+	http_PrintfHeader(to, "%s %s", hdr + 1, val);
+}
+
+/*--------------------------------------------------------------------*/
+
 static void
 http_PutField(const struct http *to, int field, const char *string)
 {
@@ -698,6 +736,7 @@ http_PutField(const struct http *to, int field, const char *string)
 		to->hd[field].b = p;
 		to->hd[field].e = p + l;
 		to->hdf[field] = 0;
+		http_VSLH(to, field);
 	}
 }
 
@@ -719,7 +758,7 @@ http_PutStatus(struct http *to, uint16_t status)
 	assert(status >= 100 && status <= 999);
 	to->status = status;
 	bprintf(buf, "%03d", status % 1000);
-	http_SetH(to, HTTP_HDR_STATUS, WS_Copy(to->ws, buf, sizeof buf));
+	http_PutField(to, HTTP_HDR_STATUS, buf);
 }
 
 void
@@ -752,9 +791,11 @@ http_PrintfHeader(struct http *to, const char *fmt, ...)
 		to->hd[to->nhd].e = to->ws->f + n;
 		to->hdf[to->nhd] = 0;
 		WS_Release(to->ws, n + 1);
+		http_VSLH(to, to->nhd);
 		to->nhd++;
 	}
 }
+
 /*--------------------------------------------------------------------*/
 
 void
@@ -765,8 +806,10 @@ http_Unset(struct http *hp, const char *hdr)
 	for (v = u = HTTP_HDR_FIRST; u < hp->nhd; u++) {
 		if (hp->hd[u].b == NULL)
 			continue;
-		if (http_IsHdr(&hp->hd[u], hdr))
+		if (http_IsHdr(&hp->hd[u], hdr)) {
+			http_VSLH_del(hp, u);
 			continue;
+		}
 		if (v != u) {
 			memcpy(&hp->hd[v], &hp->hd[u], sizeof *hp->hd);
 			memcpy(&hp->hdf[v], &hp->hdf[u], sizeof *hp->hdf);
diff --git a/bin/varnishd/cache/cache_http1_proto.c b/bin/varnishd/cache/cache_http1_proto.c
index db0a1c5..ef1043e 100644
--- a/bin/varnishd/cache/cache_http1_proto.c
+++ b/bin/varnishd/cache/cache_http1_proto.c
@@ -279,7 +279,6 @@ htc_dissect_hdrs(struct http *hp, char *p, const struct http_conn *htc)
 			hp->hdf[hp->nhd] = 0;
 			hp->hd[hp->nhd].b = p;
 			hp->hd[hp->nhd].e = q;
-			http_VSLH(hp, hp->nhd);
 			hp->nhd++;
 		} else {
 			VSLb(hp->vsl, SLT_BogoHeader, "Too many headers: %.*s",
@@ -364,15 +363,10 @@ htc_splitline(struct http *hp, const struct http_conn *htc, int req)
 	p += vct_skipcrlf(p);
 
 	*hp->hd[h1].e = '\0';
-	http_VSLH(hp, h1);
-
 	*hp->hd[h2].e = '\0';
-	http_VSLH(hp, h2);
 
-	if (hp->hd[h3].e != NULL) {
+	if (hp->hd[h3].e != NULL)
 		*hp->hd[h3].e = '\0';
-		http_VSLH(hp, h3);
-	}
 
 	return (htc_dissect_hdrs(hp, p, htc));
 }
@@ -519,7 +513,6 @@ HTTP1_Write(const struct worker *w, const struct http *hp, int resp)
 
 	if (resp) {
 		l = WRW_WriteH(w, &hp->hd[HTTP_HDR_PROTO], " ");
-		http_VSLH(hp, HTTP_HDR_PROTO);
 
 		hp->hd[HTTP_HDR_STATUS].b = WS_Alloc(hp->ws, 4);
 		AN(hp->hd[HTTP_HDR_STATUS].b);
@@ -528,18 +521,13 @@ HTTP1_Write(const struct worker *w, const struct http *hp, int resp)
 		hp->hd[HTTP_HDR_STATUS].e = hp->hd[HTTP_HDR_STATUS].b + 3;
 
 		l += WRW_WriteH(w, &hp->hd[HTTP_HDR_STATUS], " ");
-		http_VSLH(hp, HTTP_HDR_STATUS);
 
 		l += WRW_WriteH(w, &hp->hd[HTTP_HDR_RESPONSE], "\r\n");
-		http_VSLH(hp, HTTP_HDR_RESPONSE);
 	} else {
 		AN(hp->hd[HTTP_HDR_URL].b);
 		l = WRW_WriteH(w, &hp->hd[HTTP_HDR_METHOD], " ");
-		http_VSLH(hp, HTTP_HDR_METHOD);
 		l += WRW_WriteH(w, &hp->hd[HTTP_HDR_URL], " ");
-		http_VSLH(hp, HTTP_HDR_URL);
 		l += WRW_WriteH(w, &hp->hd[HTTP_HDR_PROTO], "\r\n");
-		http_VSLH(hp, HTTP_HDR_PROTO);
 	}
 	for (u = HTTP_HDR_FIRST; u < hp->nhd; u++) {
 		if (hp->hd[u].b == NULL)
@@ -547,7 +535,6 @@ HTTP1_Write(const struct worker *w, const struct http *hp, int resp)
 		AN(hp->hd[u].b);
 		AN(hp->hd[u].e);
 		l += WRW_WriteH(w, &hp->hd[u], "\r\n");
-		http_VSLH(hp, u);
 	}
 	l += WRW_Write(w, "\r\n", -1);
 	return (l);
diff --git a/bin/varnishd/cache/cache_req_fsm.c b/bin/varnishd/cache/cache_req_fsm.c
index fdf99db..8c5b43f 100644
--- a/bin/varnishd/cache/cache_req_fsm.c
+++ b/bin/varnishd/cache/cache_req_fsm.c
@@ -690,6 +690,8 @@ cnt_recv(struct worker *wrk, struct req *req)
 	VSLb(req->vsl, SLT_ReqStart, "%s %s",
 	    req->sp->client_addr_str, req->sp->client_port_str);
 
+	http_VSL_log(req->http);
+
 	if (req->err_code) {
 		req->req_step = R_STP_ERROR;
 		return (REQ_FSM_MORE);
@@ -716,12 +718,12 @@ cnt_recv(struct worker *wrk, struct req *req)
 	}
 	recv_handling = wrk->handling;
 
+	/* We wash the A-E header here for the sake of VRY */
 	if (cache_param->http_gzip_support &&
 	     (recv_handling != VCL_RET_PIPE) &&
 	     (recv_handling != VCL_RET_PASS)) {
 		if (RFC2616_Req_Gzip(req->http)) {
-			http_Unset(req->http, H_Accept_Encoding);
-			http_SetHeader(req->http, "Accept-Encoding: gzip");
+			http_ForceHeader(req->http, H_Accept_Encoding, "gzip");
 		} else {
 			http_Unset(req->http, H_Accept_Encoding);
 		}



More information about the varnish-commit mailing list