[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