[master] 3cc4a72 Introduce an enum to make the states of HTTP reception more readable.
Poul-Henning Kamp
phk at varnish-cache.org
Wed Jul 18 22:09:51 CEST 2012
commit 3cc4a726bf5d4ff8044883daacffc9bd46f607ec
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date: Wed Jul 18 20:09:21 2012 +0000
Introduce an enum to make the states of HTTP reception more readable.
diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h
index 7328779..63a7c3d 100644
--- a/bin/varnishd/cache/cache.h
+++ b/bin/varnishd/cache/cache.h
@@ -871,12 +871,20 @@ void http_Unset(struct http *hp, const char *hdr);
void http_CollectHdr(struct http *hp, const char *hdr);
/* cache_httpconn.c */
+enum htc_status_e {
+ HTC_ALL_WHITESPACE = -3,
+ HTC_OVERFLOW = -2,
+ HTC_ERROR_EOF = -1,
+ HTC_NEED_MORE = 0,
+ HTC_COMPLETE = 1
+};
+
void HTC_Init(struct http_conn *htc, struct ws *ws, int fd, struct vsl_log *,
unsigned maxbytes, unsigned maxhdr);
int HTC_Reinit(struct http_conn *htc);
-int HTC_Rx(struct http_conn *htc);
+enum htc_status_e HTC_Rx(struct http_conn *htc);
ssize_t HTC_Read(struct http_conn *htc, void *d, size_t len);
-int HTC_Complete(struct http_conn *htc);
+enum htc_status_e HTC_Complete(struct http_conn *htc);
#define HTTPH(a, b, c) extern char b[];
#include "tbl/http_headers.h"
diff --git a/bin/varnishd/cache/cache_center.c b/bin/varnishd/cache/cache_center.c
index e71ad87..d98d490 100644
--- a/bin/varnishd/cache/cache_center.c
+++ b/bin/varnishd/cache/cache_center.c
@@ -106,10 +106,11 @@ DOT }
static int
cnt_wait(struct sess *sp, struct worker *wrk, struct req *req)
{
- int i, j, tmo;
+ int j, tmo;
struct pollfd pfd[1];
double now, when;
enum sess_close why = SC_NULL;
+ enum htc_status_e hs;
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
@@ -135,20 +136,20 @@ cnt_wait(struct sess *sp, struct worker *wrk, struct req *req)
assert(j >= 0);
now = VTIM_real();
if (j != 0)
- i = HTC_Rx(req->htc);
+ hs = HTC_Rx(req->htc);
else
- i = HTC_Complete(req->htc);
- if (i == 1) {
+ hs = HTC_Complete(req->htc);
+ if (hs == HTC_COMPLETE) {
/* Got it, run with it */
req->t_req = now;
return (0);
- } else if (i == -1) {
+ } else if (hs == HTC_ERROR_EOF) {
why = SC_REM_CLOSE;
break;
- } else if (i == -2) {
+ } else if (hs == HTC_OVERFLOW) {
why = SC_RX_OVERFLOW;
break;
- } else if (i == -3) {
+ } else if (hs == HTC_ALL_WHITESPACE) {
/* Nothing but whitespace */
when = sp->t_idle + cache_param->timeout_idle;
if (when < now) {
diff --git a/bin/varnishd/cache/cache_fetch.c b/bin/varnishd/cache/cache_fetch.c
index ab2aabc..3b9b08d 100644
--- a/bin/varnishd/cache/cache_fetch.c
+++ b/bin/varnishd/cache/cache_fetch.c
@@ -437,8 +437,9 @@ FetchHdr(struct req *req, int need_host_hdr, int sendbody)
struct worker *wrk;
struct busyobj *bo;
struct http *hp;
+ enum htc_status_e hs;
int retry = -1;
- int i;
+ int i, first;
struct http_conn *htc;
wrk = req->wrk;
@@ -499,31 +500,31 @@ FetchHdr(struct req *req, int need_host_hdr, int sendbody)
VTCP_set_read_timeout(vc->fd, vc->first_byte_timeout);
- i = HTC_Rx(htc);
-
- if (i < 0) {
- VSLb(req->vsl, SLT_FetchError,
- "http first read error: %d %d (%s)",
- i, errno, strerror(errno));
- VDI_CloseFd(&bo->vbc);
- /* XXX: other cleanup ? */
- /* Retryable if we never received anything */
- return (i == -1 ? retry : -1);
- }
-
- VTCP_set_read_timeout(vc->fd, vc->between_bytes_timeout);
-
- while (i == 0) {
- i = HTC_Rx(htc);
- if (i < 0) {
+ first = 1;
+ do {
+ hs = HTC_Rx(htc);
+ if (hs == HTC_OVERFLOW) {
VSLb(req->vsl, SLT_FetchError,
- "http first read error: %d %d (%s)",
- i, errno, strerror(errno));
+ "http %sread error: overflow",
+ first ? "first " : "");
VDI_CloseFd(&bo->vbc);
/* XXX: other cleanup ? */
return (-1);
}
- }
+ if (hs == HTC_ERROR_EOF) {
+ VSLb(req->vsl, SLT_FetchError,
+ "http %sread error: EOF",
+ first ? "first " : "");
+ VDI_CloseFd(&bo->vbc);
+ /* XXX: other cleanup ? */
+ return (retry);
+ }
+ if (first) {
+ first = 0;
+ VTCP_set_read_timeout(vc->fd,
+ vc->between_bytes_timeout);
+ }
+ } while (hs != HTC_COMPLETE);
hp = bo->beresp;
diff --git a/bin/varnishd/cache/cache_httpconn.c b/bin/varnishd/cache/cache_httpconn.c
index 890dfd3..211e8a9 100644
--- a/bin/varnishd/cache/cache_httpconn.c
+++ b/bin/varnishd/cache/cache_httpconn.c
@@ -46,44 +46,6 @@
#include "vct.h"
-/*--------------------------------------------------------------------
- * Check if we have a complete HTTP request or response yet
- *
- * Return values:
- * -3 All whitespace so far
- * 0 No, keep trying
- * >0 Yes, it is this many bytes long.
- */
-
-static int
-htc_header_complete(txt *t)
-{
- const char *p;
-
- Tcheck(*t);
- assert(*t->e == '\0');
- /* Skip any leading white space */
- for (p = t->b ; vct_islws(*p); p++)
- continue;
- if (p == t->e) {
- /* All white space */
- t->e = t->b;
- *t->e = '\0';
- return (-3);
- }
- while (1) {
- p = strchr(p, '\n');
- if (p == NULL)
- return (0);
- p++;
- if (*p == '\r')
- p++;
- if (*p == '\n')
- break;
- }
- p++;
- return (p - t->b);
-}
/*--------------------------------------------------------------------*/
@@ -139,15 +101,45 @@ HTC_Reinit(struct http_conn *htc)
* Return 1 if we have a complete HTTP procol header
*/
-int
+/*--------------------------------------------------------------------
+ * Check if we have a complete HTTP request or response yet
+ *
+ */
+
+enum htc_status_e
HTC_Complete(struct http_conn *htc)
{
int i;
+ const char *p;
+ txt *t;
CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC);
- i = htc_header_complete(&htc->rxbuf);
- if (i <= 0)
- return (i);
+
+ t = &htc->rxbuf;
+ Tcheck(*t);
+ assert(*t->e == '\0');
+
+ /* Skip any leading white space */
+ for (p = t->b ; vct_islws(*p); p++)
+ continue;
+ if (p == t->e) {
+ /* All white space */
+ t->e = t->b;
+ *t->e = '\0';
+ return (HTC_ALL_WHITESPACE);
+ }
+ while (1) {
+ p = strchr(p, '\n');
+ if (p == NULL)
+ return (HTC_NEED_MORE);
+ p++;
+ if (*p == '\r')
+ p++;
+ if (*p == '\n')
+ break;
+ }
+ p++;
+ i = p - t->b;
WS_ReleaseP(htc->ws, htc->rxbuf.e);
AZ(htc->pipeline.b);
AZ(htc->pipeline.e);
@@ -156,20 +148,14 @@ HTC_Complete(struct http_conn *htc)
htc->pipeline.e = htc->rxbuf.e;
htc->rxbuf.e = htc->pipeline.b;
}
- return (1);
+ return (HTC_COMPLETE);
}
/*--------------------------------------------------------------------
* Receive more HTTP protocol bytes
- * Returns:
- * -3 all whitespace so far
- * -2 overflow
- * -1 error/EOF
- * 0 more needed
- * 1 got complete HTTP header
*/
-int
+enum htc_status_e
HTC_Rx(struct http_conn *htc)
{
int i;
@@ -179,7 +165,7 @@ HTC_Rx(struct http_conn *htc)
i = (htc->ws->r - htc->rxbuf.e) - 1; /* space for NUL */
if (i <= 0) {
WS_ReleaseP(htc->ws, htc->rxbuf.b);
- return (-2);
+ return (HTC_OVERFLOW);
}
i = read(htc->fd, htc->rxbuf.e, i);
if (i <= 0) {
@@ -188,7 +174,7 @@ HTC_Rx(struct http_conn *htc)
* so consequently an EOF can not be OK
*/
WS_ReleaseP(htc->ws, htc->rxbuf.b);
- return (-1);
+ return (HTC_ERROR_EOF);
}
htc->rxbuf.e += i;
*htc->rxbuf.e = '\0';
More information about the varnish-commit
mailing list