]> err.no Git - varnish/commitdiff
Complete the split of HTTP-editing and HTTP-transmission functions.
authorphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Fri, 28 Sep 2007 20:13:48 +0000 (20:13 +0000)
committerphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Fri, 28 Sep 2007 20:13:48 +0000 (20:13 +0000)
git-svn-id: svn+ssh://projects.linpro.no/svn/varnish/trunk@2055 d4fa192b-c00b-0410-8231-f00ffab90ce4

varnish-cache/bin/varnishd/cache.h
varnish-cache/bin/varnishd/cache_acceptor.c
varnish-cache/bin/varnishd/cache_center.c
varnish-cache/bin/varnishd/cache_fetch.c
varnish-cache/bin/varnishd/cache_http.c
varnish-cache/bin/varnishd/cache_httpconn.c
varnish-cache/bin/varnishd/cache_pipe.c

index a6eb0d35345569719803ee77e8e83dc735e0db94..25d53fb182f4839ec437db345427a0ca0dfe886f 100644 (file)
@@ -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"
index b769d0d3a77c3575440007cfcb62e92b02820eb0..1ce0d6d41000317b2839df0e3d7a46c13d7d2a9e 100644 (file)
@@ -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);
 }
 
index 3ee46bae10e23d38cb02e5ed6d94497004d35db7..1d5bb93e88e03690b46e2a8676def7861056874f 100644 (file)
@@ -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;
index 46e26fd0498d6fa2ba1d6a237f3586e4f40c6ea9..89c85f0074b63f4f2f34ce6ae6200f8bbe512496 100644 (file)
@@ -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 <errno.h>
 
 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:
index f570b91a35a85adaf58c66bda9aec31f968b5cf4..84870d1c3f181b95bf50014176bbeb42172e1041 100644 (file)
@@ -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
index cd397524b72d8d34fb6ff5fffe1d3cd54fd45aba..991fd20f706889579271b31f030e941ddbd51b9d 100644 (file)
@@ -31,6 +31,8 @@
  * HTTP protocol requests
  */
 
+#include <stdio.h>
+#include <stdlib.h>
 #include <ctype.h>
 #include <string.h>
 #include <unistd.h>
@@ -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.
  */
 
 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);
 }
-
index 20d599afe4ac89626f2e236f3a375a744b96f86a..3e6392ec6cb84d56aa5779003eaf4f39e7a0ef6f 100644 (file)
@@ -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");