[master] cb87982 Make Connection: handling an entirely internal http1 issue.

Poul-Henning Kamp phk at FreeBSD.org
Mon Jul 14 16:58:18 CEST 2014


commit cb879824e2114a711111d830377e3327098de836
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Mon Jul 14 14:57:54 2014 +0000

    Make Connection: handling an entirely internal http1 issue.

diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h
index 7579b35..7cea69d 100644
--- a/bin/varnishd/cache/cache.h
+++ b/bin/varnishd/cache/cache.h
@@ -198,6 +198,7 @@ struct http {
 	uint16_t		status;
 	uint8_t			protover;
 	uint8_t			conds;		/* If-* headers present */
+	enum sess_close		doclose;
 };
 
 /*--------------------------------------------------------------------
@@ -958,7 +959,7 @@ void http_Merge(const struct http *fm, struct http *to, int not_ce);
 
 /* cache_http1_proto.c */
 
-enum htc_status_e {
+enum http1_status_e {
 	HTTP1_ALL_WHITESPACE =	-3,
 	HTTP1_OVERFLOW =	-2,
 	HTTP1_ERROR_EOF =	-1,
@@ -968,13 +969,12 @@ enum htc_status_e {
 
 void HTTP1_Init(struct http_conn *htc, struct ws *ws, int fd, struct vsl_log *,
     unsigned maxbytes, unsigned maxhdr);
-enum htc_status_e HTTP1_Reinit(struct http_conn *htc);
-enum htc_status_e HTTP1_Rx(struct http_conn *htc);
+enum http1_status_e HTTP1_Reinit(struct http_conn *htc);
+enum http1_status_e HTTP1_Rx(struct http_conn *htc);
 ssize_t HTTP1_Read(struct http_conn *htc, void *d, size_t len);
-enum htc_status_e HTTP1_Complete(struct http_conn *htc);
+enum http1_status_e HTTP1_Complete(struct http_conn *htc);
 uint16_t HTTP1_DissectRequest(struct req *);
 uint16_t HTTP1_DissectResponse(struct http *sp, const struct http_conn *htc);
-enum sess_close HTTP1_DoConnection(struct http *);
 unsigned HTTP1_Write(const struct worker *w, const struct http *hp, const int*);
 
 #define HTTPH(a, b, c) extern char b[];
diff --git a/bin/varnishd/cache/cache_http1_fetch.c b/bin/varnishd/cache/cache_http1_fetch.c
index 57fc5d5..a36cc70 100644
--- a/bin/varnishd/cache/cache_http1_fetch.c
+++ b/bin/varnishd/cache/cache_http1_fetch.c
@@ -238,7 +238,7 @@ V1F_fetch_hdr(struct worker *wrk, struct busyobj *bo, struct req *req)
 {
 	struct vbc *vc;
 	struct http *hp;
-	enum htc_status_e hs;
+	enum http1_status_e hs;
 	int retry = -1;
 	int i, j, first;
 	struct http_conn *htc;
@@ -371,6 +371,6 @@ V1F_fetch_hdr(struct worker *wrk, struct busyobj *bo, struct req *req)
 		return (-1);
 	}
 
-	bo->doclose = HTTP1_DoConnection(hp);
+	bo->doclose = hp->doclose;
 	return (0);
 }
diff --git a/bin/varnishd/cache/cache_http1_fsm.c b/bin/varnishd/cache/cache_http1_fsm.c
index 30f212a..b6f08be 100644
--- a/bin/varnishd/cache/cache_http1_fsm.c
+++ b/bin/varnishd/cache/cache_http1_fsm.c
@@ -92,7 +92,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 htc_status_e hs;
+	enum http1_status_e hs;
 
 	CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
 	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
@@ -380,7 +380,7 @@ http1_dissect(struct worker *wrk, struct req *req)
 
 	AZ(req->err_code);
 	req->ws_req = WS_Snapshot(req->ws);
-	req->doclose = HTTP1_DoConnection(req->http);
+	req->doclose = req->http->doclose;
 
 	http_Unset(req->http, H_Expect);
 
diff --git a/bin/varnishd/cache/cache_http1_proto.c b/bin/varnishd/cache/cache_http1_proto.c
index 6abd62e..40af2cf 100644
--- a/bin/varnishd/cache/cache_http1_proto.c
+++ b/bin/varnishd/cache/cache_http1_proto.c
@@ -88,7 +88,7 @@ HTTP1_Init(struct http_conn *htc, struct ws *ws, int fd, struct vsl_log *vsl,
  * the ws somewhere, because WS_Reset only fiddles pointers.
  */
 
-enum htc_status_e
+enum http1_status_e
 HTTP1_Reinit(struct http_conn *htc)
 {
 	unsigned l;
@@ -112,7 +112,7 @@ HTTP1_Reinit(struct http_conn *htc)
  * Check if we have a complete HTTP request or response yet
  */
 
-enum htc_status_e
+enum http1_status_e
 HTTP1_Complete(struct http_conn *htc)
 {
 	char *p;
@@ -159,7 +159,7 @@ HTTP1_Complete(struct http_conn *htc)
  * Receive more HTTP protocol bytes
  */
 
-enum htc_status_e
+enum http1_status_e
 HTTP1_Rx(struct http_conn *htc)
 {
 	int i;
@@ -228,7 +228,7 @@ HTTP1_Read(struct http_conn *htc, void *d, size_t len)
  */
 
 static uint16_t
-htc_dissect_hdrs(struct http *hp, char *p, const struct http_conn *htc)
+http1_dissect_hdrs(struct http *hp, char *p, const struct http_conn *htc)
 {
 	char *q, *r;
 	txt t = htc->rxbuf;
@@ -304,7 +304,7 @@ htc_dissect_hdrs(struct http *hp, char *p, const struct http_conn *htc)
  */
 
 static uint16_t
-htc_splitline(struct http *hp, const struct http_conn *htc, const int *hf)
+http1_splitline(struct http *hp, const struct http_conn *htc, const int *hf)
 {
 	char *p;
 
@@ -369,16 +369,17 @@ htc_splitline(struct http *hp, const struct http_conn *htc, const int *hf)
 	*hp->hd[hf[1]].e = '\0';
 	*hp->hd[hf[2]].e = '\0';
 
-	return (htc_dissect_hdrs(hp, p, htc));
+	return (http1_dissect_hdrs(hp, p, htc));
 }
 
 /*--------------------------------------------------------------------*/
 
 static uint16_t
-htc_request_check_host_hdr(const struct http *hp)
+http1_request_check_host_hdr(const struct http *hp)
 {
 	int u;
 	int seen_host = 0;
+
 	for (u = HTTP_HDR_FIRST; u < hp->nhd; u++) {
 		if (hp->hd[u].b == NULL)
 			continue;
@@ -399,7 +400,7 @@ htc_request_check_host_hdr(const struct http *hp)
 /*--------------------------------------------------------------------*/
 
 static void
-htc_proto_ver(struct http *hp)
+http1_proto_ver(struct http *hp)
 {
 	if (!strcasecmp(hp->hd[HTTP_HDR_PROTO].b, "HTTP/1.0"))
 		hp->protover = 10;
@@ -409,6 +410,47 @@ htc_proto_ver(struct http *hp)
 		hp->protover = 9;
 }
 
+/*--------------------------------------------------------------------
+ */
+
+static enum sess_close
+http1_DoConnection(struct http *hp)
+{
+	char *p, *q;
+	enum sess_close retval;
+	unsigned u;
+
+	if (hp->protover < 11)
+		retval = SC_REQ_HTTP10;
+	else
+		retval = SC_NULL;;
+
+	http_CollectHdr(hp, H_Connection);
+	if (!http_GetHdr(hp, H_Connection, &p))
+		return (retval);
+	AN(p);
+	for (; *p; p++) {
+		if (vct_issp(*p))
+			continue;
+		if (*p == ',')
+			continue;
+		for (q = p + 1; *q; q++)
+			if (*q == ',' || vct_issp(*q))
+				break;
+		u = pdiff(p, q);
+		if (u == 5 && !strncasecmp(p, "close", u))
+			retval = SC_REQ_CLOSE;
+		if (u == 10 && !strncasecmp(p, "keep-alive", u))
+			retval = SC_NULL;
+		http_MarkHeader(hp, p, u, HDF_FILTER);
+		if (!*q)
+			break;
+		p = q;
+	}
+	return (retval);
+}
+
+
 /*--------------------------------------------------------------------*/
 
 uint16_t
@@ -425,14 +467,14 @@ HTTP1_DissectRequest(struct req *req)
 	hp = req->http;
 	CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC);
 
-	retval = htc_splitline(hp, htc, HTTP1_Req);
+	retval = http1_splitline(hp, htc, HTTP1_Req);
 	if (retval != 0) {
 		VSLbt(req->vsl, SLT_HttpGarbage, htc->rxbuf);
 		return (retval);
 	}
-	htc_proto_ver(hp);
+	http1_proto_ver(hp);
 
-	retval = htc_request_check_host_hdr(hp);
+	retval = http1_request_check_host_hdr(hp);
 	if (retval != 0) {
 		return (retval);
 	}
@@ -449,6 +491,8 @@ HTTP1_DissectRequest(struct req *req)
 		}
 	}
 
+	hp->doclose = http1_DoConnection(hp);
+
 	return (retval);
 }
 
@@ -464,11 +508,11 @@ HTTP1_DissectResponse(struct http *hp, const struct http_conn *htc)
 	CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC);
 	CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC);
 
-	if (htc_splitline(hp, htc, HTTP1_Resp))
+	if (http1_splitline(hp, htc, HTTP1_Resp))
 		retval = 503;
 
 	if (retval == 0) {
-		htc_proto_ver(hp);
+		http1_proto_ver(hp);
 		if (hp->protover != 10 && hp->protover != 11)
 			retval = 503;
 	}
@@ -501,46 +545,8 @@ HTTP1_DissectResponse(struct http *hp, const struct http_conn *htc)
 	    !Tlen(hp->hd[HTTP_HDR_REASON]))
 		http_SetH(hp, HTTP_HDR_REASON, http_Status2Reason(hp->status));
 
-	return (retval);
-}
-
-/*--------------------------------------------------------------------
- */
-
-enum sess_close
-HTTP1_DoConnection(struct http *hp)
-{
-	char *p, *q;
-	enum sess_close retval;
-	unsigned u;
-
-	if (hp->protover < 11)
-		retval = SC_REQ_HTTP10;
-	else
-		retval = SC_NULL;;
+	hp->doclose = http1_DoConnection(hp);
 
-	http_CollectHdr(hp, H_Connection);
-	if (!http_GetHdr(hp, H_Connection, &p))
-		return (retval);
-	AN(p);
-	for (; *p; p++) {
-		if (vct_issp(*p))
-			continue;
-		if (*p == ',')
-			continue;
-		for (q = p + 1; *q; q++)
-			if (*q == ',' || vct_issp(*q))
-				break;
-		u = pdiff(p, q);
-		if (u == 5 && !strncasecmp(p, "close", u))
-			retval = SC_REQ_CLOSE;
-		if (u == 10 && !strncasecmp(p, "keep-alive", u))
-			retval = SC_NULL;
-		http_MarkHeader(hp, p, u, HDF_FILTER);
-		if (!*q)
-			break;
-		p = q;
-	}
 	return (retval);
 }
 



More information about the varnish-commit mailing list