Commit 3cc4a726 authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Introduce an enum to make the states of HTTP reception more readable.

parent ae3e5a3a
...@@ -871,12 +871,20 @@ void http_Unset(struct http *hp, const char *hdr); ...@@ -871,12 +871,20 @@ void http_Unset(struct http *hp, const char *hdr);
void http_CollectHdr(struct http *hp, const char *hdr); void http_CollectHdr(struct http *hp, const char *hdr);
/* cache_httpconn.c */ /* 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 *, void HTC_Init(struct http_conn *htc, struct ws *ws, int fd, struct vsl_log *,
unsigned maxbytes, unsigned maxhdr); unsigned maxbytes, unsigned maxhdr);
int HTC_Reinit(struct http_conn *htc); 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); 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[]; #define HTTPH(a, b, c) extern char b[];
#include "tbl/http_headers.h" #include "tbl/http_headers.h"
......
...@@ -106,10 +106,11 @@ DOT } ...@@ -106,10 +106,11 @@ DOT }
static int static int
cnt_wait(struct sess *sp, struct worker *wrk, struct req *req) cnt_wait(struct sess *sp, struct worker *wrk, struct req *req)
{ {
int i, j, tmo; int j, tmo;
struct pollfd pfd[1]; struct pollfd pfd[1];
double now, when; double now, when;
enum sess_close why = SC_NULL; enum sess_close why = SC_NULL;
enum htc_status_e hs;
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
...@@ -135,20 +136,20 @@ cnt_wait(struct sess *sp, struct worker *wrk, struct req *req) ...@@ -135,20 +136,20 @@ cnt_wait(struct sess *sp, struct worker *wrk, struct req *req)
assert(j >= 0); assert(j >= 0);
now = VTIM_real(); now = VTIM_real();
if (j != 0) if (j != 0)
i = HTC_Rx(req->htc); hs = HTC_Rx(req->htc);
else else
i = HTC_Complete(req->htc); hs = HTC_Complete(req->htc);
if (i == 1) { if (hs == HTC_COMPLETE) {
/* Got it, run with it */ /* Got it, run with it */
req->t_req = now; req->t_req = now;
return (0); return (0);
} else if (i == -1) { } else if (hs == HTC_ERROR_EOF) {
why = SC_REM_CLOSE; why = SC_REM_CLOSE;
break; break;
} else if (i == -2) { } else if (hs == HTC_OVERFLOW) {
why = SC_RX_OVERFLOW; why = SC_RX_OVERFLOW;
break; break;
} else if (i == -3) { } else if (hs == HTC_ALL_WHITESPACE) {
/* Nothing but whitespace */ /* Nothing but whitespace */
when = sp->t_idle + cache_param->timeout_idle; when = sp->t_idle + cache_param->timeout_idle;
if (when < now) { if (when < now) {
......
...@@ -437,8 +437,9 @@ FetchHdr(struct req *req, int need_host_hdr, int sendbody) ...@@ -437,8 +437,9 @@ FetchHdr(struct req *req, int need_host_hdr, int sendbody)
struct worker *wrk; struct worker *wrk;
struct busyobj *bo; struct busyobj *bo;
struct http *hp; struct http *hp;
enum htc_status_e hs;
int retry = -1; int retry = -1;
int i; int i, first;
struct http_conn *htc; struct http_conn *htc;
wrk = req->wrk; wrk = req->wrk;
...@@ -499,31 +500,31 @@ FetchHdr(struct req *req, int need_host_hdr, int sendbody) ...@@ -499,31 +500,31 @@ FetchHdr(struct req *req, int need_host_hdr, int sendbody)
VTCP_set_read_timeout(vc->fd, vc->first_byte_timeout); VTCP_set_read_timeout(vc->fd, vc->first_byte_timeout);
i = HTC_Rx(htc); first = 1;
do {
if (i < 0) { hs = HTC_Rx(htc);
VSLb(req->vsl, SLT_FetchError, if (hs == HTC_OVERFLOW) {
"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) {
VSLb(req->vsl, SLT_FetchError, VSLb(req->vsl, SLT_FetchError,
"http first read error: %d %d (%s)", "http %sread error: overflow",
i, errno, strerror(errno)); first ? "first " : "");
VDI_CloseFd(&bo->vbc); VDI_CloseFd(&bo->vbc);
/* XXX: other cleanup ? */ /* XXX: other cleanup ? */
return (-1); 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; hp = bo->beresp;
......
...@@ -46,44 +46,6 @@ ...@@ -46,44 +46,6 @@
#include "vct.h" #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) ...@@ -139,15 +101,45 @@ HTC_Reinit(struct http_conn *htc)
* Return 1 if we have a complete HTTP procol header * 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) HTC_Complete(struct http_conn *htc)
{ {
int i; int i;
const char *p;
txt *t;
CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC); CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC);
i = htc_header_complete(&htc->rxbuf);
if (i <= 0) t = &htc->rxbuf;
return (i); 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); WS_ReleaseP(htc->ws, htc->rxbuf.e);
AZ(htc->pipeline.b); AZ(htc->pipeline.b);
AZ(htc->pipeline.e); AZ(htc->pipeline.e);
...@@ -156,20 +148,14 @@ HTC_Complete(struct http_conn *htc) ...@@ -156,20 +148,14 @@ HTC_Complete(struct http_conn *htc)
htc->pipeline.e = htc->rxbuf.e; htc->pipeline.e = htc->rxbuf.e;
htc->rxbuf.e = htc->pipeline.b; htc->rxbuf.e = htc->pipeline.b;
} }
return (1); return (HTC_COMPLETE);
} }
/*-------------------------------------------------------------------- /*--------------------------------------------------------------------
* Receive more HTTP protocol bytes * 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) HTC_Rx(struct http_conn *htc)
{ {
int i; int i;
...@@ -179,7 +165,7 @@ HTC_Rx(struct http_conn *htc) ...@@ -179,7 +165,7 @@ HTC_Rx(struct http_conn *htc)
i = (htc->ws->r - htc->rxbuf.e) - 1; /* space for NUL */ i = (htc->ws->r - htc->rxbuf.e) - 1; /* space for NUL */
if (i <= 0) { if (i <= 0) {
WS_ReleaseP(htc->ws, htc->rxbuf.b); WS_ReleaseP(htc->ws, htc->rxbuf.b);
return (-2); return (HTC_OVERFLOW);
} }
i = read(htc->fd, htc->rxbuf.e, i); i = read(htc->fd, htc->rxbuf.e, i);
if (i <= 0) { if (i <= 0) {
...@@ -188,7 +174,7 @@ HTC_Rx(struct http_conn *htc) ...@@ -188,7 +174,7 @@ HTC_Rx(struct http_conn *htc)
* so consequently an EOF can not be OK * so consequently an EOF can not be OK
*/ */
WS_ReleaseP(htc->ws, htc->rxbuf.b); WS_ReleaseP(htc->ws, htc->rxbuf.b);
return (-1); return (HTC_ERROR_EOF);
} }
htc->rxbuf.e += i; htc->rxbuf.e += i;
*htc->rxbuf.e = '\0'; *htc->rxbuf.e = '\0';
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment