[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