]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
[MEDIUM] buffers: add BF_EMPTY and BF_FULL to remove dependency on req/rep->l
authorWilly Tarreau <w@1wt.eu>
Sat, 16 Aug 2008 20:18:07 +0000 (22:18 +0200)
committerWilly Tarreau <w@1wt.eu>
Sat, 16 Aug 2008 20:18:07 +0000 (22:18 +0200)
It is not always convenient to run checks on req->l in functions to
check if a buffer is empty or full. Now the stream_sock functions
set flags BF_EMPTY and BF_FULL according to the buffer contents. Of
course, functions which touch the buffer contents adjust the flags
too.

include/proto/buffers.h
include/types/buffers.h
src/buffers.c
src/client.c
src/proto_http.c
src/proto_uxst.c
src/senddata.c
src/stream_sock.c

index 4090eade9038374a230ff327556301e53853a098..27bf2ea898f2d8100786366a7f0779b957be838f 100644 (file)
@@ -40,12 +40,15 @@ int init_buffer();
 
 /* Initializes all fields in the buffer. The ->rlim field is initialized last
  * so that the compiler can optimize it away if changed immediately after the
- * call to this function.
+ * call to this function. By default, it is set to the full size of the buffer.
+ * The BF_EMPTY flags is set.
  */
 static inline void buffer_init(struct buffer *buf)
 {
-       buf->l = buf->total = buf->flags = 0;
-       buf->rlim = buf->r = buf->lr = buf->w = buf->data;
+       buf->l = buf->total = 0;
+       buf->r = buf->lr = buf->w = buf->data;
+       buf->flags = BF_EMPTY;
+       buf->rlim = buf->data + BUFSIZE;
 }
 
 /* returns 1 if the buffer is empty, 0 otherwise */
@@ -59,11 +62,16 @@ static inline int buffer_isfull(const struct buffer *buf) {
        return buf->l == BUFSIZE;
 }
 
-/* flushes any content from buffer <buf> */
+/* flushes any content from buffer <buf> and adjusts flags
+ * accordingly.
+ */
 static inline void buffer_flush(struct buffer *buf)
 {
        buf->r = buf->lr = buf->w = buf->data;
        buf->l = 0;
+       buf->flags |= BF_EMPTY | BF_FULL;
+       if (buf->rlim)
+               buf->flags &= ~BF_FULL;
 }
 
 /* marks the buffer as "shutdown" for reads and cancels the timeout */
@@ -91,6 +99,17 @@ static inline int buffer_max(const struct buffer *buf)
                return buf->w - buf->r;
 }
 
+/* sets the buffer read limit to <size> bytes, and adjusts the FULL
+ * flag accordingly.
+ */
+static inline void buffer_set_rlim(struct buffer *buf, int size)
+{
+       buf->rlim = buf->data + size;
+       if (buf->l < size)
+               buf->flags &= ~BF_FULL;
+       else
+               buf->flags |= BF_FULL;
+}
 
 /*
  * Tries to realign the given buffer, and returns how many bytes can be written
index be936935876bc04be540eb55df640322404cd55a..0c3bb37265801876dbbf32664a268f7130505f8f 100644 (file)
 #include <common/memory.h>
 
 /* The BF_* macros designate Buffer Flags, which may be ORed in the bit field
- * member 'flags' in struct buffer.
+ * member 'flags' in struct buffer. Some of them are persistent (BF_SHUT*),
+ * some of them (BF_EMPTY,BF_FULL) may only be set by the low-level read/write
+ * functions as well as those who change the buffer's read limit.
  */
+#define BF_EMPTY                1  /* buffer is empty */
+#define BF_FULL                 2  /* buffer cannot accept any more data (l >= rlim-data) */
+
 #define BF_SHUTR                4  /* producer has already shut down */
 #define BF_SHUTW                8  /* consumer has already shut down */
 
index fa6b8a906ad7c5811efcd23b106d7d9fb76c2f6f..f7e672d0708568a5ef3c86f94f1e586330cff35a 100644 (file)
@@ -49,6 +49,12 @@ int buffer_write(struct buffer *buf, const char *msg, int len)
        if (buf->r == buf->data + BUFSIZE)
                buf->r = buf->data;
 
