[master] 6f39693 Move the primitives for buffered reads on sockets into cache_session.c (for lack of any better place) since they will become involved in protocol switching.

Poul-Henning Kamp phk at FreeBSD.org
Mon Mar 23 14:41:46 CET 2015


commit 6f396932bbcdb1d33475b66f83bbb7288cf12aee
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Mon Mar 23 11:01:45 2015 +0000

    Move the primitives for buffered reads on sockets into cache_session.c
    (for lack of any better place) since they will become involved in
    protocol switching.

diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h
index c39edc6..6619c5a 100644
--- a/bin/varnishd/cache/cache.h
+++ b/bin/varnishd/cache/cache.h
@@ -853,19 +853,7 @@ enum sess_close http_DoConnection(struct http *hp);
 
 /* cache_http1_proto.c */
 
-enum http1_status_e {
-	HTTP1_ALL_WHITESPACE =	-3,
-	HTTP1_OVERFLOW =	-2,
-	HTTP1_ERROR_EOF =	-1,
-	HTTP1_NEED_MORE =	 0,
-	HTTP1_COMPLETE =	 1
-};
-
-void HTTP1_RxInit(struct http_conn *htc, struct ws *ws,
-    unsigned maxbytes, unsigned maxhdr);
-enum http1_status_e HTTP1_Reinit(struct http_conn *htc);
-enum http1_status_e HTTP1_Rx(struct http_conn *htc);
-enum http1_status_e HTTP1_Complete(struct http_conn *htc);
+enum htc_status_e HTTP1_Complete(struct http_conn *htc);
 uint16_t HTTP1_DissectRequest(struct http_conn *htc, struct http *hp);
 uint16_t HTTP1_DissectResponse(struct http *sp, struct http_conn *htc);
 unsigned HTTP1_Write(const struct worker *w, const struct http *hp, const int*);
@@ -995,6 +983,19 @@ struct req *SES_GetReq(const struct worker *, struct sess *);
 void SES_ReleaseReq(struct req *);
 task_func_t SES_Proto_Sess;
 
+enum htc_status_e {
+	HTC_S_EMPTY =	-3,
+	HTC_S_OVERFLOW =	-2,
+	HTC_S_EOF =	-1,
+	HTC_S_OK =	 0,
+	HTC_S_COMPLETE =	 1
+};
+
+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);
+
 #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);
diff --git a/bin/varnishd/cache/cache_session.c b/bin/varnishd/cache/cache_session.c
index 792964b..d7d77a7 100644
--- a/bin/varnishd/cache/cache_session.c
+++ b/bin/varnishd/cache/cache_session.c
@@ -153,6 +153,84 @@ 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)
+{
+	int i;
+
+	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) {
+		WS_ReleaseP(htc->ws, htc->rxbuf_b);
+		return (HTC_S_OVERFLOW);
+	}
+	i = read(htc->fd, htc->rxbuf_e, i);
+	if (i <= 0) {
+		/*
+		 * We wouldn't come here if we had a complete HTTP header
+		 * so consequently an EOF can not be OK
+		 */
+		WS_ReleaseP(htc->ws, htc->rxbuf_b);
+		return (HTC_S_EOF);
+	}
+	htc->rxbuf_e += i;
+	*htc->rxbuf_e = '\0';
+	return (HTC_S_OK);
+}
+
 /*--------------------------------------------------------------------
  * Get a new session, preferably by recycling an already ready one
  *
diff --git a/bin/varnishd/http1/cache_http1_fetch.c b/bin/varnishd/http1/cache_http1_fetch.c
index 1cb7959..6308b8c 100644
--- a/bin/varnishd/http1/cache_http1_fetch.c
+++ b/bin/varnishd/http1/cache_http1_fetch.c
@@ -76,7 +76,7 @@ int
 V1F_fetch_hdr(struct worker *wrk, struct busyobj *bo, const char *def_host)
 {
 	struct http *hp;
-	enum http1_status_e hs;
+	enum htc_status_e hs;
 	int retry = 1;
 	int j, first;
 	ssize_t i;
@@ -144,7 +144,7 @@ V1F_fetch_hdr(struct worker *wrk, struct busyobj *bo, const char *def_host)
 
 	/* Receive response */
 
