[prev in list] [next in list] [prev in thread] [next in thread] 

List:       varnish-dev
Subject:    struct http_conn usage changes
From:       Martin Blix Grydeland <martin () varnish-software ! com>
Date:       2015-07-09 15:32:18
Message-ID: CANTn4crN63L4HDECdoYN=ArVza6EpXn7LhPWZBLP=Y09L+bOLw () mail ! gmail ! com
[Download RAW message or body]

[Attachment #2 (multipart/alternative)]


Hi PHK,

Attached is a set of patches to fix up the connection handling in Varnish,
making it more general for both client and backend connections. This is a
fairly benign cleanup set, that makes the code paths clearer. I propose
this for inclusion in 4.1 (and with very small font, almost unreadable, I
mention that it also sneaks in the necessary hooks for my Backend SSL
stuff).

Martin

-- 
<http://varnish-software.com>*Martin Blix Grydeland*
Senior Developer | Varnish Software AS
Mobile: +47 992 74 756
We Make Websites Fly!

[Attachment #5 (text/html)]

<div dir="ltr">Hi PHK,<div><br></div><div>Attached is a set of patches to fix up the \
connection handling in Varnish, making it more general for both client and backend \
connections. This is a fairly benign cleanup set, that makes the code paths clearer. \
I propose this for inclusion in 4.1 (and with very small font, almost unreadable, I \
mention that it also sneaks in the necessary hooks for my Backend SSL \
stuff).</div><div><br></div><div>Martin<br clear="all"><div><br></div>-- <br><div \
class="gmail_signature"><div dir="ltr"><div><div><table border="0" cellpadding="0" \
cellspacing="0" style="font-size:12px;line-height:1.5em;font-family:&#39;Helvetica \
Neue&#39;,Arial,sans-serif;color:rgb(102,102,102);width:550px;border-top-width:1px;bor \
der-top-style:solid;border-top-color:rgb(238,238,238);border-bottom-width:1px;border-b \
ottom-style:solid;border-bottom-color:rgb(238,238,238);margin-top:20px;padding-top:5px;padding-bottom:5px"><tbody><tr><td \
width="100"><a href="http://varnish-software.com" target="_blank"><img \
src="http://www.varnish-software.com/static/media/logo-email.png"></a><span></span><span></span></td><td><strong \
style="font-size:14px;color:rgb(34,34,34)">Martin Blix Grydeland</strong><br>Senior \
Developer | Varnish Software AS<br>Mobile: +47 992 74 756<br><span \
style="font-weight:bold">We Make Websites \
Fly!</span></td></tr></tbody></table></div></div></div></div> </div></div>

--047d7bfcf00afcb733051a72f577--


["0001-Move-the-HTTP-request-receive-code-away-from-cache_s.patch" (text/x-patch)]

From 928e015bde951b21a7ed06b888f30c14c7c71595 Mon Sep 17 00:00:00 2001
From: Martin Blix Grydeland <martin@varnish-software.com>
Date: Thu, 9 Jul 2015 11:07:21 +0200
Subject: [PATCH 01/10] Move the HTTP request receive code away from
 cache_sess.c

Move the HTTP request receive code away from cache_sess.c to
cache_htc.c. This code can then be shared with the backend response
code.
---
 bin/varnishd/Makefile.am               |   1 +
 bin/varnishd/cache/cache.h             |  15 +--
 bin/varnishd/cache/cache_htc.c         | 190 +++++++++++++++++++++++++++++++++
 bin/varnishd/cache/cache_session.c     | 150 +-------------------------
 bin/varnishd/http1/cache_http1_fetch.c |   4 +-
 bin/varnishd/http1/cache_http1_fsm.c   |   4 +-
 bin/varnishd/proxy/cache_proxy_proto.c |   4 +-
 7 files changed, 206 insertions(+), 162 deletions(-)
 create mode 100644 bin/varnishd/cache/cache_htc.c

diff --git a/bin/varnishd/Makefile.am b/bin/varnishd/Makefile.am
index dd2bae2..f98a480 100644
--- a/bin/varnishd/Makefile.am
+++ b/bin/varnishd/Makefile.am
@@ -27,6 +27,7 @@ varnishd_SOURCES = \
 	cache/cache_fetch_proc.c \
 	cache/cache_gzip.c \
 	cache/cache_hash.c \
+	cache/cache_htc.c \
 	cache/cache_http.c \
 	cache/cache_lck.c \
 	cache/cache_main.c \
diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h
index 522fad2..5a311f6 100644
--- a/bin/varnishd/cache/cache.h
+++ b/bin/varnishd/cache/cache.h
@@ -975,13 +975,6 @@ enum htc_status_e {
 	HTC_S_IDLE =		 3,
 };
 
-void SES_RxInit(struct http_conn *htc, struct ws *ws,
-    unsigned maxbytes, unsigned maxhdr);
-void SES_RxReInit(struct http_conn *htc);
-enum htc_status_e SES_Rx(struct http_conn *htc, double tmo);
-enum htc_status_e SES_RxReq(const struct worker *, struct req *,
-    htc_complete_f *func);
-
 #define SESS_ATTR(UP, low, typ, len)				\
 	int SES_Get_##low(const struct sess *sp, typ *dst);	\
 	void SES_Reserve_##low(struct sess *sp, typ *dst);
@@ -990,6 +983,14 @@ enum htc_status_e SES_RxReq(const struct worker *, struct req *,
 void SES_Set_String_Attr(struct sess *sp, enum sess_attr a, const char *src);
 const char *SES_Get_String_Attr(const struct sess *sp, enum sess_attr a);
 
+/* cache_htc.c */
+void HTC_RxInit(struct http_conn *htc, struct ws *ws,
+    unsigned maxbytes, unsigned maxhdr);
+void HTC_RxReInit(struct http_conn *htc);
+enum htc_status_e HTC_Rx(struct http_conn *htc, double tmo);
+enum htc_status_e HTC_RxReq(const struct worker *, struct req *,
+    htc_complete_f *func);
+
 /* cache_shmlog.c */
 extern struct VSC_C_main *VSC_C_main;
 void VSM_Init(void);
diff --git a/bin/varnishd/cache/cache_htc.c b/bin/varnishd/cache/cache_htc.c
new file mode 100644
index 0000000..f42ecf0
--- /dev/null
+++ b/bin/varnishd/cache/cache_htc.c
@@ -0,0 +1,190 @@
+/*-
+ * Copyright (c) 2006 Verdens Gang AS
+ * Copyright (c) 2006-2011 Varnish Software AS
+ * All rights reserved.
+ *
+ * Author: Poul-Henning Kamp <phk@phk.freebsd.dk>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * HTTP connection handling
+ *
+ */
+
+#include "config.h"
+
+#include <errno.h>
+#include <poll.h>
+#include <stdlib.h>
+
+#include "vtim.h"
+
+#include "cache.h"
+
+/*--------------------------------------------------------------------*/
+
+void
+HTC_RxInit(struct http_conn *htc, struct ws *ws, unsigned maxbytes,
+    unsigned maxhdr)
+{
+
+	htc->magic = HTTP_CONN_MAGIC;
+	htc->ws = ws;
+	htc->maxbytes = maxbytes;
+	htc->maxhdr = maxhdr;
+
+	(void)WS_Reserve(htc->ws, htc->maxbytes);
+	htc->rxbuf_b = ws->f;
+	htc->rxbuf_e = ws->f;
+	*htc->rxbuf_e = '\0';
+	htc->pipeline_b = NULL;
+	htc->pipeline_e = NULL;
+}
+
+/*--------------------------------------------------------------------
+ * Start over, and recycle any pipelined input.
+ * The WS_Reset is safe, even though the pipelined input is stored in
+ * the ws somewhere, because WS_Reset only fiddles pointers.
+ */
+
+void
+HTC_RxReInit(struct http_conn *htc)
+{
+	ssize_t l;
+
+	CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC);
+	(void)WS_Reserve(htc->ws, htc->maxbytes);
+	htc->rxbuf_b = htc->ws->f;
+	htc->rxbuf_e = htc->ws->f;
+	if (htc->pipeline_b != NULL) {
+		l = htc->pipeline_e - htc->pipeline_b;
+		assert(l > 0);
+		memmove(htc->rxbuf_b, htc->pipeline_b, l);
+		htc->rxbuf_e += l;
+		htc->pipeline_b = NULL;
+		htc->pipeline_e = NULL;
+	}
+	*htc->rxbuf_e = '\0';
+}
+
+/*--------------------------------------------------------------------
+ * Receive more HTTP protocol bytes
+ */
+
+enum htc_status_e
+HTC_Rx(struct http_conn *htc, double tmo)
+{
+	int i, j;
+	struct pollfd pfd[1];
+
+	CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC);
+	AN(htc->ws->r);
+	AZ(htc->pipeline_b);
+	AZ(htc->pipeline_e);
+	i = (htc->ws->r - htc->rxbuf_e) - 1;	/* space for NUL */
+	if (i <= 0)
+		return (HTC_S_OVERFLOW);
+	if (tmo > 0.0) {
+		pfd[0].fd = htc->fd;
+		pfd[0].events = POLLIN;
+		pfd[0].revents = 0;
+		j = (int)floor(tmo * 1e3);
+		if (j == 0)
+			j++;
+		j = poll(pfd, 1, j);
+		if (j == 0)
+			return (HTC_S_TIMEOUT);
+	}
+	i = read(htc->fd, htc->rxbuf_e, i);
+	if (i <= 0)
+		return (HTC_S_EOF);
+	htc->rxbuf_e += i;
+	*htc->rxbuf_e = '\0';
+	return (HTC_S_MORE);
+}
+
+/*----------------------------------------------------------------------
+ * Receive a request/packet/whatever, with timeouts
+ */
+
+enum htc_status_e
+HTC_RxReq(const struct worker *wrk, struct req *req, htc_complete_f *func)
+{
+	double tmo;
+	double now, when;
+	struct sess *sp;
+	enum htc_status_e hs;
+
+	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
+	CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
+	sp = req->sp;
+	CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
+	CHECK_OBJ_NOTNULL(req->htc, HTTP_CONN_MAGIC);
+
+	AZ(isnan(sp->t_idle));
+	assert(isnan(req->t_first));
+
+	when = sp->t_idle + cache_param->timeout_idle;
+	tmo = cache_param->timeout_linger;
+	while (1) {
+		hs = HTC_Rx(req->htc, tmo);
+		now = VTIM_real();
+		if (hs == HTC_S_EOF) {
+			WS_ReleaseP(req->htc->ws, req->htc->rxbuf_b);
+			return (HTC_S_CLOSE);
+		}
+		if (hs == HTC_S_OVERFLOW) {
+			WS_ReleaseP(req->htc->ws, req->htc->rxbuf_b);
+			return (HTC_S_OVERFLOW);
+		}
+		hs = func(req->htc);
+		if (hs == HTC_S_OVERFLOW) {
+			WS_ReleaseP(req->htc->ws, req->htc->rxbuf_b);
+			return (HTC_S_OVERFLOW);
+		}
+		if (hs == HTC_S_JUNK) {
+			WS_ReleaseP(req->htc->ws, req->htc->rxbuf_b);
+			return (HTC_S_JUNK);
+		}
+		if (hs == HTC_S_COMPLETE) {
+			/* Got it, run with it */
+			if (isnan(req->t_first))
+				req->t_first = now;
+			req->t_req = now;
+			return (HTC_S_COMPLETE);
+		}
+		if (when < now)
+			return (HTC_S_TIMEOUT);
+		if (hs == HTC_S_MORE) {
+			/* Working on it */
+			if (isnan(req->t_first))
+				req->t_first = now;
+			tmo = when - now;
+			continue;
+		}
+		assert(hs == HTC_S_EMPTY);
+		/* Nothing but whitespace */
+		tmo = sp->t_idle + cache_param->timeout_linger - now;
+		if (tmo < 0)
+			return (HTC_S_IDLE);
+	}
+}
diff --git a/bin/varnishd/cache/cache_session.c b/bin/varnishd/cache/cache_session.c
index f3ab04a..6dcf6f6 100644
--- a/bin/varnishd/cache/cache_session.c
+++ b/bin/varnishd/cache/cache_session.c
@@ -144,154 +144,6 @@ SES_Get_String_Attr(const struct sess *sp, enum sess_attr a)
 	return (q);
 }
 
-/*--------------------------------------------------------------------*/
-
-void
-SES_RxInit(struct http_conn *htc, struct ws *ws, unsigned maxbytes,
-    unsigned maxhdr)
-{
-
-	htc->magic = HTTP_CONN_MAGIC;
-	htc->ws = ws;
-	htc->maxbytes = maxbytes;
-	htc->maxhdr = maxhdr;
-
-	(void)WS_Reserve(htc->ws, htc->maxbytes);
-	htc->rxbuf_b = ws->f;
-	htc->rxbuf_e = ws->f;
-	*htc->rxbuf_e = '\0';
-	htc->pipeline_b = NULL;
-	htc->pipeline_e = NULL;
-}
-
-/*--------------------------------------------------------------------
- * Start over, and recycle any pipelined input.
- * The WS_Reset is safe, even though the pipelined input is stored in
- * the ws somewhere, because WS_Reset only fiddles pointers.
- */
-
-void
-SES_RxReInit(struct http_conn *htc)
-{
-	ssize_t l;
-
-	CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC);
-	(void)WS_Reserve(htc->ws, htc->maxbytes);
-	htc->rxbuf_b = htc->ws->f;
-	htc->rxbuf_e = htc->ws->f;
-	if (htc->pipeline_b != NULL) {
-		l = htc->pipeline_e - htc->pipeline_b;
-		assert(l > 0);
-		memmove(htc->rxbuf_b, htc->pipeline_b, l);
-		htc->rxbuf_e += l;
-		htc->pipeline_b = NULL;
-		htc->pipeline_e = NULL;
-	}
-	*htc->rxbuf_e = '\0';
-}
-
-/*--------------------------------------------------------------------
- * Receive more HTTP protocol bytes
- */
-
-enum htc_status_e
-SES_Rx(struct http_conn *htc, double tmo)
-{
-	int i, j;
-	struct pollfd pfd[1];
-
-	CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC);
-	AN(htc->ws->r);
-	AZ(htc->pipeline_b);
-	AZ(htc->pipeline_e);
-	i = (htc->ws->r - htc->rxbuf_e) - 1;	/* space for NUL */
-	if (i <= 0)
-		return (HTC_S_OVERFLOW);
-	if (tmo > 0.0) {
-		pfd[0].fd = htc->fd;
-		pfd[0].events = POLLIN;
-		pfd[0].revents = 0;
-		j = (int)floor(tmo * 1e3);
-		if (j == 0)
-			j++;
-		j = poll(pfd, 1, j);
-		if (j == 0)
-			return (HTC_S_TIMEOUT);
-	}
-	i = read(htc->fd, htc->rxbuf_e, i);
-	if (i <= 0)
-		return (HTC_S_EOF);
-	htc->rxbuf_e += i;
-	*htc->rxbuf_e = '\0';
-	return (HTC_S_MORE);
-}
-
-/*----------------------------------------------------------------------
- * Receive a request/packet/whatever, with timeouts
- */
-
-enum htc_status_e
-SES_RxReq(const struct worker *wrk, struct req *req, htc_complete_f *func)
-{
-	double tmo;
-	double now, when;
-	struct sess *sp;
-	enum htc_status_e hs;
-
-	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
-	CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
-	sp = req->sp;
-	CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
-
-	AZ(isnan(sp->t_idle));
-	assert(isnan(req->t_first));
-
-	when = sp->t_idle + cache_param->timeout_idle;
-	tmo = cache_param->timeout_linger;
-	while (1) {
-		hs = SES_Rx(req->htc, tmo);
-		now = VTIM_real();
-		if (hs == HTC_S_EOF) {
-			WS_ReleaseP(req->htc->ws, req->htc->rxbuf_b);
-			return (HTC_S_CLOSE);
-		}
-		if (hs == HTC_S_OVERFLOW) {
-			WS_ReleaseP(req->htc->ws, req->htc->rxbuf_b);
-			return (HTC_S_OVERFLOW);
-		}
-		hs = func(req->htc);
-		if (hs == HTC_S_OVERFLOW) {
-			WS_ReleaseP(req->htc->ws, req->htc->rxbuf_b);
-			return (HTC_S_OVERFLOW);
-		}
-		if (hs == HTC_S_JUNK) {
-			WS_ReleaseP(req->htc->ws, req->htc->rxbuf_b);
-			return (HTC_S_JUNK);
-		}
-		if (hs == HTC_S_COMPLETE) {
-			/* Got it, run with it */
-			if (isnan(req->t_first))
-				req->t_first = now;
-			req->t_req = now;
-			return (HTC_S_COMPLETE);
-		}
-		if (when < now)
-			return (HTC_S_TIMEOUT);
-		if (hs == HTC_S_MORE) {
-			/* Working on it */
-			if (isnan(req->t_first))
-				req->t_first = now;
-			tmo = when - now;
-			continue;
-		}
-		assert(hs == HTC_S_EMPTY);
-		/* Nothing but whitespace */
-		tmo = sp->t_idle + cache_param->timeout_linger - now;
-		if (tmo < 0)
-			return (HTC_S_IDLE);
-	}
-}
-
 /*--------------------------------------------------------------------
  * Get a new session, preferably by recycling an already ready one
  *
@@ -381,7 +233,7 @@ SES_Proto_Sess(struct worker *wrk, void *arg)
 	req = Req_New(wrk, sp);
 	CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
 	req->htc->fd = sp->fd;
-	SES_RxInit(req->htc, req->ws,
+	HTC_RxInit(req->htc, req->ws,
 	    cache_param->http_req_size, cache_param->http_req_hdr_len);
 
 	if (sp->sess_step < S_STP_H1_LAST) {
diff --git a/bin/varnishd/http1/cache_http1_fetch.c b/bin/varnishd/http1/cache_http1_fetch.c
index 2a2099b..d935c7a 100644
--- a/bin/varnishd/http1/cache_http1_fetch.c
+++ b/bin/varnishd/http1/cache_http1_fetch.c
@@ -151,7 +151,7 @@ V1F_FetchRespHdr(struct busyobj *bo)
 
 	/* Receive response */
 
-	SES_RxInit(htc, bo->ws, cache_param->http_resp_size,
+	HTC_RxInit(htc, bo->ws, cache_param->http_resp_size,
 	    cache_param->http_resp_hdr_len);
 	CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC);
 	CHECK_OBJ_NOTNULL(bo->htc, HTTP_CONN_MAGIC);
@@ -160,7 +160,7 @@ V1F_FetchRespHdr(struct busyobj *bo)
 
 	first = 1;
 	do {
-		hs = SES_Rx(htc, 0);
+		hs = HTC_Rx(htc, 0);
 		if (hs == HTC_S_MORE)
 			hs = HTTP1_Complete(htc);
 		if (hs == HTC_S_OVERFLOW) {
diff --git a/bin/varnishd/http1/cache_http1_fsm.c b/bin/varnishd/http1/cache_http1_fsm.c
index 103ba3b..7fc177b 100644
--- a/bin/varnishd/http1/cache_http1_fsm.c
+++ b/bin/varnishd/http1/cache_http1_fsm.c
@@ -199,7 +199,7 @@ HTTP1_Session(struct worker *wrk, struct req *req)
 			AZ(req->vcl);
 			AZ(req->esi_level);
 
-			hs = SES_RxReq(wrk, req, HTTP1_Complete);
+			hs = HTC_RxReq(wrk, req, HTTP1_Complete);
 			if (hs < HTC_S_EMPTY) {
 				req->acct.req_hdrbytes +=
 				    req->htc->rxbuf_e - req->htc->rxbuf_b;
@@ -272,7 +272,7 @@ HTTP1_Session(struct worker *wrk, struct req *req)
 		case S_STP_H1CLEANUP:
 			if (Req_Cleanup(sp, wrk, req))
 				return;
-			SES_RxReInit(req->htc);
+			HTC_RxReInit(req->htc);
 			if (HTTP1_Complete(req->htc) == HTC_S_COMPLETE) {
 				AZ(req->vsl->wid);
 				req->t_first = req->t_req = sp->t_idle;
diff --git a/bin/varnishd/proxy/cache_proxy_proto.c b/bin/varnishd/proxy/cache_proxy_proto.c
index e359cb0..3ca1c8a 100644
--- a/bin/varnishd/proxy/cache_proxy_proto.c
+++ b/bin/varnishd/proxy/cache_proxy_proto.c
@@ -351,7 +351,7 @@ VPX_Proto_Sess(struct worker *wrk, void *priv)
 	assert(sizeof vpx1_sig == 5);
 	assert(sizeof vpx2_sig == 12);
 
-	hs = SES_RxReq(wrk, req, vpx_complete);
+	hs = HTC_RxReq(wrk, req, vpx_complete);
 	if (hs != HTC_S_COMPLETE) {
 		Req_Release(req);
 		SES_Delete(sp, SC_RX_JUNK, NAN);
@@ -376,7 +376,7 @@ VPX_Proto_Sess(struct worker *wrk, void *priv)
 	else
 		req->htc->pipeline_e = req->htc->rxbuf_e;
 	WS_Release(req->htc->ws, 0);
-	SES_RxReInit(req->htc);
+	HTC_RxReInit(req->htc);
 	req->t_req = NAN;
 	req->t_first = NAN;
 	req->sp->sess_step = S_STP_H1NEWREQ;
-- 
2.1.4


["0002-Remove-unused-wrk-argument-from-HTC_RxReq.patch" (text/x-patch)]

From ccc36eff64f59695c7e0771c4da55ec13ced4945 Mon Sep 17 00:00:00 2001
From: Martin Blix Grydeland <martin@varnish-software.com>
Date: Thu, 9 Jul 2015 11:51:59 +0200
Subject: [PATCH 02/10] Remove unused wrk argument from HTC_RxReq

---
 bin/varnishd/cache/cache.h             | 3 +--
 bin/varnishd/cache/cache_htc.c         | 3 +--
 bin/varnishd/http1/cache_http1_fsm.c   | 2 +-
 bin/varnishd/proxy/cache_proxy_proto.c | 2 +-
 4 files changed, 4 insertions(+), 6 deletions(-)

diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h
index 5a311f6..b45e45b 100644
--- a/bin/varnishd/cache/cache.h
+++ b/bin/varnishd/cache/cache.h
@@ -988,8 +988,7 @@ void HTC_RxInit(struct http_conn *htc, struct ws *ws,
     unsigned maxbytes, unsigned maxhdr);
 void HTC_RxReInit(struct http_conn *htc);
 enum htc_status_e HTC_Rx(struct http_conn *htc, double tmo);
-enum htc_status_e HTC_RxReq(const struct worker *, struct req *,
-    htc_complete_f *func);
+enum htc_status_e HTC_RxReq(struct req *req, htc_complete_f *func);
 
 /* cache_shmlog.c */
 extern struct VSC_C_main *VSC_C_main;
diff --git a/bin/varnishd/cache/cache_htc.c b/bin/varnishd/cache/cache_htc.c
index f42ecf0..4f9cfb8 100644
--- a/bin/varnishd/cache/cache_htc.c
+++ b/bin/varnishd/cache/cache_htc.c
@@ -127,14 +127,13 @@ HTC_Rx(struct http_conn *htc, double tmo)
  */
 
 enum htc_status_e
-HTC_RxReq(const struct worker *wrk, struct req *req, htc_complete_f *func)
+HTC_RxReq(struct req *req, htc_complete_f *func)
 {
 	double tmo;
 	double now, when;
 	struct sess *sp;
 	enum htc_status_e hs;
 
-	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
 	CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
 	sp = req->sp;
 	CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
diff --git a/bin/varnishd/http1/cache_http1_fsm.c b/bin/varnishd/http1/cache_http1_fsm.c
index 7fc177b..16fda8b 100644
--- a/bin/varnishd/http1/cache_http1_fsm.c
+++ b/bin/varnishd/http1/cache_http1_fsm.c
@@ -199,7 +199,7 @@ HTTP1_Session(struct worker *wrk, struct req *req)
 			AZ(req->vcl);
 			AZ(req->esi_level);
 
-			hs = HTC_RxReq(wrk, req, HTTP1_Complete);
+			hs = HTC_RxReq(req, HTTP1_Complete);
 			if (hs < HTC_S_EMPTY) {
 				req->acct.req_hdrbytes +=
 				    req->htc->rxbuf_e - req->htc->rxbuf_b;
diff --git a/bin/varnishd/proxy/cache_proxy_proto.c b/bin/varnishd/proxy/cache_proxy_proto.c
index 3ca1c8a..679ebf1 100644
--- a/bin/varnishd/proxy/cache_proxy_proto.c
+++ b/bin/varnishd/proxy/cache_proxy_proto.c
@@ -351,7 +351,7 @@ VPX_Proto_Sess(struct worker *wrk, void *priv)
 	assert(sizeof vpx1_sig == 5);
 	assert(sizeof vpx2_sig == 12);
 
-	hs = HTC_RxReq(wrk, req, vpx_complete);
+	hs = HTC_RxReq(req, vpx_complete);
 	if (hs != HTC_S_COMPLETE) {
 		Req_Release(req);
 		SES_Delete(sp, SC_RX_JUNK, NAN);
-- 
2.1.4


["0003-Create-a-HTC_RxResp-function-to-receive-backend-resp.patch" (text/x-patch)]

From b0d511d2aa892672ee15375d7eaa346ff9c68789 Mon Sep 17 00:00:00 2001
From: Martin Blix Grydeland <martin@varnish-software.com>
Date: Thu, 9 Jul 2015 11:52:19 +0200
Subject: [PATCH 03/10] Create a HTC_RxResp function to receive backend
 response.

HTC_RxResp reads a backend response from a struct http_conn.
---
 bin/varnishd/cache/cache.h             |  1 +
 bin/varnishd/cache/cache_htc.c         | 48 ++++++++++++++++++++++++++++++++
 bin/varnishd/http1/cache_http1_fetch.c | 51 ++++++----------------------------
 3 files changed, 58 insertions(+), 42 deletions(-)

diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h
index b45e45b..6e85407 100644
--- a/bin/varnishd/cache/cache.h
+++ b/bin/varnishd/cache/cache.h
@@ -989,6 +989,7 @@ void HTC_RxInit(struct http_conn *htc, struct ws *ws,
 void HTC_RxReInit(struct http_conn *htc);
 enum htc_status_e HTC_Rx(struct http_conn *htc, double tmo);
 enum htc_status_e HTC_RxReq(struct req *req, htc_complete_f *func);
+enum htc_status_e HTC_RxResp(struct busyobj *bo, htc_complete_f *func);
 
 /* cache_shmlog.c */
 extern struct VSC_C_main *VSC_C_main;
diff --git a/bin/varnishd/cache/cache_htc.c b/bin/varnishd/cache/cache_htc.c
index 4f9cfb8..b11c3ba 100644
--- a/bin/varnishd/cache/cache_htc.c
+++ b/bin/varnishd/cache/cache_htc.c
@@ -37,6 +37,7 @@
 #include <stdlib.h>
 
 #include "vtim.h"
+#include "vtcp.h"
 
 #include "cache.h"
 
@@ -187,3 +188,50 @@ HTC_RxReq(struct req *req, htc_complete_f *func)
 			return (HTC_S_IDLE);
 	}
 }
+
+/*----------------------------------------------------------------------
+ * Receive a response/packet/whatever, with timeouts
+ */
+
+enum htc_status_e
+HTC_RxResp(struct busyobj *bo, htc_complete_f *func)
+{
+	struct http_conn *htc;
+	int first;
+	enum htc_status_e hs;
+
+	CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
+	CHECK_OBJ_NOTNULL(bo->htc, HTTP_CONN_MAGIC);
+	AN(func);
+
+	htc = bo->htc;
+	VTCP_set_read_timeout(htc->fd, htc->first_byte_timeout);
+
+	first = 1;
+	do {
+		hs = HTC_Rx(htc, 0);
+		if (hs == HTC_S_MORE)
+			hs = func(htc);
+		if (hs == HTC_S_OVERFLOW) {
+			WS_ReleaseP(htc->ws, htc->rxbuf_b);
+			VSLb(bo->vsl, SLT_FetchError,
+			    "http %sread error: overflow",
+			    first ? "first " : "");
+			htc->doclose = SC_RX_OVERFLOW;
+			return (hs);
+		}
+		if (hs == HTC_S_EOF) {
+			WS_ReleaseP(htc->ws, htc->rxbuf_b);
+			VSLb(bo->vsl, SLT_FetchError, "http %sread error: EOF",
+			    first ? "first " : "");
+			htc->doclose = SC_RX_TIMEOUT;
+			return (HTC_S_TIMEOUT);
+		}
+		if (first) {
+			first = 0;
+			VTCP_set_read_timeout(htc->fd,
+			    htc->between_bytes_timeout);
+		}
+	} while (hs != HTC_S_COMPLETE);
+	return (hs);
+}
diff --git a/bin/varnishd/http1/cache_http1_fetch.c b/bin/varnishd/http1/cache_http1_fetch.c
index d935c7a..5084a9e 100644
--- a/bin/varnishd/http1/cache_http1_fetch.c
+++ b/bin/varnishd/http1/cache_http1_fetch.c
@@ -135,11 +135,8 @@ V1F_SendReq(struct worker *wrk, struct busyobj *bo, uint64_t *ctr,
 int
 V1F_FetchRespHdr(struct busyobj *bo)
 {
-
-	struct http *hp;
-	enum htc_status_e hs;
-	int first;
 	struct http_conn *htc;
+	enum htc_status_e hs;
 
 	CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
 	CHECK_OBJ_NOTNULL(bo->htc, HTTP_CONN_MAGIC);
@@ -153,52 +150,22 @@ V1F_FetchRespHdr(struct busyobj *bo)
 
 	HTC_RxInit(htc, bo->ws, cache_param->http_resp_size,
 	    cache_param->http_resp_hdr_len);
-	CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC);
-	CHECK_OBJ_NOTNULL(bo->htc, HTTP_CONN_MAGIC);
 
-	VTCP_set_read_timeout(htc->fd, htc->first_byte_timeout);
-
-	first = 1;
-	do {
-		hs = HTC_Rx(htc, 0);
-		if (hs == HTC_S_MORE)
-			hs = HTTP1_Complete(htc);
-		if (hs == HTC_S_OVERFLOW) {
-			WS_ReleaseP(htc->ws, htc->rxbuf_b);
-			bo->acct.beresp_hdrbytes +=
-			    htc->rxbuf_e - htc->rxbuf_b;
-			VSLb(bo->vsl, SLT_FetchError,
-			    "http %sread error: overflow",
-			    first ? "first " : "");
-			htc->doclose = SC_RX_OVERFLOW;
-			return (-1);
-		}
-		if (hs == HTC_S_EOF) {
-			WS_ReleaseP(htc->ws, htc->rxbuf_b);
-			bo->acct.beresp_hdrbytes +=
-			    htc->rxbuf_e - htc->rxbuf_b;
-			VSLb(bo->vsl, SLT_FetchError, "http %sread error: EOF",
-			    first ? "first " : "");
-			htc->doclose = SC_RX_TIMEOUT;
-			return (first ? 1 : -1);
-		}
-		if (first) {
-			first = 0;
-			VTCP_set_read_timeout(htc->fd,
-			    htc->between_bytes_timeout);
-		}
-	} while (hs != HTC_S_COMPLETE);
+	hs = HTC_RxResp(bo, HTTP1_Complete);
 	bo->acct.beresp_hdrbytes += htc->rxbuf_e - htc->rxbuf_b;
+	if (hs == HTC_S_TIMEOUT && htc->rxbuf_e == htc->rxbuf_b)
+		/* Timeout and not received anything - allow retry */
+		return (1);
+	else if (hs != HTC_S_COMPLETE)
+		return (-1);
 
-	hp = bo->beresp;
-
-	if (HTTP1_DissectResponse(hp, htc)) {
+	if (HTTP1_DissectResponse(bo->beresp, htc)) {
 		VSLb(bo->vsl, SLT_FetchError, "http format error");
 		htc->doclose = SC_RX_JUNK;
 		return (-1);
 	}
 
-	htc->doclose = http_DoConnection(hp);
+	htc->doclose = http_DoConnection(bo->beresp);
 
 	return (0);
 }
-- 
2.1.4


["0004-Make-HTC_Rx-static.patch" (text/x-patch)]

From 58eb168f871639e2c0d5fc436403f4b342ebfd74 Mon Sep 17 00:00:00 2001
From: Martin Blix Grydeland <martin@varnish-software.com>
Date: Thu, 9 Jul 2015 11:57:50 +0200
Subject: [PATCH 04/10] Make HTC_Rx static

HTC_Rx is now only used from cache_htc.c. Make it a local static function.
---
 bin/varnishd/cache/cache.h     |  1 -
 bin/varnishd/cache/cache_htc.c | 77 +++++++++++++++++++++---------------------
 2 files changed, 39 insertions(+), 39 deletions(-)

diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h
index 6e85407..50f7609 100644
--- a/bin/varnishd/cache/cache.h
+++ b/bin/varnishd/cache/cache.h
@@ -987,7 +987,6 @@ const char *SES_Get_String_Attr(const struct sess *sp, enum sess_attr a);
 void HTC_RxInit(struct http_conn *htc, struct ws *ws,
     unsigned maxbytes, unsigned maxhdr);
 void HTC_RxReInit(struct http_conn *htc);
-enum htc_status_e HTC_Rx(struct http_conn *htc, double tmo);
 enum htc_status_e HTC_RxReq(struct req *req, htc_complete_f *func);
 enum htc_status_e HTC_RxResp(struct busyobj *bo, htc_complete_f *func);
 
diff --git a/bin/varnishd/cache/cache_htc.c b/bin/varnishd/cache/cache_htc.c
index b11c3ba..58cc798 100644
--- a/bin/varnishd/cache/cache_htc.c
+++ b/bin/varnishd/cache/cache_htc.c
@@ -41,6 +41,43 @@
 
 #include "cache.h"
 
+/*--------------------------------------------------------------------
+ * Receive more HTTP protocol bytes
+ */
+
+static enum htc_status_e
+htc_rx(struct http_conn *htc, double tmo)
+{
+	int i, j;
+	struct pollfd pfd[1];
+
+	CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC);
+	CHECK_OBJ_NOTNULL(htc->ws, WS_MAGIC);
+	AN(htc->ws->r);
+	AZ(htc->pipeline_b);
+	AZ(htc->pipeline_e);
+	i = (htc->ws->r - htc->rxbuf_e) - 1;	/* space for NUL */
+	if (i <= 0)
+		return (HTC_S_OVERFLOW);
+	if (tmo > 0.0) {
+		pfd[0].fd = htc->fd;
+		pfd[0].events = POLLIN;
+		pfd[0].revents = 0;
+		j = (int)floor(tmo * 1e3);
+		if (j == 0)
+			j++;
+		j = poll(pfd, 1, j);
+		if (j == 0)
+			return (HTC_S_TIMEOUT);
+	}
+	i = read(htc->fd, htc->rxbuf_e, i);
+	if (i <= 0)
+		return (HTC_S_EOF);
+	htc->rxbuf_e += i;
+	*htc->rxbuf_e = '\0';
+	return (HTC_S_MORE);
+}
+
 /*--------------------------------------------------------------------*/
 
 void
@@ -87,42 +124,6 @@ HTC_RxReInit(struct http_conn *htc)
 	*htc->rxbuf_e = '\0';
 }
 
-/*--------------------------------------------------------------------
- * Receive more HTTP protocol bytes
- */
-
-enum htc_status_e
-HTC_Rx(struct http_conn *htc, double tmo)
-{
-	int i, j;
-	struct pollfd pfd[1];
-
-	CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC);
-	AN(htc->ws->r);
-	AZ(htc->pipeline_b);
-	AZ(htc->pipeline_e);
-	i = (htc->ws->r - htc->rxbuf_e) - 1;	/* space for NUL */
-	if (i <= 0)
-		return (HTC_S_OVERFLOW);
-	if (tmo > 0.0) {
-		pfd[0].fd = htc->fd;
-		pfd[0].events = POLLIN;
-		pfd[0].revents = 0;
-		j = (int)floor(tmo * 1e3);
-		if (j == 0)
-			j++;
-		j = poll(pfd, 1, j);
-		if (j == 0)
-			return (HTC_S_TIMEOUT);
-	}
-	i = read(htc->fd, htc->rxbuf_e, i);
-	if (i <= 0)
-		return (HTC_S_EOF);
-	htc->rxbuf_e += i;
-	*htc->rxbuf_e = '\0';
-	return (HTC_S_MORE);
-}
-
 /*----------------------------------------------------------------------
  * Receive a request/packet/whatever, with timeouts
  */
@@ -146,7 +147,7 @@ HTC_RxReq(struct req *req, htc_complete_f *func)
 	when = sp->t_idle + cache_param->timeout_idle;
 	tmo = cache_param->timeout_linger;
 	while (1) {
-		hs = HTC_Rx(req->htc, tmo);
+		hs = htc_rx(req->htc, tmo);
 		now = VTIM_real();
 		if (hs == HTC_S_EOF) {
 			WS_ReleaseP(req->htc->ws, req->htc->rxbuf_b);
@@ -209,7 +210,7 @@ HTC_RxResp(struct busyobj *bo, htc_complete_f *func)
 
 	first = 1;
 	do {
-		hs = HTC_Rx(htc, 0);
+		hs = htc_rx(htc, 0);
 		if (hs == HTC_S_MORE)
 			hs = func(htc);
 		if (hs == HTC_S_OVERFLOW) {
-- 
2.1.4


["0005-Make-struct-http_conn-have-an-int-pointer-to-the-fd.patch" (text/x-patch)]

From 500e0377c08b7528f35bfe38acd2bc67fdc43bd7 Mon Sep 17 00:00:00 2001
From: Martin Blix Grydeland <martin@varnish-software.com>
Date: Thu, 9 Jul 2015 11:17:24 +0200
Subject: [PATCH 05/10] Make struct http_conn have an int pointer to the fd

Make struct http_conn have an int pointer to the fd in the owning
struct. This ensures changes (e.g. setting to -1 on close) are visible
throughout.

Add a HTC_InitObj helper function to help set up a struct http_conn
---
 bin/varnishd/cache/cache.h             |  3 ++-
 bin/varnishd/cache/cache_backend.c     |  3 +--
 bin/varnishd/cache/cache_htc.c         | 27 +++++++++++++++++++++------
 bin/varnishd/cache/cache_panic.c       |  6 +++++-
 bin/varnishd/cache/cache_session.c     |  2 +-
 bin/varnishd/http1/cache_http1_fetch.c |  4 ++--
 bin/varnishd/http1/cache_http1_vfp.c   |  2 +-
 7 files changed, 33 insertions(+), 14 deletions(-)

diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h
index 50f7609..31bcf2b 100644
--- a/bin/varnishd/cache/cache.h
+++ b/bin/varnishd/cache/cache.h
@@ -223,7 +223,7 @@ struct http_conn {
 	unsigned		magic;
 #define HTTP_CONN_MAGIC		0x3e19edd1
 
-	int			fd;
+	int			*pfd;
 	enum sess_close		doclose;
 	unsigned		maxbytes;
 	unsigned		maxhdr;
@@ -984,6 +984,7 @@ void SES_Set_String_Attr(struct sess *sp, enum sess_attr a, const char *src);
 const char *SES_Get_String_Attr(const struct sess *sp, enum sess_attr a);
 
 /* cache_htc.c */
+void HTC_InitObj(struct http_conn *htc, int *fd);
 void HTC_RxInit(struct http_conn *htc, struct ws *ws,
     unsigned maxbytes, unsigned maxhdr);
 void HTC_RxReInit(struct http_conn *htc);
diff --git a/bin/varnishd/cache/cache_backend.c b/bin/varnishd/cache/cache_backend.c
index bb5da81..d38b0fc 100644
--- a/bin/varnishd/cache/cache_backend.c
+++ b/bin/varnishd/cache/cache_backend.c
@@ -135,9 +135,8 @@ vbe_dir_getfd(struct worker *wrk, struct backend *bp, struct busyobj *bo)
 	    vc->fd, bp->display_name, abuf2, pbuf2, abuf1, pbuf1);
 
 	bp->vsc->req++;
-	INIT_OBJ(bo->htc, HTTP_CONN_MAGIC);
+	HTC_InitObj(bo->htc, &vc->fd);
 	bo->htc->priv = vc;
-	bo->htc->fd = vc->fd;
 	FIND_TMO(first_byte_timeout,
 	    bo->htc->first_byte_timeout, bo, bp);
 	FIND_TMO(between_bytes_timeout,
diff --git a/bin/varnishd/cache/cache_htc.c b/bin/varnishd/cache/cache_htc.c
index 58cc798..d822fa7 100644
--- a/bin/varnishd/cache/cache_htc.c
+++ b/bin/varnishd/cache/cache_htc.c
@@ -60,7 +60,7 @@ htc_rx(struct http_conn *htc, double tmo)
 	if (i <= 0)
 		return (HTC_S_OVERFLOW);
 	if (tmo > 0.0) {
-		pfd[0].fd = htc->fd;
+		pfd[0].fd = *htc->pfd;
 		pfd[0].events = POLLIN;
 		pfd[0].revents = 0;
 		j = (int)floor(tmo * 1e3);
@@ -70,7 +70,7 @@ htc_rx(struct http_conn *htc, double tmo)
 		if (j == 0)
 			return (HTC_S_TIMEOUT);
 	}
-	i = read(htc->fd, htc->rxbuf_e, i);
+	i = read(*htc->pfd, htc->rxbuf_e, i);
 	if (i <= 0)
 		return (HTC_S_EOF);
 	htc->rxbuf_e += i;
@@ -78,14 +78,29 @@ htc_rx(struct http_conn *htc, double tmo)
 	return (HTC_S_MORE);
 }
 
-/*--------------------------------------------------------------------*/
+/*--------------------------------------------------------------------
+ * Initialize a struct http_conn pointer
+ */
+void
+HTC_InitObj(struct http_conn *htc, int *pfd)
+{
+
+	AN(htc);
+	AN(pfd);
+	INIT_OBJ(htc, HTTP_CONN_MAGIC);
+	htc->pfd = pfd;
+}
+
+/*--------------------------------------------------------------------
+ * Set up a struct http_conn to read from the given workspace.
+ */
 
 void
 HTC_RxInit(struct http_conn *htc, struct ws *ws, unsigned maxbytes,
     unsigned maxhdr)
 {
 
-	htc->magic = HTTP_CONN_MAGIC;
+	CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC);
 	htc->ws = ws;
 	htc->maxbytes = maxbytes;
 	htc->maxhdr = maxhdr;
@@ -206,7 +221,7 @@ HTC_RxResp(struct busyobj *bo, htc_complete_f *func)
 	AN(func);
 
 	htc = bo->htc;
-	VTCP_set_read_timeout(htc->fd, htc->first_byte_timeout);
+	VTCP_set_read_timeout(*htc->pfd, htc->first_byte_timeout);
 
 	first = 1;
 	do {
@@ -230,7 +245,7 @@ HTC_RxResp(struct busyobj *bo, htc_complete_f *func)
 		}
 		if (first) {
 			first = 0;
-			VTCP_set_read_timeout(htc->fd,
+			VTCP_set_read_timeout(*htc->pfd,
 			    htc->between_bytes_timeout);
 		}
 	} while (hs != HTC_S_COMPLETE);
diff --git a/bin/varnishd/cache/cache_panic.c b/bin/varnishd/cache/cache_panic.c
index c35ddaa..aaeb7a3 100644
--- a/bin/varnishd/cache/cache_panic.c
+++ b/bin/varnishd/cache/cache_panic.c
@@ -148,7 +148,11 @@ pan_htc(struct vsb *vsb, const struct http_conn *htc)
 {
 
 	VSB_printf(vsb, "http_conn = %p {\n", htc);
-	VSB_printf(vsb, "  fd = %d,\n", htc->fd);
+	VSB_printf(vsb, "  pfd = %p(", htc->pfd);
+	if (htc->pfd)
+		VSB_printf(vsb, "<nil>),\n");
+	else
+		VSB_printf(vsb, "%d),\n", *htc->pfd);
 	VSB_printf(vsb, "},\n");
 }
 
diff --git a/bin/varnishd/cache/cache_session.c b/bin/varnishd/cache/cache_session.c
index 6dcf6f6..aebc433 100644
--- a/bin/varnishd/cache/cache_session.c
+++ b/bin/varnishd/cache/cache_session.c
@@ -232,7 +232,7 @@ SES_Proto_Sess(struct worker *wrk, void *arg)
 	(void)VTCP_blocking(sp->fd);
 	req = Req_New(wrk, sp);
 	CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
-	req->htc->fd = sp->fd;
+	HTC_InitObj(req->htc, &sp->fd);
 	HTC_RxInit(req->htc, req->ws,
 	    cache_param->http_req_size, cache_param->http_req_hdr_len);
 
diff --git a/bin/varnishd/http1/cache_http1_fetch.c b/bin/varnishd/http1/cache_http1_fetch.c
index 5084a9e..7f32b32 100644
--- a/bin/varnishd/http1/cache_http1_fetch.c
+++ b/bin/varnishd/http1/cache_http1_fetch.c
@@ -96,8 +96,8 @@ V1F_SendReq(struct worker *wrk, struct busyobj *bo, uint64_t *ctr,
 		do_chunked = 1;
 	}
 
-	(void)VTCP_blocking(htc->fd);	/* XXX: we should timeout instead */
-	V1L_Reserve(wrk, wrk->aws, &htc->fd, bo->vsl, bo->t_prev);
+	(void)VTCP_blocking(*htc->pfd);	/* XXX: we should timeout instead */
+	V1L_Reserve(wrk, wrk->aws, htc->pfd, bo->vsl, bo->t_prev);
 	*ctr += HTTP1_Write(wrk, hp, HTTP1_Req);
 
 	/* Deal with any message-body the request might (still) have */
diff --git a/bin/varnishd/http1/cache_http1_vfp.c b/bin/varnishd/http1/cache_http1_vfp.c
index c63716d..83d483e 100644
--- a/bin/varnishd/http1/cache_http1_vfp.c
+++ b/bin/varnishd/http1/cache_http1_vfp.c
@@ -73,7 +73,7 @@ v1f_read(const struct vfp_ctx *vc, struct http_conn *htc, void *d, ssize_t len)
 			htc->pipeline_b = htc->pipeline_e = NULL;
 	}
 	if (len > 0) {
-		i = read(htc->fd, p, len);
+		i = read(*htc->pfd, p, len);
 		if (i < 0) {
 			// XXX: VTCP_Assert(i); // but also: EAGAIN
 			VSLb(vc->wrk->vsl, SLT_FetchError,
-- 
2.1.4


["0006-Make-V1L_Reserve-take-a-pointer-to-a-struct-http_con.patch" (text/x-patch)]

From 6e014de5a89813b6a0ba60f75a7ca54e69ecd11d Mon Sep 17 00:00:00 2001
From: Martin Blix Grydeland <martin@varnish-software.com>
Date: Thu, 9 Jul 2015 13:19:07 +0200
Subject: [PATCH 06/10] Make V1L_Reserve take a pointer to a struct http_conn

Instead of being handed an fd pointer, take the pointer to a struct
http_conn instead.
---
 bin/varnishd/http1/cache_http1.h         |  4 ++--
 bin/varnishd/http1/cache_http1_deliver.c |  2 +-
 bin/varnishd/http1/cache_http1_fetch.c   |  2 +-
 bin/varnishd/http1/cache_http1_line.c    | 21 +++++++++++----------
 4 files changed, 15 insertions(+), 14 deletions(-)

diff --git a/bin/varnishd/http1/cache_http1.h b/bin/varnishd/http1/cache_http1.h
index f717b78..050fb77 100644
--- a/bin/varnishd/http1/cache_http1.h
+++ b/bin/varnishd/http1/cache_http1.h
@@ -56,8 +56,8 @@ void V1P_Charge(struct req *, const struct v1p_acct *, struct VSC_C_vbe *);
 /* cache_http1_line.c */
 void V1L_Chunked(const struct worker *w);
 void V1L_EndChunk(const struct worker *w);
-void V1L_Reserve(struct worker *, struct ws *, int *fd, struct vsl_log *,
-    double t0);
+void V1L_Reserve(struct worker *, struct ws *, struct http_conn *,
+    struct vsl_log *, double t0);
 unsigned V1L_Flush(const struct worker *w);
 unsigned V1L_FlushRelease(struct worker *w);
 size_t V1L_Write(const struct worker *w, const void *ptr, ssize_t len);
diff --git a/bin/varnishd/http1/cache_http1_deliver.c b/bin/varnishd/http1/cache_http1_deliver.c
index f0762df..6b0ffb0 100644
--- a/bin/varnishd/http1/cache_http1_deliver.c
+++ b/bin/varnishd/http1/cache_http1_deliver.c
@@ -105,7 +105,7 @@ V1D_Deliver(struct req *req, struct busyobj *bo)
 
 	VDP_push(req, v1d_bytes, NULL, 1);
 
-	V1L_Reserve(req->wrk, req->ws, &req->sp->fd, req->vsl, req->t_prev);
+	V1L_Reserve(req->wrk, req->ws, req->htc, req->vsl, req->t_prev);
 
 	req->acct.resp_hdrbytes += HTTP1_Write(req->wrk, req->resp, HTTP1_Resp);
 	if (DO_DEBUG(DBG_FLUSH_HEAD))
diff --git a/bin/varnishd/http1/cache_http1_fetch.c b/bin/varnishd/http1/cache_http1_fetch.c
index 7f32b32..dfa0d3a 100644
--- a/bin/varnishd/http1/cache_http1_fetch.c
+++ b/bin/varnishd/http1/cache_http1_fetch.c
@@ -97,7 +97,7 @@ V1F_SendReq(struct worker *wrk, struct busyobj *bo, uint64_t *ctr,
 	}
 
 	(void)VTCP_blocking(*htc->pfd);	/* XXX: we should timeout instead */
-	V1L_Reserve(wrk, wrk->aws, htc->pfd, bo->vsl, bo->t_prev);
+	V1L_Reserve(wrk, wrk->aws, htc, bo->vsl, bo->t_prev);
 	*ctr += HTTP1_Write(wrk, hp, HTTP1_Req);
 
 	/* Deal with any message-body the request might (still) have */
diff --git a/bin/varnishd/http1/cache_http1_line.c b/bin/varnishd/http1/cache_http1_line.c
index 2bcaf6e..448f208 100644
--- a/bin/varnishd/http1/cache_http1_line.c
+++ b/bin/varnishd/http1/cache_http1_line.c
@@ -49,7 +49,7 @@
 struct v1l {
 	unsigned		magic;
 #define V1L_MAGIC		0x2f2142e5
-	int			*wfd;
+	struct http_conn	*htc;
 	unsigned		werr;	/* valid after V1L_Flush() */
 	struct iovec		*iov;
 	unsigned		siov;
@@ -68,14 +68,15 @@ struct v1l {
  */
 
 void
-V1L_Reserve(struct worker *wrk, struct ws *ws, int *fd, struct vsl_log *vsl,
-    double t0)
+V1L_Reserve(struct worker *wrk, struct ws *ws, struct http_conn *htc,
+    struct vsl_log *vsl, double t0)
 {
 	struct v1l *v1l;
 	unsigned u;
 	void *res;
 
 	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
+	CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC);
 	AZ(wrk->v1l);
 
 	res = WS_Snapshot(ws);
@@ -98,7 +99,7 @@ V1L_Reserve(struct worker *wrk, struct ws *ws, int *fd, struct vsl_log *vsl,
 	v1l->werr = 0;
 	v1l->liov = 0;
 	v1l->niov = 0;
-	v1l->wfd = fd;
+	v1l->htc = htc;
 	v1l->t0 = t0;
 	v1l->vsl = vsl;
 	wrk->v1l = v1l;
@@ -154,13 +155,13 @@ V1L_Flush(const struct worker *wrk)
 	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
 	v1l = wrk->v1l;
 	CHECK_OBJ_NOTNULL(v1l, V1L_MAGIC);
-	AN(v1l->wfd);
+	CHECK_OBJ_NOTNULL(v1l->htc, HTTP_CONN_MAGIC);
 
 	/* For chunked, there must be one slot reserved for the chunked tail */
 	if (v1l->ciov < v1l->siov)
 		assert(v1l->niov < v1l->siov);
 
-	if (*v1l->wfd >= 0 && v1l->liov > 0 && v1l->werr == 0) {
+	if (*v1l->htc->pfd >= 0 && v1l->liov > 0 && v1l->werr == 0) {
 		if (v1l->ciov < v1l->siov && v1l->cliov > 0) {
 			/* Add chunk head & tail */
 			bprintf(cbuf, "00%zx\r\n", v1l->cliov);
@@ -177,7 +178,7 @@ V1L_Flush(const struct worker *wrk)
 			v1l->iov[v1l->ciov].iov_len = 0;
 		}
 
-		i = writev(*v1l->wfd, v1l->iov, v1l->niov);
+		i = writev(*v1l->htc->pfd, v1l->iov, v1l->niov);
 		if (i > 0)
 			v1l->cnt += i;
 		while (i != v1l->liov && i > 0) {
@@ -203,7 +204,7 @@ V1L_Flush(const struct worker *wrk)
 			    i, v1l->liov);
 
 			v1l_prune(v1l, i);
-			i = writev(*v1l->wfd, v1l->iov, v1l->niov);
+			i = writev(*v1l->htc->pfd, v1l->iov, v1l->niov);
 			if (i > 0)
 				v1l->cnt += i;
 		}
@@ -230,8 +231,8 @@ V1L_Write(const struct worker *wrk, const void *ptr, ssize_t len)
 	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
 	v1l = wrk->v1l;
 	CHECK_OBJ_NOTNULL(v1l, V1L_MAGIC);
-	AN(v1l->wfd);
-	if (len == 0 || *v1l->wfd < 0)
+	CHECK_OBJ_NOTNULL(v1l->htc, HTTP_CONN_MAGIC);
+	if (len == 0 || *v1l->htc->pfd < 0)
 		return (0);
 	if (len == -1)
 		len = strlen(ptr);
-- 
2.1.4


["0007-Add-pluggable-read-write-function-pointers-to-struct.patch" (text/x-patch)]

From a5690e2b83d5ae469f6ecd12b1aad1e2235c37fb Mon Sep 17 00:00:00 2001
From: Martin Blix Grydeland <martin@varnish-software.com>
Date: Thu, 9 Jul 2015 13:52:04 +0200
Subject: [PATCH 07/10] Add pluggable read/write function pointers to struct
 http_conn

Make the socket read and write calls go through function
pointers. This allows changing the way bits are written (e.g. adding
crypto) while still using the protocol read/write functionality in
Varnish.
---
 bin/varnishd/cache/cache.h            | 42 ++++++++++++++++++++++++++++++++++-
 bin/varnishd/cache/cache_backend.c    |  2 +-
 bin/varnishd/cache/cache_htc.c        |  9 +++++---
 bin/varnishd/cache/cache_session.c    |  2 +-
 bin/varnishd/http1/cache_http1_line.c |  4 ++--
 bin/varnishd/http1/cache_http1_vfp.c  |  2 +-
 6 files changed, 52 insertions(+), 9 deletions(-)

diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h
index 31bcf2b..4eb46df 100644
--- a/bin/varnishd/cache/cache.h
+++ b/bin/varnishd/cache/cache.h
@@ -219,6 +219,8 @@ struct vfp_ctx {
  *
  */
 
+struct htc_oper;
+
 struct http_conn {
 	unsigned		magic;
 #define HTTP_CONN_MAGIC		0x3e19edd1
@@ -236,12 +238,50 @@ struct http_conn {
 	enum body_status	body_status;
 	struct vfp_ctx		vfc[1];
 	void			*priv;
+	const struct htc_oper	*oper;
 
 	/* Timeouts */
 	double			first_byte_timeout;
 	double			between_bytes_timeout;
 };
 
+typedef ssize_t htc_read_f(struct http_conn *, void *, size_t);
+typedef ssize_t htc_write_f(struct http_conn *, void *, size_t);
+typedef ssize_t htc_writev_f(struct http_conn *, const struct iovec *, int);
+
+struct htc_oper {
+	htc_read_f		*read;
+	htc_write_f		*write;
+	htc_writev_f		*writev;
+};
+
+static inline ssize_t
+HTC_read(struct http_conn *htc, void *buf, size_t count)
+{
+	if (htc->oper && htc->oper->read)
+		return (htc->oper->read(htc, buf, count));
+	else
+		return (read(*htc->pfd, buf, count));
+}
+
+static inline ssize_t
+HTC_write(struct http_conn *htc, void *buf, size_t count)
+{
+	if (htc->oper && htc->oper->write)
+		return (htc->oper->write(htc, buf, count));
+	else
+		return (write(*htc->pfd, buf, count));
+}
+
+static inline ssize_t
+HTC_writev(struct http_conn *htc, const struct iovec *iov, int iovcnt)
+{
+	if (htc->oper && htc->oper->writev)
+		return (htc->oper->writev(htc, iov, iovcnt));
+	else
+		return (writev(*htc->pfd, iov, iovcnt));
+}
+
 /*--------------------------------------------------------------------*/
 
 struct acct_req {
@@ -984,7 +1024,7 @@ void SES_Set_String_Attr(struct sess *sp, enum sess_attr a, const char *src);
 const char *SES_Get_String_Attr(const struct sess *sp, enum sess_attr a);
 
 /* cache_htc.c */
-void HTC_InitObj(struct http_conn *htc, int *fd);
+void HTC_InitObj(struct http_conn *htc, int *fd, const struct htc_oper *);
 void HTC_RxInit(struct http_conn *htc, struct ws *ws,
     unsigned maxbytes, unsigned maxhdr);
 void HTC_RxReInit(struct http_conn *htc);
diff --git a/bin/varnishd/cache/cache_backend.c b/bin/varnishd/cache/cache_backend.c
index d38b0fc..3f08eab 100644
--- a/bin/varnishd/cache/cache_backend.c
+++ b/bin/varnishd/cache/cache_backend.c
@@ -135,7 +135,7 @@ vbe_dir_getfd(struct worker *wrk, struct backend *bp, struct busyobj *bo)
 	    vc->fd, bp->display_name, abuf2, pbuf2, abuf1, pbuf1);
 
 	bp->vsc->req++;
-	HTC_InitObj(bo->htc, &vc->fd);
+	HTC_InitObj(bo->htc, &vc->fd, NULL);
 	bo->htc->priv = vc;
 	FIND_TMO(first_byte_timeout,
 	    bo->htc->first_byte_timeout, bo, bp);
diff --git a/bin/varnishd/cache/cache_htc.c b/bin/varnishd/cache/cache_htc.c
index d822fa7..a877245 100644
--- a/bin/varnishd/cache/cache_htc.c
+++ b/bin/varnishd/cache/cache_htc.c
@@ -70,7 +70,7 @@ htc_rx(struct http_conn *htc, double tmo)
 		if (j == 0)
 			return (HTC_S_TIMEOUT);
 	}
-	i = read(*htc->pfd, htc->rxbuf_e, i);
+	i = HTC_read(htc, htc->rxbuf_e, i);
 	if (i <= 0)
 		return (HTC_S_EOF);
 	htc->rxbuf_e += i;
@@ -79,16 +79,19 @@ htc_rx(struct http_conn *htc, double tmo)
 }
 
 /*--------------------------------------------------------------------
- * Initialize a struct http_conn pointer
+ * Initialize a struct http_conn pointer.
+ * oper is an optional pointer to a struct with function pointers
+ * for read/write operations
  */
 void
-HTC_InitObj(struct http_conn *htc, int *pfd)
+HTC_InitObj(struct http_conn *htc, int *pfd, const struct htc_oper *oper)
 {
 
 	AN(htc);
 	AN(pfd);
 	INIT_OBJ(htc, HTTP_CONN_MAGIC);
 	htc->pfd = pfd;
+	htc->oper = oper;
 }
 
 /*--------------------------------------------------------------------
diff --git a/bin/varnishd/cache/cache_session.c b/bin/varnishd/cache/cache_session.c
index aebc433..4f62e25 100644
--- a/bin/varnishd/cache/cache_session.c
+++ b/bin/varnishd/cache/cache_session.c
@@ -232,7 +232,7 @@ SES_Proto_Sess(struct worker *wrk, void *arg)
 	(void)VTCP_blocking(sp->fd);
 	req = Req_New(wrk, sp);
 	CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
-	HTC_InitObj(req->htc, &sp->fd);
+	HTC_InitObj(req->htc, &sp->fd, NULL);
 	HTC_RxInit(req->htc, req->ws,
 	    cache_param->http_req_size, cache_param->http_req_hdr_len);
 
diff --git a/bin/varnishd/http1/cache_http1_line.c b/bin/varnishd/http1/cache_http1_line.c
index 448f208..ef40184 100644
--- a/bin/varnishd/http1/cache_http1_line.c
+++ b/bin/varnishd/http1/cache_http1_line.c
@@ -178,7 +178,7 @@ V1L_Flush(const struct worker *wrk)
 			v1l->iov[v1l->ciov].iov_len = 0;
 		}
 
-		i = writev(*v1l->htc->pfd, v1l->iov, v1l->niov);
+		i = HTC_writev(v1l->htc, v1l->iov, v1l->niov);
 		if (i > 0)
 			v1l->cnt += i;
 		while (i != v1l->liov && i > 0) {
@@ -204,7 +204,7 @@ V1L_Flush(const struct worker *wrk)
 			    i, v1l->liov);
 
 			v1l_prune(v1l, i);
-			i = writev(*v1l->htc->pfd, v1l->iov, v1l->niov);
+			i = HTC_writev(v1l->htc, v1l->iov, v1l->niov);
 			if (i > 0)
 				v1l->cnt += i;
 		}
diff --git a/bin/varnishd/http1/cache_http1_vfp.c b/bin/varnishd/http1/cache_http1_vfp.c
index 83d483e..41a2ef1 100644
--- a/bin/varnishd/http1/cache_http1_vfp.c
+++ b/bin/varnishd/http1/cache_http1_vfp.c
@@ -73,7 +73,7 @@ v1f_read(const struct vfp_ctx *vc, struct http_conn *htc, void *d, ssize_t len)
 			htc->pipeline_b = htc->pipeline_e = NULL;
 	}
 	if (len > 0) {
-		i = read(*htc->pfd, p, len);
+		i = HTC_read(htc, p, len);
 		if (i < 0) {
 			// XXX: VTCP_Assert(i); // but also: EAGAIN
 			VSLb(vc->wrk->vsl, SLT_FetchError,
-- 
2.1.4


["0008-Update-pipe-to-use-struct-http_conn.patch" (text/x-patch)]

From ac7ccf5ec4fe926b91c0c22586463a8621b6a021 Mon Sep 17 00:00:00 2001
From: Martin Blix Grydeland <martin@varnish-software.com>
Date: Thu, 9 Jul 2015 15:19:32 +0200
Subject: [PATCH 08/10] Update pipe to use struct http_conn

---
 bin/varnishd/cache/cache_backend.c    |  4 ++-
 bin/varnishd/http1/cache_http1.h      |  2 +-
 bin/varnishd/http1/cache_http1_pipe.c | 47 ++++++++++++++++-------------------
 3 files changed, 26 insertions(+), 27 deletions(-)

diff --git a/bin/varnishd/cache/cache_backend.c b/bin/varnishd/cache/cache_backend.c
index 3f08eab..40053a5 100644
--- a/bin/varnishd/cache/cache_backend.c
+++ b/bin/varnishd/cache/cache_backend.c
@@ -297,6 +297,7 @@ vbe_dir_http1pipe(const struct director *d, struct req *req, struct busyobj *bo)
 
 	CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC);
 	CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
+	CHECK_OBJ_NOTNULL(req->htc, HTTP_CONN_MAGIC);
 	CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
 	CAST_OBJ_NOTNULL(bp, d->priv, BACKEND_MAGIC);
 
@@ -314,12 +315,13 @@ vbe_dir_http1pipe(const struct director *d, struct req *req, struct busyobj *bo)
 		VSLb(bo->vsl, SLT_FetchError, "no backend connection");
 		SES_Close(req->sp, SC_RX_TIMEOUT);
 	} else {
+		CHECK_OBJ_NOTNULL(bo->htc, HTTP_CONN_MAGIC);
 		i = V1F_SendReq(req->wrk, bo, &v1a.bereq, 1);
 		VSLb_ts_req(req, "Pipe", W_TIM_real(req->wrk));
 		if (vbc->state == VBC_STATE_STOLEN)
 			VBT_Wait(req->wrk, vbc);
 		if (i == 0)
-			V1P_Process(req, vbc->fd, &v1a);
+			V1P_Process(req->htc, bo->htc, &v1a);
 		VSLb_ts_req(req, "PipeSess", W_TIM_real(req->wrk));
 		SES_Close(req->sp, SC_TX_PIPE);
 		bo->htc->doclose = SC_TX_PIPE;
diff --git a/bin/varnishd/http1/cache_http1.h b/bin/varnishd/http1/cache_http1.h
index 050fb77..6041828 100644
--- a/bin/varnishd/http1/cache_http1.h
+++ b/bin/varnishd/http1/cache_http1.h
@@ -50,7 +50,7 @@ struct v1p_acct {
 };
 
 void V1P_Init(void);
-void V1P_Process(struct req *, int fd, struct v1p_acct *);
+void V1P_Process(struct http_conn *, struct http_conn *, struct v1p_acct *);
 void V1P_Charge(struct req *, const struct v1p_acct *, struct VSC_C_vbe *);
 
 /* cache_http1_line.c */
diff --git a/bin/varnishd/http1/cache_http1_pipe.c b/bin/varnishd/http1/cache_http1_pipe.c
index 85df545..e177b2a 100644
--- a/bin/varnishd/http1/cache_http1_pipe.c
+++ b/bin/varnishd/http1/cache_http1_pipe.c
@@ -43,16 +43,16 @@
 static struct lock pipestat_mtx;
 
 static int
-rdf(int fd0, int fd1, uint64_t *pcnt)
+rdf(struct http_conn *htc_r, struct http_conn *htc_w, uint64_t *pcnt)
 {
 	int i, j;
 	char buf[BUFSIZ], *p;
 
-	i = read(fd0, buf, sizeof buf);
+	i = HTC_read(htc_r, buf, sizeof buf);
 	if (i <= 0)
 		return (1);
-	for (p = buf; i > 0; i -= j, p += j) {
-		j = write(fd1, p, i);
+	for (p = buf; i > 0; i-= j, p += j) {
+		j = HTC_write(htc_w, p, i);
 		if (j <= 0)
 			return (1);
 		*pcnt += j;
@@ -84,52 +84,49 @@ V1P_Charge(struct req *req, const struct v1p_acct *a, struct VSC_C_vbe *b)
 }
 
 void
-V1P_Process(struct req *req, int fd, struct v1p_acct *v1a)
+V1P_Process(struct http_conn *htc_c, struct http_conn *htc_b,
+    struct v1p_acct *v1a)
 {
 	struct pollfd fds[2];
 	int i, j;
 
-	CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
-	CHECK_OBJ_NOTNULL(req->sp, SESS_MAGIC);
-	assert(fd > 0);
+	CHECK_OBJ_NOTNULL(htc_c, HTTP_CONN_MAGIC);
+	CHECK_OBJ_NOTNULL(htc_b, HTTP_CONN_MAGIC);
 
-	if (req->htc->pipeline_b != NULL) {
-		j = write(fd,  req->htc->pipeline_b,
-		    req->htc->pipeline_e - req->htc->pipeline_b);
+	if (htc_c->pipeline_b != NULL) {
+		j = HTC_write(htc_b,  htc_c->pipeline_b,
+		    htc_c->pipeline_e - htc_c->pipeline_b);
 		if (j < 0)
 			return;
-		req->htc->pipeline_b = NULL;
-		req->htc->pipeline_e = NULL;
+		htc_c->pipeline_b = NULL;
+		htc_c->pipeline_e = NULL;
 		v1a->in += j;
 	}
 	memset(fds, 0, sizeof fds);
-	fds[0].fd = fd;
+	fds[0].fd = *htc_b->pfd;
 	fds[0].events = POLLIN | POLLERR;
-	fds[1].fd = req->sp->fd;
+	fds[1].fd = *htc_c->pfd;
 	fds[1].events = POLLIN | POLLERR;
 
 	while (fds[0].fd > -1 || fds[1].fd > -1) {
 		fds[0].revents = 0;
 		fds[1].revents = 0;
-		i = poll(fds, 2,
-		    (int)(cache_param->pipe_timeout * 1e3));
+		i = poll(fds, 2, (int)(cache_param->pipe_timeout * 1e3));
 		if (i < 1)
 			break;
-		if (fds[0].revents &&
-		    rdf(fd, req->sp->fd, &v1a->out)) {
+		if (fds[0].revents && rdf(htc_b, htc_c, &v1a->out)) {
 			if (fds[1].fd == -1)
 				break;
-			(void)shutdown(fd, SHUT_RD);
-			(void)shutdown(req->sp->fd, SHUT_WR);
+			(void)shutdown(*htc_b->pfd, SHUT_RD);
+			(void)shutdown(*htc_c->pfd, SHUT_WR);
 			fds[0].events = 0;
 			fds[0].fd = -1;
 		}
-		if (fds[1].revents &&
-		    rdf(req->sp->fd, fd, &v1a->in)) {
+		if (fds[1].revents && rdf(htc_c, htc_b, &v1a->in)) {
 			if (fds[0].fd == -1)
 				break;
-			(void)shutdown(req->sp->fd, SHUT_RD);
-			(void)shutdown(fd, SHUT_WR);
+			(void)shutdown(*htc_c->pfd, SHUT_RD);
+			(void)shutdown(*htc_b->pfd, SHUT_WR);
 			fds[1].events = 0;
 			fds[1].fd = -1;
 		}
-- 
2.1.4


["0009-Make-pan_htc-more-useful.patch" (text/x-patch)]

From 95cffb69f43ca6e088dc633c65bc07f84475caf2 Mon Sep 17 00:00:00 2001
From: Martin Blix Grydeland <martin@varnish-software.com>
Date: Thu, 9 Jul 2015 15:52:17 +0200
Subject: [PATCH 09/10] Make pan_htc more useful

---
 bin/varnishd/cache/cache_panic.c | 30 ++++++++++++++++++++++--------
 1 file changed, 22 insertions(+), 8 deletions(-)

diff --git a/bin/varnishd/cache/cache_panic.c b/bin/varnishd/cache/cache_panic.c
index aaeb7a3..482e11f 100644
--- a/bin/varnishd/cache/cache_panic.c
+++ b/bin/varnishd/cache/cache_panic.c
@@ -148,11 +148,27 @@ pan_htc(struct vsb *vsb, const struct http_conn *htc)
 {
 
 	VSB_printf(vsb, "http_conn = %p {\n", htc);
-	VSB_printf(vsb, "  pfd = %p(", htc->pfd);
+	VSB_indent(vsb, 2);
+	VSB_printf(vsb, "pfd = %p(", htc->pfd);
 	if (htc->pfd)
 		VSB_printf(vsb, "<nil>),\n");
 	else
 		VSB_printf(vsb, "%d),\n", *htc->pfd);
+	VSB_printf(vsb, "doclose = %s,\n", sess_close_2str(htc->doclose, 0));
+	VSB_printf(vsb, "ws = %p,\n", htc->ws);
+	VSB_printf(vsb, "{rxbuf_b, rxbuf_e} = {%p, %p},\n",
+	    htc->rxbuf_b, htc->rxbuf_e);
+	VSB_printf(vsb, "{pipeline_b, pipeline_e} = {%p, %p},\n",
+	    htc->pipeline_b, htc->pipeline_e);
+	VSB_printf(vsb, "content_length = %jd,\n", htc->content_length);
+	VSB_printf(vsb, "body_status = %s,\n",
+	    body_status_2str(htc->body_status));
+	VSB_printf(vsb, "oper = %p,\n", htc->oper);
+	VSB_printf(vsb, "first_byte_timeout = %f,\n",
+	    htc->first_byte_timeout);
+	VSB_printf(vsb, "between_bytes_timeout = %f,\n",
+	    htc->between_bytes_timeout);
+	VSB_indent(vsb, -2);
 	VSB_printf(vsb, "},\n");
 }
 
@@ -327,11 +343,9 @@ pan_busyobj(struct vsb *vsb, const struct busyobj *bo)
 	VSB_indent(vsb, -2);
 	VSB_printf(vsb, "},\n");
 
-	if (bo->htc != NULL) {
-		VSB_printf(vsb, "bodystatus = %d (%s),\n",
-		    bo->htc->body_status,
-		    body_status_2str(bo->htc->body_status));
-	}
+	if (VALID_OBJ(bo->htc, HTTP_CONN_MAGIC))
+		pan_htc(vsb, bo->htc);
+
 	if (!VTAILQ_EMPTY(&bo->vfc->vfp)) {
 		VSB_printf(vsb, "filters =");
 		VTAILQ_FOREACH(vfe, &bo->vfc->vfp, list)
@@ -340,8 +354,6 @@ pan_busyobj(struct vsb *vsb, const struct busyobj *bo)
 		VSB_printf(vsb, "\n");
 	}
 
-	if (VALID_OBJ(bo->htc, HTTP_CONN_MAGIC))
-		pan_htc(vsb, bo->htc);
 	VDI_Panic(bo->director_req, vsb, "director_req");
 	if (bo->director_resp == bo->director_req)
 		VSB_printf(vsb, "director_resp = director_req,\n");
@@ -402,6 +414,8 @@ pan_req(struct vsb *vsb, const struct req *req)
 		pan_wrk(vsb, req->wrk);
 
 	pan_ws(vsb, req->ws);
+	if (VALID_OBJ(req->htc, HTTP_CONN_MAGIC))
+		pan_htc(vsb, req->htc);
 	pan_http(vsb, "req", req->http);
 	if (req->resp->ws != NULL)
 		pan_http(vsb, "resp", req->resp);
-- 
2.1.4


["0010-Add-a-panic-operation-to-htc-for-custom-panic-messag.patch" (text/x-patch)]

From f5e7a72bb4c8818363a643c0ee09c7e54d296833 Mon Sep 17 00:00:00 2001
From: Martin Blix Grydeland <martin@varnish-software.com>
Date: Thu, 9 Jul 2015 17:19:35 +0200
Subject: [PATCH 10/10] Add a panic operation to htc for custom panic message

---
 bin/varnishd/cache/cache.h       | 2 ++
 bin/varnishd/cache/cache_panic.c | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h
index 4eb46df..71c144d 100644
--- a/bin/varnishd/cache/cache.h
+++ b/bin/varnishd/cache/cache.h
@@ -248,11 +248,13 @@ struct http_conn {
 typedef ssize_t htc_read_f(struct http_conn *, void *, size_t);
 typedef ssize_t htc_write_f(struct http_conn *, void *, size_t);
 typedef ssize_t htc_writev_f(struct http_conn *, const struct iovec *, int);
+typedef ssize_t htc_panic_f(struct vsb *, const struct http_conn *);
 
 struct htc_oper {
 	htc_read_f		*read;
 	htc_write_f		*write;
 	htc_writev_f		*writev;
+	htc_panic_f		*panic;
 };
 
 static inline ssize_t
diff --git a/bin/varnishd/cache/cache_panic.c b/bin/varnishd/cache/cache_panic.c
index 482e11f..4b334db 100644
--- a/bin/varnishd/cache/cache_panic.c
+++ b/bin/varnishd/cache/cache_panic.c
@@ -168,6 +168,8 @@ pan_htc(struct vsb *vsb, const struct http_conn *htc)
 	    htc->first_byte_timeout);
 	VSB_printf(vsb, "between_bytes_timeout = %f,\n",
 	    htc->between_bytes_timeout);
+	if (htc->oper && htc->oper->panic)
+		htc->oper->panic(vsb, htc);
 	VSB_indent(vsb, -2);
 	VSB_printf(vsb, "},\n");
 }
-- 
2.1.4



_______________________________________________
varnish-dev mailing list
varnish-dev@varnish-cache.org
https://www.varnish-cache.org/lists/mailman/listinfo/varnish-dev

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic