From: phk Date: Fri, 28 Sep 2007 20:13:48 +0000 (+0000) Subject: Complete the split of HTTP-editing and HTTP-transmission functions. X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9cd0bfedec43cd5a3062012e65e2b6224c8cc1a7;p=varnish Complete the split of HTTP-editing and HTTP-transmission functions. git-svn-id: svn+ssh://projects.linpro.no/svn/varnish/trunk@2055 d4fa192b-c00b-0410-8231-f00ffab90ce4 --- diff --git a/varnish-cache/bin/varnishd/cache.h b/varnish-cache/bin/varnishd/cache.h index a6eb0d35..25d53fb1 100644 --- a/varnish-cache/bin/varnishd/cache.h +++ b/varnish-cache/bin/varnishd/cache.h @@ -110,8 +110,6 @@ struct http { #define HTTP_MAGIC 0x6428b5c9 struct ws *ws; - txt rx; /* Received Request */ - txt pl; /* Pipelined bytes */ unsigned char conds; /* If-* headers present */ enum httpwhence logtag; @@ -126,7 +124,7 @@ struct http_conn { unsigned magic; #define HTTP_CONN_MAGIC 0x3e19edd1 - struct http *http; + int fd; struct ws *ws; txt rxbuf; txt pipeline; @@ -289,6 +287,8 @@ struct sess { struct http *http; struct ws ws[1]; + struct http_conn htc[1]; + /* Timestamps, all on TIM_real() timescale */ double t_open; double t_req; @@ -470,18 +470,17 @@ int http_GetStatus(const struct http *hp); const char *http_GetReq(const struct http *hp); const char *http_GetProto(const struct http *hp); int http_HdrIs(const struct http *hp, const char *hdr, const char *val); -int http_GetTail(struct http *hp, unsigned len, char **b, char **e); -int http_Read(struct http *hp, int fd, void *b, unsigned len); -void http_RecvPrep(struct http *hp); -int http_RecvPrepAgain(struct http *hp); -int http_RecvSome(int fd, struct http *hp); -int http_RecvHead(struct http *hp, int fd); -int http_DissectRequest(struct worker *w, struct http *sp, int fd); -int http_DissectResponse(struct worker *w, struct http *sp, int fd); +int http_DissectRequest(struct sess *sp); +int http_DissectResponse(struct worker *w, struct http_conn *htc, struct http *sp); const char *http_DoConnection(struct http *hp); void http_CopyHome(struct worker *w, int fd, struct http *hp); void http_Unset(struct http *hp, const char *hdr); +/* cache_httpconn.c */ +void HTC_Init(struct http_conn *htc, struct ws *ws, int fd); +int HTC_Reinit(struct http_conn *htc); +int HTC_Rx(struct http_conn *htc); +int HTC_Read(struct http_conn *htc, void *d, unsigned len); #define HTTPH(a, b, c, d, e, f, g) extern char b[]; #include "http_headers.h" diff --git a/varnish-cache/bin/varnishd/cache_acceptor.c b/varnish-cache/bin/varnishd/cache_acceptor.c index b769d0d3..1ce0d6d4 100644 --- a/varnish-cache/bin/varnishd/cache_acceptor.c +++ b/varnish-cache/bin/varnishd/cache_acceptor.c @@ -194,7 +194,7 @@ vca_acct(void *arg) sp->id = i; sp->t_open = TIM_real(); - http_RecvPrep(sp->http); + HTC_Init(sp->htc, sp->ws, sp->fd); sp->step = STP_FIRST; WRK_QueueSession(sp); } @@ -224,13 +224,13 @@ vca_pollsession(struct sess *sp) { int i; - i = http_RecvSome(sp->fd, sp->http); - if (i < 1) - return (i); + i = HTC_Rx(sp->htc); + /* XXX: fix retval */ + if (i == 0) + return (-1); if (i == 1) - vca_close_session(sp, "overflow"); - else if (i == 2) - vca_close_session(sp, "no request"); + return (0); + vca_close_session(sp, "err/poll"); return (1); } diff --git a/varnish-cache/bin/varnishd/cache_center.c b/varnish-cache/bin/varnishd/cache_center.c index 3ee46bae..1d5bb93e 100644 --- a/varnish-cache/bin/varnishd/cache_center.c +++ b/varnish-cache/bin/varnishd/cache_center.c @@ -88,20 +88,15 @@ cnt_again(struct sess *sp) assert(sp->xid == 0); - do - i = http_RecvSome(sp->fd, sp->http); - while (i == -1); - if (i == 0) { + do + i = HTC_Rx(sp->htc); + while (i == 0); + if (i == 1) { sp->step = STP_RECV; - return (0); - } - if (i == 1) + } else { vca_close_session(sp, "overflow"); - else if (i == 2) - vca_close_session(sp, "no request"); - else - INCOMPL(); - sp->step = STP_DONE; + sp->step = STP_DONE; + } return (0); } @@ -185,6 +180,7 @@ static int cnt_done(struct sess *sp) { double dh, dp, da; + int i; AZ(sp->obj); AZ(sp->bereq); @@ -224,12 +220,13 @@ cnt_done(struct sess *sp) return (1); } - if (http_RecvPrepAgain(sp->http)) { + i = HTC_Reinit(sp->htc); + if (i == 1) { VSL_stats->sess_pipeline++; sp->step = STP_RECV; return (0); } - if (sp->http->pl.b < sp->http->pl.e) { + if (Tlen(sp->htc->rxbuf)) { VSL_stats->sess_readahead++; sp->step = STP_AGAIN; return (0); @@ -388,13 +385,13 @@ cnt_first(struct sess *sp) sp->wrk->acct.sess++; SES_RefSrcAddr(sp); do - i = http_RecvSome(sp->fd, sp->http); - while (i == -1); - if (i == 0) { + i = HTC_Rx(sp->htc); + while (i == 0); + if (i == 1) { sp->step = STP_RECV; return (0); } - if (i == 1) + if (i == -1) vca_close_session(sp, "blast"); else if (i == 2) vca_close_session(sp, "silent"); @@ -756,7 +753,7 @@ cnt_recv(struct sess *sp) sp->vcl = sp->wrk->vcl; sp->wrk->vcl = NULL; - done = http_DissectRequest(sp->wrk, sp->http, sp->fd); + done = http_DissectRequest(sp); if (done != 0) { RES_Error(sp, done, NULL); /* XXX: STP_ERROR ? */ sp->step = STP_DONE; diff --git a/varnish-cache/bin/varnishd/cache_fetch.c b/varnish-cache/bin/varnishd/cache_fetch.c index 46e26fd0..89c85f00 100644 --- a/varnish-cache/bin/varnishd/cache_fetch.c +++ b/varnish-cache/bin/varnishd/cache_fetch.c @@ -49,7 +49,7 @@ /*--------------------------------------------------------------------*/ static int -fetch_straight(struct sess *sp, int fd, struct http *hp, const char *b) +fetch_straight(struct sess *sp, struct http_conn *htc, const char *b) { int i; unsigned char *p; @@ -70,12 +70,12 @@ fetch_straight(struct sess *sp, int fd, struct http *hp, const char *b) sp->obj->len = cl; p = st->ptr; - i = fcntl(fd, F_GETFL); /* XXX ? */ + i = fcntl(htc->fd, F_GETFL); /* XXX ? */ i &= ~O_NONBLOCK; - i = fcntl(fd, F_SETFL, i); + i = fcntl(htc->fd, F_SETFL, i); while (cl > 0) { - i = http_Read(hp, fd, p, cl); + i = HTC_Read(htc, p, cl); if (i <= 0) return (-1); p += i; @@ -88,7 +88,7 @@ fetch_straight(struct sess *sp, int fd, struct http *hp, const char *b) /* XXX: Cleanup. It must be possible somehow :-( */ static int -fetch_chunked(struct sess *sp, int fd, struct http *hp) +fetch_chunked(struct sess *sp, struct http_conn *htc) { int i; char *q; @@ -132,7 +132,7 @@ fetch_chunked(struct sess *sp, int fd, struct http *hp) * deal more complex than reading a single character * at a time. */ - i = http_Read(hp, fd, bp, 1); + i = HTC_Read(htc, bp, 1); if (i <= 0) return (-1); bp += i; @@ -179,7 +179,7 @@ fetch_chunked(struct sess *sp, int fd, struct http *hp) /* Pick up the rest of this chunk */ while (v > 0) { - i = http_Read(hp, fd, st->ptr + st->len, v); + i = HTC_Read(htc, st->ptr + st->len, v); if (i <= 0) return (-1); st->len += i; @@ -211,16 +211,16 @@ fetch_chunked(struct sess *sp, int fd, struct http *hp) #include static int -fetch_eof(struct sess *sp, int fd, struct http *hp) +fetch_eof(struct sess *sp, struct http_conn *htc) { int i; unsigned char *p; struct storage *st; unsigned v; - i = fcntl(fd, F_GETFL); /* XXX ? */ + i = fcntl(htc->fd, F_GETFL); /* XXX ? */ i &= ~O_NONBLOCK; - i = fcntl(fd, F_SETFL, i); + i = fcntl(htc->fd, F_SETFL, i); p = NULL; v = 0; @@ -234,7 +234,7 @@ fetch_eof(struct sess *sp, int fd, struct http *hp) } AN(p); AN(st); - i = http_Read(hp, fd, p, v); + i = HTC_Read(htc, p, v); if (i < 0) return (-1); if (i == 0) @@ -268,6 +268,8 @@ Fetch(struct sess *sp) struct bereq *bereq; int mklen, is_head; unsigned len; + struct http_conn htc[1]; + int i; CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); CHECK_OBJ_NOTNULL(sp->wrk, WORKER_MAGIC); @@ -300,12 +302,12 @@ Fetch(struct sess *sp) CHECK_OBJ_NOTNULL(sp->wrk, WORKER_MAGIC); CHECK_OBJ_NOTNULL(sp->obj, OBJECT_MAGIC); - CHECK_OBJ_NOTNULL(sp->backend, BACKEND_MAGIC); - if (http_RecvHead(hp, vc->fd)) { - /* XXX: cleanup */ - return (1); - } - if (http_DissectResponse(sp->wrk, hp, vc->fd)) { + HTC_Init(htc, bereq->ws, vc->fd); + do + i = HTC_Rx(htc); + while (i == 0); + + if (http_DissectResponse(sp->wrk, htc, hp)) { /* XXX: cleanup */ return (1); } @@ -326,8 +328,8 @@ Fetch(struct sess *sp) CHECK_OBJ_NOTNULL(sp->backend, BACKEND_MAGIC); /* Filter into object */ hp2 = &sp->obj->http; - len = Tlen(hp->rx); - len += 256; /* margin for content-length etc */ + len = Tlen(htc->rxbuf); + len += 256; /* XXX: margin for content-length etc */ CHECK_OBJ_NOTNULL(sp->backend, BACKEND_MAGIC); b = malloc(len); @@ -349,10 +351,10 @@ Fetch(struct sess *sp) if (is_head) { /* nothing */ } else if (http_GetHdr(hp, H_Content_Length, &b)) { - cls = fetch_straight(sp, vc->fd, hp, b); + cls = fetch_straight(sp, htc, b); mklen = 1; } else if (http_HdrIs(hp, H_Transfer_Encoding, "chunked")) { - cls = fetch_chunked(sp, vc->fd, hp); + cls = fetch_chunked(sp, htc); mklen = 1; } else if (http_GetHdr(hp, H_Transfer_Encoding, &b)) { /* XXX: AUGH! */ @@ -362,7 +364,7 @@ Fetch(struct sess *sp) } else if (strcmp(http_GetProto(hp), "HTTP/1.1")) { switch (http_GetStatus(hp)) { case 200: - cls = fetch_eof(sp, vc->fd, hp); + cls = fetch_eof(sp, htc); mklen = 1; break; default: diff --git a/varnish-cache/bin/varnishd/cache_http.c b/varnish-cache/bin/varnishd/cache_http.c index f570b91a..84870d1c 100644 --- a/varnish-cache/bin/varnishd/cache_http.c +++ b/varnish-cache/bin/varnishd/cache_http.c @@ -347,7 +347,7 @@ http_GetReq(const struct http *hp) */ static int -http_dissect_hdrs(struct worker *w, struct http *hp, int fd, char *p) +http_dissect_hdrs(struct worker *w, struct http *hp, int fd, char *p, txt t) { char *q, *r; @@ -357,8 +357,8 @@ http_dissect_hdrs(struct worker *w, struct http *hp, int fd, char *p) hp->nhd = HTTP_HDR_FIRST; hp->conds = 0; r = NULL; /* For FlexeLint */ - assert(p < hp->rx.e); /* http_header_complete() guarantees this */ - for (; p < hp->rx.e; p = r) { + assert(p < t.e); /* http_header_complete() guarantees this */ + for (; p < t.e; p = r) { /* XXX: handle continuation lines */ q = strchr(p, '\n'); assert(q != NULL); @@ -391,16 +391,23 @@ http_dissect_hdrs(struct worker *w, struct http *hp, int fd, char *p) /*--------------------------------------------------------------------*/ int -http_DissectRequest(struct worker *w, struct http *hp, int fd) +http_DissectRequest(struct sess *sp) { char *p; + struct http_conn *htc; + struct http *hp; + CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); + htc = sp->htc; + CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC); + hp = sp->http; CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC); + /* Assert a NUL at rx.e */ - Tcheck(hp->rx); + Tcheck(htc->rxbuf); hp->logtag = HTTP_Rx; - for (p = hp->rx.b ; isspace(*p); p++) + for (p = htc->rxbuf.b ; isspace(*p); p++) continue; /* First, the request type (GET/HEAD etc) */ @@ -408,23 +415,23 @@ http_DissectRequest(struct worker *w, struct http *hp, int fd) for (; isalpha(*p); p++) ; hp->hd[HTTP_HDR_REQ].e = p; - WSLH(w, HTTP_T_Request, fd, hp, HTTP_HDR_REQ); + WSLH(sp->wrk, HTTP_T_Request, sp->fd, hp, HTTP_HDR_REQ); *p++ = '\0'; /* Next find the URI */ while (isspace(*p) && *p != '\n') p++; if (*p == '\n') { - WSLR(w, SLT_HttpGarbage, fd, hp->rx); + WSLR(sp->wrk, SLT_HttpGarbage, sp->fd, htc->rxbuf); return (400); } hp->hd[HTTP_HDR_URL].b = p; while (!isspace(*p)) p++; hp->hd[HTTP_HDR_URL].e = p; - WSLH(w, HTTP_T_URL, fd, hp, HTTP_HDR_URL); + WSLH(sp->wrk, HTTP_T_URL, sp->fd, hp, HTTP_HDR_URL); if (*p == '\n') { - WSLR(w, SLT_HttpGarbage, fd, hp->rx); + WSLR(sp->wrk, SLT_HttpGarbage, sp->fd, htc->rxbuf); return (400); } *p++ = '\0'; @@ -433,44 +440,45 @@ http_DissectRequest(struct worker *w, struct http *hp, int fd) while (isspace(*p) && *p != '\n') p++; if (*p == '\n') { - WSLR(w, SLT_HttpGarbage, fd, hp->rx); + WSLR(sp->wrk, SLT_HttpGarbage, sp->fd, htc->rxbuf); return (400); } hp->hd[HTTP_HDR_PROTO].b = p; while (!isspace(*p)) p++; hp->hd[HTTP_HDR_PROTO].e = p; - WSLH(w, HTTP_T_Protocol, fd, hp, HTTP_HDR_PROTO); + WSLH(sp->wrk, HTTP_T_Protocol, sp->fd, hp, HTTP_HDR_PROTO); if (*p != '\n') *p++ = '\0'; while (isspace(*p) && *p != '\n') p++; if (*p != '\n') { - WSLR(w, SLT_HttpGarbage, fd, hp->rx); + WSLR(sp->wrk, SLT_HttpGarbage, sp->fd, htc->rxbuf); return (400); } *p++ = '\0'; - return (http_dissect_hdrs(w, hp, fd, p)); + return (http_dissect_hdrs(sp->wrk, hp, sp->fd, p, htc->rxbuf)); } /*--------------------------------------------------------------------*/ int -http_DissectResponse(struct worker *w, struct http *hp, int fd) +http_DissectResponse(struct worker *w, struct http_conn *htc, struct http *hp) { char *p, *q; + CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC); CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC); - /* Assert a NUL at rx.e */ - Tcheck(hp->rx); + /* Assert a NUL at rx.e (?) */ + Tcheck(htc->rxbuf); hp->logtag = HTTP_Rx; - for (p = hp->rx.b ; isspace(*p); p++) + for (p = htc->rxbuf.b ; isspace(*p); p++) continue; if (memcmp(p, "HTTP/1.", 7)) { - WSLR(w, SLT_HttpGarbage, fd, hp->rx); + WSLR(w, SLT_HttpGarbage, htc->fd, htc->rxbuf); return (400); } /* First, protocol */ @@ -478,7 +486,7 @@ http_DissectResponse(struct worker *w, struct http *hp, int fd) while (!isspace(*p)) p++; hp->hd[HTTP_HDR_PROTO].e = p; - WSLH(w, HTTP_T_Protocol, fd, hp, HTTP_HDR_PROTO); + WSLH(w, HTTP_T_Protocol, htc->fd, hp, HTTP_HDR_PROTO); *p++ = '\0'; /* Next find the status */ @@ -488,7 +496,7 @@ http_DissectResponse(struct worker *w, struct http *hp, int fd) while (!isspace(*p)) p++; hp->hd[HTTP_HDR_STATUS].e = p; - WSLH(w, HTTP_T_Status, fd, hp, HTTP_HDR_STATUS); + WSLH(w, HTTP_T_Status, htc->fd, hp, HTTP_HDR_STATUS); *p++ = '\0'; /* Next find the response */ @@ -502,11 +510,12 @@ http_DissectResponse(struct worker *w, struct http *hp, int fd) continue; *q = '\0'; hp->hd[HTTP_HDR_RESPONSE].e = q; - WSLH(w, HTTP_T_Response, fd, hp, HTTP_HDR_RESPONSE); + WSLH(w, HTTP_T_Response, htc->fd, hp, HTTP_HDR_RESPONSE); p++; - return (http_dissect_hdrs(w, hp, fd, p)); + return (http_dissect_hdrs(w, hp, htc->fd, p, htc->rxbuf)); } + /*--------------------------------------------------------------------*/ void diff --git a/varnish-cache/bin/varnishd/cache_httpconn.c b/varnish-cache/bin/varnishd/cache_httpconn.c index cd397524..991fd20f 100644 --- a/varnish-cache/bin/varnishd/cache_httpconn.c +++ b/varnish-cache/bin/varnishd/cache_httpconn.c @@ -31,6 +31,8 @@ * HTTP protocol requests */ +#include +#include #include #include #include @@ -39,8 +41,7 @@ #include "cache.h" /*-------------------------------------------------------------------- - * Check if we have a complete HTTP request or response yet between the - * two pointers given. + * Check if we have a complete HTTP request or response yet * * Return values: * -1 No, and you can nuke the (white-space) content. @@ -49,19 +50,19 @@ */ static int -http_header_complete(const char *b, const char *e) +htc_header_complete(txt *t) { const char *p; - AN(b); - AN(e); - assert(b <= e); - assert(*e == '\0'); + Tcheck(*t); + assert(*t->e == '\0'); /* Skip any leading white space */ - for (p = b ; isspace(*p); p++) + for (p = t->b ; isspace(*p); p++) continue; - if (*p == '\0') - return (-1); + if (*p == '\0') { + t->e = t->b; + return (0); + } while (1) { p = strchr(p, '\n'); if (p == NULL) @@ -73,169 +74,109 @@ http_header_complete(const char *b, const char *e) break; } p++; - return (p - b); + return (p - t->b); } /*--------------------------------------------------------------------*/ void -http_RecvPrep(struct http *hp) +HTC_Init(struct http_conn *htc, struct ws *ws, int fd) { - unsigned l; - CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC); - WS_Assert(hp->ws); - WS_Reset(hp->ws); - WS_Reserve(hp->ws, 0); - hp->rx.b = hp->ws->f; - hp->rx.e = hp->rx.b; - if (hp->pl.b != NULL) { - l = Tlen(hp->pl); - memmove(hp->rx.b, hp->pl.b, l); - hp->rx.e = hp->rx.b + l; - hp->pl.b = hp->pl.e = NULL; - } - *hp->rx.e = '\0'; + htc->magic = HTTP_CONN_MAGIC; + htc->ws = ws; + htc->fd = fd; + WS_Reset(htc->ws); + WS_Reserve(htc->ws, (htc->ws->e - htc->ws->s) / 2); + htc->rxbuf.b = ws->f; + htc->rxbuf.e = ws->f; + 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. + */ + int -http_RecvPrepAgain(struct http *hp) +HTC_Reinit(struct http_conn *htc) { + unsigned l; int i; - http_RecvPrep(hp); - if (hp->rx.b == hp->rx.e) - return (0); - i = http_header_complete(hp->rx.b, hp->rx.e); - if (i == -1) - hp->rx.e = hp->rx.b; - if (i <= 0) - return (0); - WS_ReleaseP(hp->ws, hp->rx.e); - if (hp->rx.e != hp->rx.b + i) { - hp->pl.b = hp->rx.b + i; - hp->pl.e = hp->rx.e; - hp->rx.e = hp->pl.b; + CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC); + WS_Reset(htc->ws); + WS_Reserve(htc->ws, (htc->ws->e - htc->ws->s) / 2); + htc->rxbuf.b = htc->ws->f; + htc->rxbuf.e = htc->ws->f; + if (htc->pipeline.b != NULL) { + l = Tlen(htc->pipeline); + memmove(htc->rxbuf.b, htc->pipeline.b, l); + htc->rxbuf.e += l; + htc->pipeline.b = NULL; + htc->pipeline.e = NULL; } + *htc->rxbuf.e = '\0'; + i = htc_header_complete(&htc->rxbuf); return (i); } /*--------------------------------------------------------------------*/ int -http_RecvSome(int fd, struct http *hp) +HTC_Rx(struct http_conn *htc) { - unsigned l; int i; - l = pdiff(hp->rx.e, hp->ws->e) - 1; - l /= 2; /* Don't fill all of workspace with read-ahead */ - if (l <= 1) { - VSL(SLT_HttpError, fd, "Received too much"); - VSLR(SLT_HttpGarbage, fd, hp->rx); - hp->rx.b = hp->rx.e = NULL; - WS_Release(hp->ws, 0); - return (1); + CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC); + i = (htc->ws->r - htc->rxbuf.e) - 1; /* space for NUL */ + assert(i > 0); + i = read(htc->fd, htc->rxbuf.e, i); + if (i < 0) { + WS_ReleaseP(htc->ws, htc->rxbuf.b); + return (-1); } - errno = 0; - i = read(fd, hp->rx.e, l - 1); - if (i > 0) { - hp->rx.e += i; - *hp->rx.e = '\0'; - i = http_header_complete(hp->rx.b, hp->rx.e); - if (i == -1) - hp->rx.e = hp->rx.b; - if (i == 0) - return (-1); - WS_ReleaseP(hp->ws, hp->rx.e); - if (hp->rx.e != hp->rx.b + i) { - hp->pl.b = hp->rx.b + i; - hp->pl.e = hp->rx.e; - hp->rx.e = hp->pl.b; - } + htc->rxbuf.e += i; + *htc->rxbuf.e = '\0'; + i = htc_header_complete(&htc->rxbuf); + if (i == 0) return (0); + WS_ReleaseP(htc->ws, htc->rxbuf.e); + if (htc->rxbuf.b + i < htc->rxbuf.e) { + htc->pipeline.b = htc->rxbuf.b + i; + htc->pipeline.e = htc->rxbuf.e; + htc->rxbuf.e = htc->pipeline.b; } - - if (hp->rx.e != hp->rx.b) { - VSL(SLT_HttpError, fd, - "Received (only) %d bytes, errno %d", - hp->rx.e - hp->rx.b, errno); - VSLR(SLT_Debug, fd, hp->rx); - } else if (errno == 0) - VSL(SLT_HttpError, fd, "Received nothing"); - else - VSL(SLT_HttpError, fd, "Received errno %d", errno); - hp->rx.b = hp->rx.e = NULL; - WS_Release(hp->ws, 0); - return(2); -} - -/*--------------------------------------------------------------------*/ - -int -http_RecvHead(struct http *hp, int fd) -{ - int i; - - CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC); - http_RecvPrep(hp); - do - i = http_RecvSome(fd, hp); - while (i == -1); - return (i); -} - -/*--------------------------------------------------------------------*/ - -int -http_GetTail(struct http *hp, unsigned len, char **b, char **e) -{ - - if (hp->pl.b >= hp->pl.e) - return (0); - - if (len == 0) - len = Tlen(hp->pl); - - if (hp->pl.b + len > hp->pl.e) - len = Tlen(hp->pl); - if (len == 0) - return (0); - *b = hp->pl.b; - *e = hp->pl.b + len; - hp->pl.b += len; - Tcheck(hp->pl); return (1); } -/*--------------------------------------------------------------------*/ -/* Read from fd, but soak up any tail first */ - int -http_Read(struct http *hp, int fd, void *p, unsigned len) +HTC_Read(struct http_conn *htc, void *d, unsigned len) { + unsigned l; + unsigned char *p; int i; - unsigned u; - char *b = p; - - u = 0; - if (hp->pl.b < hp->pl.e) { - u = Tlen(hp->pl); - if (u > len) - u = len; - memcpy(b, hp->pl.b, u); - hp->pl.b += u; - b += u; - len -= u; - } - if (hp->pl.e == hp->pl.b) - hp->pl.b = hp->pl.e = NULL; - if (len > 0) { - i = read(fd, b, len); - if (i < 0) /* XXX i == 0 ?? */ - return (i); - u += i; + + l = 0; + p = d; + CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC); + if (htc->pipeline.b) { + l = Tlen(htc->pipeline); + if (l > len) + l = len; + memcpy(p, htc->pipeline.b, l); + p += l; + len -= l; + htc->pipeline.b += l; + if (htc->pipeline.b == htc->pipeline.e) + htc->pipeline.b = htc->pipeline.e = NULL; } - return (u); + if (len == 0) + return (l); + i = read(htc->fd, p, len); + if (i < 0) + return (i); + return (i + l); } - diff --git a/varnish-cache/bin/varnishd/cache_pipe.c b/varnish-cache/bin/varnishd/cache_pipe.c index 20d599af..3e6392ec 100644 --- a/varnish-cache/bin/varnishd/cache_pipe.c +++ b/varnish-cache/bin/varnishd/cache_pipe.c @@ -70,7 +70,6 @@ void PipeSession(struct sess *sp) { struct vbe_conn *vc; - char *b, *e; struct worker *w; struct bereq *bereq; struct pollfd fds[2]; @@ -89,8 +88,8 @@ PipeSession(struct sess *sp) WRK_Reset(w, &vc->fd); http_Write(w, bereq->http, 0); - if (http_GetTail(sp->http, 0, &b, &e) && b != e) - WRK_Write(w, b, e - b); + if (sp->htc->pipeline.b != NULL) + WRK_Write(w, sp->htc->pipeline.b, Tlen(sp->htc->pipeline)); if (WRK_Flush(w)) { vca_close_session(sp, "pipe");