+       buf->flags &= ~(BF_EMPTY|BF_FULL);
+       if (buf->l == 0)
+               buf->flags |= BF_EMPTY;
+       if (buf->l >= buf->rlim - buf->data)
+               buf->flags |= BF_FULL;
+
        return -1;
 }
 
@@ -74,8 +80,14 @@ int buffer_write_chunk(struct buffer *buf, struct chunk *chunk)
        buf->total += chunk->len;
        if (buf->r == buf->data + BUFSIZE)
                buf->r = buf->data;
-       chunk->len = 0;
 
+       buf->flags &= ~(BF_EMPTY|BF_FULL);
+       if (buf->l == 0)
+               buf->flags |= BF_EMPTY;
+       if (buf->l >= buf->rlim - buf->data)
+               buf->flags |= BF_FULL;
+
+       chunk->len = 0;
        return -1;
 }
 
@@ -110,6 +122,12 @@ int buffer_replace(struct buffer *b, char *pos, char *end, const char *str)
        if (b->lr > pos) b->lr += delta;
        b->l += delta;
 
+       b->flags &= ~(BF_EMPTY|BF_FULL);
+       if (b->l == 0)
+               b->flags |= BF_EMPTY;
+       if (b->l >= b->rlim - b->data)
+               b->flags |= BF_FULL;
+
        return delta;
 }
 
@@ -145,6 +163,12 @@ int buffer_replace2(struct buffer *b, char *pos, char *end, const char *str, int
        if (b->lr > pos) b->lr += delta;
        b->l += delta;
 
+       b->flags &= ~(BF_EMPTY|BF_FULL);
+       if (b->l == 0)
+               b->flags |= BF_EMPTY;
+       if (b->l >= b->rlim - b->data)
+               b->flags |= BF_FULL;
+
        return delta;
 }
 
@@ -183,6 +207,12 @@ int buffer_insert_line2(struct buffer *b, char *pos, const char *str, int len)
        if (b->lr > pos) b->lr += delta;
        b->l += delta;
 
+       b->flags &= ~(BF_EMPTY|BF_FULL);
+       if (b->l == 0)
+               b->flags |= BF_EMPTY;
+       if (b->l >= b->rlim - b->data)
+               b->flags |= BF_FULL;
+
        return delta;
 }
 
index 7135d7177e8d6997fb5c09d2b4a3e9a2b67bd01e..67c6dc7959611b91a0dc5f314f121ab24a8ab131 100644 (file)
@@ -333,7 +333,6 @@ int event_accept(int fd) {
                        goto out_fail_req; /* no memory */
 
                buffer_init(s->req);
-               s->req->rlim += BUFSIZE;
                if (p->mode == PR_MODE_HTTP) /* reserve some space for header rewriting */
                        s->req->rlim -= MAXREWRITE;
 
index acbe5ddcafa5cc622b35efca77458f032dfc9cf2..294ab374503ae14f9c0702dae1e38d6a98fb7cb9 100644 (file)
@@ -1743,7 +1743,7 @@ int process_request(struct session *t)
                         *    later, so the session will never terminate. We
                         *    must terminate it now.
                         */
-                       if (unlikely(req->l >= req->rlim - req->data)) {
+                       if (unlikely(req->flags & BF_FULL)) {
                                /* FIXME: check if URI is set and return Status
                                 * 414 Request URI too long instead.
                                 */
@@ -2331,7 +2331,7 @@ int process_request(struct session *t)
                  */
                if (!(t->flags & (SN_ASSIGNED|SN_DIRECT)) &&
                     t->txn.meth == HTTP_METH_POST && t->be->url_param_name != NULL &&
-                    t->be->url_param_post_limit != 0 && req->l < BUFSIZE &&
+                    t->be->url_param_post_limit != 0 && !(req->flags & BF_FULL) &&
                     memchr(msg->sol + msg->sl.rq.u, '?', msg->sl.rq.u_l) == NULL) {
                        /* are there enough bytes here? total == l || r || rlim ?
                         * len is unsigned, but eoh is int,
@@ -2408,7 +2408,7 @@ int process_request(struct session *t)
                 * could. Let's switch to the DATA state.                    *
                 ************************************************************/
 
-               req->rlim = req->data + BUFSIZE; /* no more rewrite needed */
+               buffer_set_rlim(req, BUFSIZE); /* no more rewrite needed */
                t->logs.tv_request = now;
 
                /* When a connection is tarpitted, we use the tarpit timeout,
@@ -2418,7 +2418,7 @@ int process_request(struct session *t)
                 * FIXME: this part should be moved elsewhere (eg: on the server side)
                 */
                if (txn->flags & TX_CLTARPIT) {
-                       t->req->l = 0;
+                       buffer_flush(t->req);
                        /* flush the request so that we can drop the connection early
                         * if the client closes first.
                         */
@@ -2502,8 +2502,7 @@ int process_request(struct session *t)
                 * buffer closed).
                 */
                if (req->l - body >= limit ||             /* enough bytes! */
-                   req->l >= req->rlim - req->data ||    /* full */
-                   req->flags & (BF_READ_ERROR | BF_READ_NULL | BF_READ_TIMEOUT)) {
+                   req->flags & (BF_FULL | BF_READ_ERROR | BF_READ_NULL | BF_READ_TIMEOUT)) {
                        /* The situation will not evolve, so let's give up on the analysis. */
                        t->logs.tv_request = now;  /* update the request timer to reflect full request */
                        t->analysis &= ~AN_REQ_HTTP_BODY;
@@ -2542,9 +2541,9 @@ int process_response(struct session *t)
                 * For the parsing, we use a 28 states FSM.
                 *
                 * Here is the information we currently have :
-                *   rep->data + req->som  = beginning of response
-                *   rep->data + req->eoh  = end of processed headers / start of current one
-                *   rep->data + req->eol  = end of current header or line (LF or CRLF)
+                *   rep->data + rep->som  = beginning of response
+                *   rep->data + rep->eoh  = end of processed headers / start of current one
+                *   rep->data + rep->eol  = end of current header or line (LF or CRLF)
                 *   rep->lr = first non-visited byte
                 *   rep->r  = end of data
                 */
@@ -2644,7 +2643,7 @@ int process_response(struct session *t)
                                return 1;
                        }
                        /* too large response does not fit in buffer. */
-                       else if (rep->l >= rep->rlim - rep->data) {
+                       else if (rep->flags & BF_FULL) {
                                goto hdr_response_bad;
                        }
                        /* read timeout : return a 504 to the client. */
@@ -2948,7 +2947,7 @@ int process_response(struct session *t)
                 * could. Let's switch to the DATA state.                    *
                 ************************************************************/
 
-               rep->rlim = rep->data + BUFSIZE; /* no more rewrite needed */
+               buffer_set_rlim(rep, BUFSIZE); /* no more rewrite needed */
                t->logs.t_data = tv_ms_elapsed(&t->logs.tv_accept, &now);
 
 #ifdef CONFIG_HAP_TCPSPLICE
@@ -3049,7 +3048,7 @@ int process_cli(struct session *t)
                 * allowed to forward the data.
                 */
                else if (!(rep->flags & BF_SHUTW) &&   /* already done */
-                        rep->l == 0 && rep->flags & BF_MAY_FORWARD &&
+                        rep->flags & BF_EMPTY && rep->flags & BF_MAY_FORWARD &&
                         rep->flags & BF_SHUTR && !(t->flags & SN_SELF_GEN)) {
                        buffer_shutw(rep);
                        if (!(req->flags & BF_SHUTR)) {
@@ -3129,7 +3128,7 @@ int process_cli(struct session *t)
 
                /* manage read timeout */
                if (!(req->flags & BF_SHUTR)) {
-                       if (req->l >= req->rlim - req->data) {
+                       if (req->flags & BF_FULL) {
                                /* no room to read more data */
                                if (EV_FD_COND_C(t->cli_fd, DIR_RD)) {
                                        /* stop reading until we get some space */
@@ -3148,7 +3147,7 @@ int process_cli(struct session *t)
                         */
                        if (req->flags & BF_SHUTR && t->flags & SN_SELF_GEN) {
                                produce_content(t);
-                               if (rep->l == 0) {
+                               if (rep->flags & BF_EMPTY) {
                                        buffer_shutw(rep);
                                        fd_delete(t->cli_fd);
                                        t->cli_state = CL_STCLOSE;
@@ -3158,7 +3157,7 @@ int process_cli(struct session *t)
                        }
 
                        /* we don't enable client write if the buffer is empty, nor if the server has to analyze it */
-                       if ((rep->l == 0) || !(rep->flags & BF_MAY_FORWARD)) {
+                       if ((rep->flags & BF_EMPTY) || !(rep->flags & BF_MAY_FORWARD)) {
                                if (EV_FD_COND_C(t->cli_fd, DIR_WR)) {
                                        /* stop writing */
                                        rep->wex = TICK_ETERNITY;
@@ -3227,7 +3226,7 @@ int process_srv(struct session *t)
        if (t->srv_state == SV_STIDLE) {
                if ((rep->flags & BF_SHUTW) ||
                         ((req->flags & BF_SHUTR) &&
-                         (req->l == 0 || t->be->options & PR_O_ABRT_CLOSE))) { /* give up */
+                         (req->flags & BF_EMPTY || t->be->options & PR_O_ABRT_CLOSE))) { /* give up */
                        req->cex = TICK_ETERNITY;
                        if (t->pend_pos)
                                t->logs.t_queue = tv_ms_elapsed(&t->logs.tv_accept, &now);
@@ -3359,7 +3358,7 @@ int process_srv(struct session *t)
        else if (t->srv_state == SV_STCONN) { /* connection in progress */
                if ((rep->flags & BF_SHUTW) ||
                    ((req->flags & BF_SHUTR) &&
-                    ((req->l == 0 && !(req->flags & BF_WRITE_STATUS)) ||
+                    ((req->flags & BF_EMPTY && !(req->flags & BF_WRITE_STATUS)) ||
                      t->be->options & PR_O_ABRT_CLOSE))) { /* give up */
                        req->cex = TICK_ETERNITY;
                        if (!(t->flags & SN_CONN_TAR)) {
@@ -3458,10 +3457,10 @@ int process_srv(struct session *t)
                else { /* no error or write 0 */
                        t->logs.t_connect = tv_ms_elapsed(&t->logs.tv_accept, &now);
 
-                       if (req->l == 0) /* nothing to write */ {
+                       if (req->flags & BF_EMPTY) {
                                EV_FD_CLR(t->srv_fd, DIR_WR);
                                req->wex = TICK_ETERNITY;
-                       } else  /* need the right to write */ {
+                       } else {
                                EV_FD_SET(t->srv_fd, DIR_WR);
                                req->wex = tick_add_ifset(now_ms, t->be->timeout.server);
                                if (tick_isset(req->wex)) {
@@ -3475,7 +3474,7 @@ int process_srv(struct session *t)
                                EV_FD_SET(t->srv_fd, DIR_RD);
                                rep->rex = tick_add_ifset(now_ms, t->be->timeout.server);
                                t->srv_state = SV_STDATA;
-                               rep->rlim = rep->data + BUFSIZE; /* no rewrite needed */
+                               buffer_set_rlim(rep, BUFSIZE); /* no rewrite needed */
 
                                /* if the user wants to log as soon as possible, without counting
                                   bytes from the server, then this is the right moment. */
@@ -3493,7 +3492,7 @@ int process_srv(struct session *t)
                        else {
                                t->srv_state = SV_STDATA;
                                t->analysis |= AN_RTR_HTTP_HDR;
-                               rep->rlim = rep->data + BUFSIZE - MAXREWRITE; /* rewrite needed */
+                               buffer_set_rlim(rep, BUFSIZE - MAXREWRITE); /* rewrite needed */
                                t->txn.rsp.msg_state = HTTP_MSG_RPBEFORE;
                                /* reset hdr_idx which was already initialized by the request.
                                 * right now, the http parser does it.
@@ -3558,7 +3557,7 @@ int process_srv(struct session *t)
                 * coming from the server.
                 */
                else if (!(req->flags & BF_SHUTW) && /* not already done */
-                        req->l == 0 && req->flags & BF_MAY_FORWARD &&
+                        req->flags & BF_EMPTY && req->flags & BF_MAY_FORWARD &&
                         (req->flags & BF_SHUTR ||
                          (t->be->options & PR_O_FORCE_CLO && rep->flags & BF_READ_STATUS))) {
                        buffer_shutw(req);
@@ -3642,7 +3641,7 @@ int process_srv(struct session *t)
 
                /* manage read timeout */
                if (!(rep->flags & BF_SHUTR)) {
-                       if (rep->l >= rep->rlim - rep->data) {
+                       if (rep->flags & BF_FULL) {
                                if (EV_FD_COND_C(t->srv_fd, DIR_RD))
                                        rep->rex = TICK_ETERNITY;
                        } else {
@@ -3653,7 +3652,7 @@ int process_srv(struct session *t)
 
                /* manage write timeout */
                if (!(req->flags & BF_SHUTW)) {
-                       if (req->l == 0 || !(req->flags & BF_MAY_FORWARD)) {
+                       if (req->flags & BF_EMPTY || !(req->flags & BF_MAY_FORWARD)) {
                                /* stop writing */
                                if (EV_FD_COND_C(t->srv_fd, DIR_WR))
                                        req->wex = TICK_ETERNITY;
@@ -5101,7 +5100,7 @@ int stats_check_uri_auth(struct session *t, struct proxy *backend)
        EV_FD_CLR(t->cli_fd, DIR_RD);
        buffer_shutr(t->req);
        buffer_shutr(t->rep);
-       t->req->rlim = t->req->data + BUFSIZE; /* no more rewrite needed */
+       buffer_set_rlim(t->req, BUFSIZE); /* no more rewrite needed */
        t->logs.tv_request = now;
        t->data_source = DATA_SRC_STATS;
        t->data_state  = DATA_ST_INIT;
index d74bcb4c971065265948d21740c5e88d7271d751..443586f2a4906a81badbaafdc8c27ea6f6029c0a 100644 (file)
@@ -483,8 +483,6 @@ int uxst_event_accept(int fd) {
 
                buffer_init(s->req);
                buffer_init(s->rep);
-               s->req->rlim += BUFSIZE;
-               s->rep->rlim += BUFSIZE;
 
                fd_insert(cfd);
                fdtab[cfd].owner = t;
@@ -582,7 +580,7 @@ static int process_uxst_cli(struct session *t)
                        return 1;
                }       
                /* last server read and buffer empty */
-               else if ((s == SV_STSHUTR || s == SV_STCLOSE) && (rep->l == 0)) {
+               else if ((s == SV_STSHUTR || s == SV_STCLOSE) && (rep->flags & BF_EMPTY)) {
                        EV_FD_CLR(t->cli_fd, DIR_WR);
                        buffer_shutw(rep);
                        shutdown(t->cli_fd, SHUT_WR);
@@ -635,7 +633,7 @@ static int process_uxst_cli(struct session *t)
                        return 1;
                }
 
-               if (req->l >= req->rlim - req->data) {
+               if (req->flags & BF_FULL) {
                        /* no room to read more data */
                        if (EV_FD_COND_C(t->cli_fd, DIR_RD)) {
                                /* stop reading until we get some space */
@@ -657,7 +655,7 @@ static int process_uxst_cli(struct session *t)
                        }
                }
 
-               if ((rep->l == 0) ||
+               if ((rep->flags & BF_EMPTY) ||
                    ((s < SV_STDATA) /* FIXME: this may be optimized && (rep->w == rep->h)*/)) {
                        if (EV_FD_COND_C(t->cli_fd, DIR_WR)) {
                                /* stop writing */
@@ -694,7 +692,7 @@ static int process_uxst_cli(struct session *t)
                        }
                        return 1;
                }
-               else if ((s == SV_STSHUTR || s == SV_STCLOSE) && (rep->l == 0)) {
+               else if ((s == SV_STSHUTR || s == SV_STCLOSE) && (rep->flags & BF_EMPTY)) {
                        buffer_shutw(rep);
                        fd_delete(t->cli_fd);
                        t->cli_state = CL_STCLOSE;
@@ -717,7 +715,7 @@ static int process_uxst_cli(struct session *t)
                        return 1;
                }
 
-               if (rep->l == 0) {
+               if (rep->flags & BF_EMPTY) {
                        if (EV_FD_COND_C(t->cli_fd, DIR_WR)) {
                                /* stop writing */
                                rep->wex = TICK_ETERNITY;
@@ -770,7 +768,7 @@ static int process_uxst_cli(struct session *t)
                        }
                        return 1;
                }
-               else if (req->l >= req->rlim - req->data) {
+               else if (req->flags & BF_FULL) {
                        /* no room to read more data */
 
                        /* FIXME-20050705: is it possible for a client to maintain a session
@@ -821,7 +819,7 @@ static int process_uxst_srv(struct session *t)
        if (s == SV_STIDLE) {
                if (c == CL_STCLOSE || c == CL_STSHUTW ||
                         (c == CL_STSHUTR &&
-                         (t->req->l == 0 || t->be->options & PR_O_ABRT_CLOSE))) { /* give up */
+                         (t->req->flags & BF_EMPTY || t->be->options & PR_O_ABRT_CLOSE))) { /* give up */
                        tv_eternity(&req->cex);
                        if (t->pend_pos)
                                t->logs.t_queue = tv_ms_elapsed(&t->logs.tv_accept, &now);
@@ -870,7 +868,7 @@ static int process_uxst_srv(struct session *t)
        else if (s == SV_STCONN) { /* connection in progress */
                if (c == CL_STCLOSE || c == CL_STSHUTW ||
                    (c == CL_STSHUTR &&
-                    ((t->req->l == 0 && !(req->flags & BF_WRITE_STATUS)) ||
+                    ((t->req->flags & BF_EMPTY && !(req->flags & BF_WRITE_STATUS)) ||
                      t->be->options & PR_O_ABRT_CLOSE))) { /* give up */
                        tv_eternity(&req->cex);
                        fd_delete(t->srv_fd);
@@ -941,7 +939,7 @@ static int process_uxst_srv(struct session *t)
                        t->logs.t_connect = tv_ms_elapsed(&t->logs.tv_accept, &now);
 
                        //fprintf(stderr,"3: c=%d, s=%d\n", c, s);
-                       if (req->l == 0) /* nothing to write */ {
+                       if (req->flags & BF_EMPTY) /* nothing to write */ {
                                EV_FD_CLR(t->srv_fd, DIR_WR);
                                tv_eternity(&req->wex);
                        } else  /* need the right to write */ {
@@ -962,7 +960,7 @@ static int process_uxst_srv(struct session *t)
                        t->srv_state = SV_STDATA;
                        if (t->srv)
                                t->srv->cum_sess++;
-                       rep->rlim = rep->data + BUFSIZE; /* no rewrite needed */
+                       buffer_set_rlim(rep, BUFSIZE); /* no rewrite needed */
 
                        /* if the user wants to log as soon as possible, without counting
                           bytes from the server, then this is the right moment. */
@@ -1007,7 +1005,7 @@ static int process_uxst_srv(struct session *t)
                        return 1;
                }
                /* end of client read and no more data to send */
-               else if ((c == CL_STSHUTR || c == CL_STCLOSE) && (req->l == 0)) {
+               else if ((c == CL_STSHUTR || c == CL_STCLOSE) && (req->flags & BF_EMPTY)) {
                        EV_FD_CLR(t->srv_fd, DIR_WR);
                        buffer_shutw(req);
                        shutdown(t->srv_fd, SHUT_WR);
@@ -1048,7 +1046,7 @@ static int process_uxst_srv(struct session *t)
                }
 
                /* recompute request time-outs */
-               if (req->l == 0) {
+               if (req->flags & BF_EMPTY) {
                        if (EV_FD_COND_C(t->srv_fd, DIR_WR)) {
                                /* stop writing */
                                tv_eternity(&req->wex);
@@ -1106,7 +1104,7 @@ static int process_uxst_srv(struct session *t)
 
                        return 1;
                }
-               else if ((c == CL_STSHUTR || c == CL_STCLOSE) && (req->l == 0)) {
+               else if ((c == CL_STSHUTR || c == CL_STCLOSE) && (req->flags & BF_EMPTY)) {
                        //EV_FD_CLR(t->srv_fd, DIR_WR);
                        buffer_shutw(req);
                        fd_delete(t->srv_fd);
@@ -1142,7 +1140,7 @@ static int process_uxst_srv(struct session *t)
 
                        return 1;
                }
-               else if (req->l == 0) {
+               else if (req->flags & BF_EMPTY) {
                        if (EV_FD_COND_C(t->srv_fd, DIR_WR)) {
                                /* stop writing */
                                tv_eternity(&req->wex);
@@ -1263,8 +1261,8 @@ void process_uxst_session(struct task *t, int *next)
                                continue;
                        }
                        if (s->cli_state == CL_STSHUTR ||
-                           (s->req->l >= s->req->rlim - s->req->data)) {
-                               if (s->req->l == 0) {
+                           (s->req->flags & BF_FULL)) {
+                               if (s->req->flags & BF_EMPTY) {
                                        s->srv_state = SV_STCLOSE;
                                        fsm_resync |= 1;
                                        continue;
@@ -1275,7 +1273,7 @@ void process_uxst_session(struct task *t, int *next)
                                 */
                                memcpy(s->rep->data, s->req->data, sizeof(s->rep->data));
                                s->rep->l = s->req->l;
-                               s->rep->rlim = s->rep->data + BUFSIZE;
+                               buffer_set_rlim(s->rep, BUFSIZE);
                                s->rep->w = s->rep->data;
                                s->rep->lr = s->rep->r = s->rep->data + s->rep->l;
 
index 33fe5481977025f10284b7f44b1550679da6243d..6bc5915b49c03ea59cf7b43db65e671dc097f0b4 100644 (file)
@@ -51,13 +51,13 @@ void client_retnclose(struct session *s, const struct chunk *msg)
        EV_FD_CLR(s->cli_fd, DIR_RD);
        EV_FD_SET(s->cli_fd, DIR_WR);
        buffer_shutr(s->req);
+       buffer_flush(s->req);
        s->rep->wex = tick_add_ifset(now_ms, s->rep->wto);
        s->rep->flags |= BF_MAY_FORWARD;
        s->cli_state = CL_STSHUTR; // FIXME: still used by unix sockets
        buffer_flush(s->rep);
        if (msg && msg->len)
                buffer_write(s->rep, msg->str, msg->len);
-       s->req->l = 0;
 }
 
 
@@ -69,10 +69,10 @@ void client_retnclose(struct session *s, const struct chunk *msg)
  */
 void client_return(struct session *s, const struct chunk *msg)
 {
+       buffer_flush(s->req);
        buffer_flush(s->rep);
        if (msg && msg->len)
                buffer_write(s->rep, msg->str, msg->len);
-       s->req->l = 0;
 }
 
 /*
index 3e3e0b9d83c59fbd04fb5b4240d9f994db7f5da7..b35b9fe76723bc5428d26cad67de0e65fd91633a 100644 (file)
@@ -84,6 +84,7 @@ int stream_sock_read(int fd) {
                        /* Not anymore room to store data. This should theorically
                         * never happen, but better safe than sorry !
                         */
+                       b->flags |= BF_FULL;
                        EV_FD_CLR(fd, DIR_RD);
                        b->rex = TICK_ETERNITY;
                        goto out_wakeup;
@@ -111,6 +112,7 @@ int stream_sock_read(int fd) {
                        b->l += ret;
                        cur_read += ret;
                        b->flags |= BF_PARTIAL_READ;
+                       b->flags &= ~BF_EMPTY;
        
                        if (b->r == b->data + BUFSIZE) {
                                b->r = b->data; /* wrap around the buffer */
@@ -118,7 +120,7 @@ int stream_sock_read(int fd) {
 
                        b->total += ret;
 
-                       if (b->l == b->rlim - b->data) {
+                       if (b->l >= b->rlim - b->data) {
                                /* The buffer is now full, there's no point in going through
                                 * the loop again.
                                 */
@@ -151,6 +153,7 @@ int stream_sock_read(int fd) {
                                        b->xfer_large = 0;
                                }
 
+                               b->flags |= BF_FULL;
                                EV_FD_CLR(fd, DIR_RD);
                                b->rex = TICK_ETERNITY;
                                goto out_wakeup;
@@ -335,12 +338,16 @@ int stream_sock_write(int fd) {
                        b->w += ret;
            
                        b->flags |= BF_PARTIAL_WRITE;
+
+                       if (b->l < b->rlim - b->data)
+                               b->flags &= ~BF_FULL;
            
                        if (b->w == b->data + BUFSIZE) {
                                b->w = b->data; /* wrap around the buffer */
                        }
 
                        if (!b->l) {
+                               b->flags |= BF_EMPTY;
                                EV_FD_CLR(fd, DIR_WR);
                                b->wex = TICK_ETERNITY;
                                goto out_wakeup;