-	HTTP1_RxInit(htc, bo->ws, cache_param->http_resp_size,
+	SES_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);
@@ -153,8 +153,10 @@ V1F_fetch_hdr(struct worker *wrk, struct busyobj *bo, const char *def_host)
 
 	first = 1;
 	do {
-		hs = HTTP1_Rx(htc);
-		if (hs == HTTP1_OVERFLOW) {
+		hs = SES_Rx(htc);
+		if (hs == HTC_S_OK)
+			hs = HTTP1_Complete(htc);
+		if (hs == HTC_S_OVERFLOW) {
 			bo->acct.beresp_hdrbytes +=
 			    htc->rxbuf_e - htc->rxbuf_b;
 			VSLb(bo->vsl, SLT_FetchError,
@@ -163,7 +165,7 @@ V1F_fetch_hdr(struct worker *wrk, struct busyobj *bo, const char *def_host)
 			bo->doclose = SC_RX_OVERFLOW;
 			return (-1);
 		}
-		if (hs == HTTP1_ERROR_EOF) {
+		if (hs == HTC_S_EOF) {
 			bo->acct.beresp_hdrbytes +=
 			    htc->rxbuf_e - htc->rxbuf_b;
 			VSLb(bo->vsl, SLT_FetchError, "http %sread error: EOF",
@@ -177,7 +179,7 @@ V1F_fetch_hdr(struct worker *wrk, struct busyobj *bo, const char *def_host)
 			VTCP_set_read_timeout(htc->fd,
 			    htc->between_bytes_timeout);
 		}
-	} while (hs != HTTP1_COMPLETE);
+	} while (hs != HTC_S_COMPLETE);
 	bo->acct.beresp_hdrbytes += htc->rxbuf_e - htc->rxbuf_b;
 
 	hp = bo->beresp;
diff --git a/bin/varnishd/http1/cache_http1_fsm.c b/bin/varnishd/http1/cache_http1_fsm.c
index a88e4ca..698dc79 100644
--- a/bin/varnishd/http1/cache_http1_fsm.c
+++ b/bin/varnishd/http1/cache_http1_fsm.c
@@ -56,7 +56,7 @@ http1_wait(struct sess *sp, struct worker *wrk, struct req *req)
 	struct pollfd pfd[1];
 	double now, when;
 	enum sess_close why = SC_NULL;
-	enum http1_status_e hs;
+	enum htc_status_e hs;
 
 	CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
 	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
@@ -80,10 +80,12 @@ http1_wait(struct sess *sp, struct worker *wrk, struct req *req)
 		assert(j >= 0);
 		now = VTIM_real();
 		if (j != 0)
-			hs = HTTP1_Rx(req->htc);
+			hs = SES_Rx(req->htc);
 		else
+			hs = HTC_S_OK;			// XXX HTC_S_TIMEOUT ?
+		if (hs == HTC_S_OK)
 			hs = HTTP1_Complete(req->htc);
-		if (hs == HTTP1_COMPLETE) {
+		if (hs == HTC_S_COMPLETE) {
 			/* Got it, run with it */
 			if (isnan(req->t_first))
 				req->t_first = now;
@@ -92,13 +94,13 @@ http1_wait(struct sess *sp, struct worker *wrk, struct req *req)
 			req->acct.req_hdrbytes +=
 			    req->htc->rxbuf_e - req->htc->rxbuf_b;
 			return (REQ_FSM_MORE);
-		} else if (hs == HTTP1_ERROR_EOF) {
+		} else if (hs == HTC_S_EOF) {
 			why = SC_REM_CLOSE;
 			break;
-		} else if (hs == HTTP1_OVERFLOW) {
+		} else if (hs == HTC_S_OVERFLOW) {
 			why = SC_RX_OVERFLOW;
 			break;
-		} else if (hs == HTTP1_ALL_WHITESPACE) {
+		} else if (hs == HTC_S_EMPTY) {
 			/* Nothing but whitespace */
 			when = sp->t_idle + cache_param->timeout_idle;
 			if (when < now) {
@@ -208,7 +210,8 @@ http1_cleanup(struct sess *sp, struct worker *wrk, struct req *req)
 	WS_Reset(req->ws, NULL);
 	WS_Reset(wrk->aws, NULL);
 
-	if (HTTP1_Reinit(req->htc) == HTTP1_COMPLETE) {
+	SES_RxReInit(req->htc);
+	if (HTTP1_Complete(req->htc) == HTC_S_COMPLETE) {
 		AZ(req->vsl->wid);
 		req->t_first = req->t_req = sp->t_idle;
 		wrk->stats->sess_pipeline++;
@@ -372,7 +375,7 @@ HTTP1_Session(struct worker *wrk, struct req *req)
 
 	if (sp->sess_step == S_STP_H1NEWREQ) {
 		req->htc->fd = sp->fd;
-		HTTP1_RxInit(req->htc, req->ws,
+		SES_RxInit(req->htc, req->ws,
 		    cache_param->http_req_size, cache_param->http_req_hdr_len);
 	}
 
diff --git a/bin/varnishd/http1/cache_http1_proto.c b/bin/varnishd/http1/cache_http1_proto.c
index 15e4b77..28cbc0f 100644
--- a/bin/varnishd/http1/cache_http1_proto.c
+++ b/bin/varnishd/http1/cache_http1_proto.c
@@ -57,58 +57,11 @@ const int HTTP1_Resp[3] = {
 	HTTP_HDR_PROTO, HTTP_HDR_STATUS, HTTP_HDR_REASON
 };
 
-/*--------------------------------------------------------------------*/
-
-void
-HTTP1_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.
- */
-
-enum http1_status_e
-HTTP1_Reinit(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';
-	return (HTTP1_Complete(htc));
-}
-
 /*--------------------------------------------------------------------
  * Check if we have a complete HTTP request or response yet
  */
 
-enum http1_status_e
+enum htc_status_e
 HTTP1_Complete(struct http_conn *htc)
 {
 	char *p;
@@ -127,12 +80,12 @@ HTTP1_Complete(struct http_conn *htc)
 		/* All white space */
 		htc->rxbuf_e = htc->rxbuf_b;
 		*htc->rxbuf_e = '\0';
-		return (HTTP1_ALL_WHITESPACE);
+		return (HTC_S_EMPTY);
 	}
 	while (1) {
 		p = strchr(p, '\n');
 		if (p == NULL)
-			return (HTTP1_NEED_MORE);
+			return (HTC_S_OK);
 		p++;
 		if (*p == '\r')
 			p++;
@@ -146,39 +99,7 @@ HTTP1_Complete(struct http_conn *htc)
 		htc->pipeline_e = htc->rxbuf_e;
 		htc->rxbuf_e = p;
 	}
-	return (HTTP1_COMPLETE);
-}
-
-/*--------------------------------------------------------------------
- * Receive more HTTP protocol bytes
- */
-
-enum http1_status_e
-HTTP1_Rx(struct http_conn *htc)
-{
-	int i;
-
-	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) {
-		WS_ReleaseP(htc->ws, htc->rxbuf_b);
-		return (HTTP1_OVERFLOW);
-	}
-	i = read(htc->fd, htc->rxbuf_e, i);
-	if (i <= 0) {
-		/*
-		 * We wouldn't come here if we had a complete HTTP header
-		 * so consequently an EOF can not be OK
-		 */
-		WS_ReleaseP(htc->ws, htc->rxbuf_b);
-		return (HTTP1_ERROR_EOF);
-	}
-	htc->rxbuf_e += i;
-	*htc->rxbuf_e = '\0';
-	return (HTTP1_Complete(htc));
+	return (HTC_S_COMPLETE);
 }
 
 /*--------------------------------------------------------------------



More information about the varnish-commit mailing list