]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MAJOR: channel: replace the struct buffer with a pointer to a buffer
authorWilly Tarreau <w@1wt.eu>
Fri, 12 Oct 2012 21:49:43 +0000 (23:49 +0200)
committerWilly Tarreau <w@1wt.eu>
Sat, 13 Oct 2012 07:07:52 +0000 (09:07 +0200)
With this commit, we now separate the channel from the buffer. This will
allow us to replace buffers on the fly without touching the channel. Since
nobody is supposed to keep a reference to a buffer anymore, doing so is not
a problem and will also permit some copy-less data manipulation.

Interestingly, these changes have shown a 2% performance increase on some
workloads, probably due to a better cache placement of data.

14 files changed:
include/common/buffer.h
include/proto/channel.h
include/types/channel.h
src/acl.c
src/backend.c
src/buffer.c
src/channel.c
src/dumpstats.c
src/haproxy.c
src/peers.c
src/proto_http.c
src/proto_tcp.c
src/session.c
src/stream_interface.c

index 6ad16c617b29b433fc6994ced276e686227124c8..d46495c883f2f8e5bce16e78b781403c5dc66c68 100644 (file)
@@ -28,6 +28,7 @@
 
 #include <common/chunk.h>
 #include <common/config.h>
+#include <common/memory.h>
 
 
 struct buffer {
@@ -38,7 +39,9 @@ struct buffer {
        char data[0];                   /* <size> bytes */
 };
 
+extern struct pool_head *pool2_buffer;
 
+int init_buffer();
 int buffer_replace2(struct buffer *b, char *pos, char *end, const char *str, int len);
 int buffer_insert_line2(struct buffer *b, char *pos, const char *str, int len);
 void buffer_dump(FILE *o, struct buffer *b, int from, int to);
index 37f5457ded7a5063ad8f804876b12ff6d0434377..80bd39d1df8918f04cebb462c5bfb3f39f6cca03 100644 (file)
@@ -51,9 +51,9 @@ int bo_getblk(struct channel *chn, char *blk, int len, int offset);
 /* Initialize all fields in the channel. */
 static inline void channel_init(struct channel *chn)
 {
-       chn->buf.o = 0;
-       chn->buf.i = 0;
-       chn->buf.p = chn->buf.data;
+       chn->buf->o = 0;
+       chn->buf->i = 0;
+       chn->buf->p = chn->buf->data;
        chn->to_forward = 0;
        chn->total = 0;
        chn->pipe = NULL;
@@ -73,7 +73,7 @@ static inline void channel_init(struct channel *chn)
  */
 static inline unsigned int channel_is_empty(struct channel *c)
 {
-       return !(c->buf.o | (long)c->pipe);
+       return !(c->buf->o | (long)c->pipe);
 }
 
 /* Returns non-zero if the buffer input is considered full. The reserved space
@@ -83,20 +83,20 @@ static inline unsigned int channel_is_empty(struct channel *c)
  */
 static inline int channel_full(const struct channel *chn)
 {
-       int rem = chn->buf.size;
+       int rem = chn->buf->size;
 
-       rem -= chn->buf.o;
-       rem -= chn->buf.i;
+       rem -= chn->buf->o;
+       rem -= chn->buf->i;
        if (!rem)
                return 1; /* buffer already full */
 
-       if (chn->to_forward >= chn->buf.size ||
-           (CHN_INFINITE_FORWARD < MAX_RANGE(typeof(chn->buf.size)) && // just there to ensure gcc
+       if (chn->to_forward >= chn->buf->size ||
+           (CHN_INFINITE_FORWARD < MAX_RANGE(typeof(chn->buf->size)) && // just there to ensure gcc
             chn->to_forward == CHN_INFINITE_FORWARD))                  // avoids the useless second
                return 0;                                               // test whenever possible
 
        rem -= global.tune.maxrewrite;
-       rem += chn->buf.o;
+       rem += chn->buf->o;
        rem += chn->to_forward;
        return rem <= 0;
 }
@@ -139,10 +139,10 @@ static inline void channel_check_timeouts(struct channel *chn)
  */
 static inline void channel_erase(struct channel *chn)
 {
-       chn->buf.o = 0;
-       chn->buf.i = 0;
+       chn->buf->o = 0;
+       chn->buf->i = 0;
        chn->to_forward = 0;
-       chn->buf.p = chn->buf.data;
+       chn->buf->p = chn->buf->data;
 }
 
 /* marks the channel as "shutdown" ASAP for reads */
@@ -236,7 +236,7 @@ static inline void channel_dont_read(struct channel *chn)
  */
 static inline int buffer_reserved(const struct channel *chn)
 {
-       int ret = global.tune.maxrewrite - chn->to_forward - chn->buf.o;
+       int ret = global.tune.maxrewrite - chn->to_forward - chn->buf->o;
 
        if (chn->to_forward == CHN_INFINITE_FORWARD)
                return 0;
@@ -251,7 +251,7 @@ static inline int buffer_reserved(const struct channel *chn)
  */
 static inline int buffer_max_len(const struct channel *chn)
 {
-       return chn->buf.size - buffer_reserved(chn);
+       return chn->buf->size - buffer_reserved(chn);
 }
 
 /* Return the amount of bytes that can be written into the buffer at once,
@@ -259,7 +259,7 @@ static inline int buffer_max_len(const struct channel *chn)
  */
 static inline int buffer_contig_space_res(const struct channel *chn)
 {
-       return buffer_contig_space_with_res(&chn->buf, buffer_reserved(chn));
+       return buffer_contig_space_with_res(chn->buf, buffer_reserved(chn));
 }
 
 /* Returns the amount of space available at the input of the buffer, taking the
@@ -269,21 +269,21 @@ static inline int buffer_contig_space_res(const struct channel *chn)
  */
 static inline int bi_avail(const struct channel *chn)
 {
-       int rem = chn->buf.size;
+       int rem = chn->buf->size;
        int rem2;
 
-       rem -= chn->buf.o;
-       rem -= chn->buf.i;
+       rem -= chn->buf->o;
+       rem -= chn->buf->i;
        if (!rem)
                return rem; /* buffer already full */
 
-       if (chn->to_forward >= chn->buf.size ||
-           (CHN_INFINITE_FORWARD < MAX_RANGE(typeof(chn->buf.size)) && // just there to ensure gcc
+       if (chn->to_forward >= chn->buf->size ||
+           (CHN_INFINITE_FORWARD < MAX_RANGE(typeof(chn->buf->size)) && // just there to ensure gcc
             chn->to_forward == CHN_INFINITE_FORWARD))                  // avoids the useless second
                return rem;                                             // test whenever possible
 
        rem2 = rem - global.tune.maxrewrite;
-       rem2 += chn->buf.o;
+       rem2 += chn->buf->o;
        rem2 += chn->to_forward;
 
        if (rem > rem2)
@@ -300,14 +300,14 @@ static inline int bi_avail(const struct channel *chn)
  */
 static inline void bi_erase(struct channel *chn)
 {
-       if (!chn->buf.o)
+       if (!chn->buf->o)
                return channel_erase(chn);
 
        chn->to_forward = 0;
-       if (!chn->buf.i)
+       if (!chn->buf->i)
                return;
 
-       chn->buf.i = 0;
+       chn->buf->i = 0;
 }
 
 /*
@@ -319,10 +319,10 @@ static inline void bi_erase(struct channel *chn)
  */
 static inline void bo_skip(struct channel *chn, int len)
 {
-       chn->buf.o -= len;
+       chn->buf->o -= len;
 
-       if (buffer_len(&chn->buf) == 0)
-               chn->buf.p = chn->buf.data;
+       if (buffer_len(chn->buf) == 0)
+               chn->buf->p = chn->buf->data;
 
        /* notify that some data was written to the SI from the buffer */
        chn->flags |= CF_WRITE_PARTIAL;
@@ -374,7 +374,7 @@ static inline int bo_getchr(struct channel *chn)
                        return -2;
                return -1;
        }
-       return *buffer_wrap_sub(&chn->buf, chn->buf.p - chn->buf.o);
+       return *buffer_wrap_sub(chn->buf, chn->buf->p - chn->buf->o);
 }
 
 
index a21e13f0296292ea480d1f15457b1c9f8fc9c4da..efd1a128c1f96952217be5b009c0e146fd78ed90 100644 (file)
@@ -186,7 +186,7 @@ struct channel {
        struct stream_interface *prod;  /* producer attached to this channel */
        struct stream_interface *cons;  /* consumer attached to this channel */
        struct pipe *pipe;              /* non-NULL only when data present */
-       struct buffer buf;              /* embedded buffer for now, will move */
+       struct buffer *buf;             /* buffer attached to the channel, always present but may move */
 };
 
 
index d65447a5e3c8bf0afeb8f7a0c06a01ff455ebb98..ba7c1f0ea1a0f8b8262e6664a5f6600602c9e68b 100644 (file)
--- a/src/acl.c
+++ b/src/acl.c
@@ -108,7 +108,7 @@ acl_fetch_req_len(struct proxy *px, struct session *l4, void *l7, unsigned int o
                return 0;
 
        smp->type = SMP_T_UINT;
-       smp->data.uint = l4->req->buf.i;
+       smp->data.uint = l4->req->buf->i;
        smp->flags = SMP_F_VOLATILE | SMP_F_MAY_CHANGE;
        return 1;
 }
@@ -128,8 +128,8 @@ acl_fetch_ssl_hello_type(struct proxy *px, struct session *l4, void *l7, unsigne
 
        chn = ((opt & SMP_OPT_DIR) == SMP_OPT_DIR_RES) ? l4->rep : l4->req;
 
-       bleft = chn->buf.i;
-       data = (const unsigned char *)chn->buf.p;
+       bleft = chn->buf->i;
+       data = (const unsigned char *)chn->buf->p;
 
        if (!bleft)
                goto too_short;
@@ -194,11 +194,11 @@ acl_fetch_req_ssl_ver(struct proxy *px, struct session *l4, void *l7, unsigned i
                return 0;
 
        msg_len = 0;
-       bleft = l4->req->buf.i;
+       bleft = l4->req->buf->i;
        if (!bleft)
                goto too_short;
 
-       data = (const unsigned char *)l4->req->buf.p;
+       data = (const unsigned char *)l4->req->buf->p;
        if ((*data >= 0x14 && *data <= 0x17) || (*data == 0xFF)) {
                /* SSLv3 header format */
                if (bleft < 5)
@@ -266,8 +266,8 @@ acl_fetch_req_ssl_ver(struct proxy *px, struct session *l4, void *l7, unsigned i
         * all the part of the request which fits in a buffer is already
         * there.
         */
-       if (msg_len > buffer_max_len(l4->req) + l4->req->buf.data - l4->req->buf.p)
-               msg_len = buffer_max_len(l4->req) + l4->req->buf.data - l4->req->buf.p;
+       if (msg_len > buffer_max_len(l4->req) + l4->req->buf->data - l4->req->buf->p)
+               msg_len = buffer_max_len(l4->req) + l4->req->buf->data - l4->req->buf->p;
 
        if (bleft < msg_len)
                goto too_short;
@@ -332,8 +332,8 @@ acl_fetch_ssl_hello_sni(struct proxy *px, struct session *l4, void *l7, unsigned
 
        chn = ((opt & SMP_OPT_DIR) == SMP_OPT_DIR_RES) ? l4->rep : l4->req;
 
-       bleft = chn->buf.i;
-       data = (unsigned char *)chn->buf.p;
+       bleft = chn->buf->i;
+       data = (unsigned char *)chn->buf->p;
 
        /* Check for SSL/TLS Handshake */
        if (!bleft)
index bae62b5067da0c9ce40ecb2d58109decb5bd7966..4528d0e477c9574a457fb0a84947d146df6added 100644 (file)
@@ -258,11 +258,11 @@ struct server *get_server_ph_post(struct session *s)
        struct proxy    *px   = s->be;
        unsigned int     plen = px->url_param_len;
        unsigned long    len  = msg->body_len;
-       const char      *params = b_ptr(&req->buf, (int)(msg->sov - req->buf.o));
+       const char      *params = b_ptr(req->buf, (int)(msg->sov - req->buf->o));
        const char      *p    = params;
 
-       if (len > buffer_len(&req->buf) - msg->sov)
-               len = buffer_len(&req->buf) - msg->sov;
+       if (len > buffer_len(req->buf) - msg->sov)
+               len = buffer_len(req->buf) - msg->sov;
 
        if (len == 0)
                return NULL;
@@ -343,7 +343,7 @@ struct server *get_server_hh(struct session *s)
        ctx.idx = 0;
 
        /* if the message is chunked, we skip the chunk size, but use the value as len */
-       http_find_header2(px->hh_name, plen, b_ptr(&s->req->buf, (int)-s->req->buf.o), &txn->hdr_idx, &ctx);
+       http_find_header2(px->hh_name, plen, b_ptr(s->req->buf, (int)-s->req->buf->o), &txn->hdr_idx, &ctx);
 
        /* if the header is not found or empty, let's fallback to round robin */
        if (!ctx.idx || !ctx.vlen)
@@ -419,12 +419,12 @@ struct server *get_server_rch(struct session *s)
        args[0].data.str.len = px->hh_len;
        args[1].type = ARGT_STOP;
 
-       b_rew(&s->req->buf, rewind = s->req->buf.o);
+       b_rew(s->req->buf, rewind = s->req->buf->o);
 
        ret = smp_fetch_rdp_cookie(px, s, NULL, SMP_OPT_DIR_REQ|SMP_OPT_FINAL, args, &smp);
        len = smp.data.str.len;
 
-       b_adv(&s->req->buf, rewind);
+       b_adv(s->req->buf, rewind);
 
        if (ret == 0 || (smp.flags & SMP_F_MAY_CHANGE) || len == 0)
                return NULL;
@@ -569,7 +569,7 @@ int assign_server(struct session *s)
                                if (s->txn.req.msg_state < HTTP_MSG_BODY)
                                        break;
                                srv = get_server_uh(s->be,
-                                                   b_ptr(&s->req->buf, (int)(s->txn.req.sl.rq.u - s->req->buf.o)),
+                                                   b_ptr(s->req->buf, (int)(s->txn.req.sl.rq.u - s->req->buf->o)),
                                                    s->txn.req.sl.rq.u_l);
                                break;
 
@@ -579,7 +579,7 @@ int assign_server(struct session *s)
                                        break;
 
                                srv = get_server_ph(s->be,
-                                                   b_ptr(&s->req->buf, (int)(s->txn.req.sl.rq.u - s->req->buf.o)),
+                                                   b_ptr(s->req->buf, (int)(s->txn.req.sl.rq.u - s->req->buf->o)),
                                                    s->txn.req.sl.rq.u_l);
 
                                if (!srv && s->txn.meth == HTTP_METH_POST)
@@ -905,13 +905,13 @@ static void assign_tproxy_address(struct session *s)
                                ((struct sockaddr_in *)&s->req->cons->conn.addr.from)->sin_port = 0;
                                ((struct sockaddr_in *)&s->req->cons->conn.addr.from)->sin_addr.s_addr = 0;
 
-                               b_rew(&s->req->buf, rewind = s->req->buf.o);
+                               b_rew(s->req->buf, rewind = s->req->buf->o);
                                if (http_get_hdr(&s->txn.req, srv->bind_hdr_name, srv->bind_hdr_len,
                                                 &s->txn.hdr_idx, srv->bind_hdr_occ, NULL, &vptr, &vlen)) {
                                        ((struct sockaddr_in *)&s->req->cons->conn.addr.from)->sin_addr.s_addr =
                                                htonl(inetaddr_host_lim(vptr, vptr + vlen));
                                }
-                               b_adv(&s->req->buf, rewind);
+                               b_adv(s->req->buf, rewind);
                        }
                        break;
                default:
@@ -939,13 +939,13 @@ static void assign_tproxy_address(struct session *s)
                                ((struct sockaddr_in *)&s->req->cons->conn.addr.from)->sin_port = 0;
                                ((struct sockaddr_in *)&s->req->cons->conn.addr.from)->sin_addr.s_addr = 0;
 
-                               b_rew(&s->req->buf, rewind = s->req->buf.o);
+                               b_rew(s->req->buf, rewind = s->req->buf->o);
                                if (http_get_hdr(&s->txn.req, s->be->bind_hdr_name, s->be->bind_hdr_len,
                                                 &s->txn.hdr_idx, s->be->bind_hdr_occ, NULL, &vptr, &vlen)) {
                                        ((struct sockaddr_in *)&s->req->cons->conn.addr.from)->sin_addr.s_addr =
                                                htonl(inetaddr_host_lim(vptr, vptr + vlen));
                                }
-                               b_adv(&s->req->buf, rewind);
+                               b_adv(s->req->buf, rewind);
                        }
                        break;
                default:
@@ -1144,7 +1144,7 @@ int tcp_persist_rdp_cookie(struct session *s, struct channel *req, int an_bit)
                req,
                req->rex, req->wex,
                req->flags,
-               req->buf.i,
+               req->buf->i,
                req->analysers);
 
        if (s->flags & SN_ASSIGNED)
index f98da94508297901906091babd071d256f8bc778..899f5f4952f4cebb28fb3a2ecddfe6bf4c60cd2e 100644 (file)
 
 #include <common/config.h>
 #include <common/buffer.h>
+#include <common/memory.h>
 
 #include <types/global.h>
 
+struct pool_head *pool2_buffer;
+
+
+/* perform minimal intializations, report 0 in case of error, 1 if OK. */
+int init_buffer()
+{
+       pool2_buffer = create_pool("buffer", sizeof (struct buffer) + global.tune.bufsize, MEM_F_SHARED);
+       return pool2_buffer != NULL;
+}
+
 /* This function writes the string <str> at position <pos> which must be in
  * buffer <b>, and moves <end> just after the end of <str>. <b>'s parameters
  * <l> and <r> are updated to be valid after the shift. The shift value
index 7b0d44e1d58854b5543c027e837813289a7957ec..6e945d4c4d0a841c6f90661e04fee22a7b63355e 100644 (file)
@@ -18,9 +18,8 @@
 #include <common/config.h>
 #include <common/memory.h>
 #include <common/buffer.h>
-#include <proto/channel.h>
-#include <types/global.h>
 
+#include <proto/channel.h>
 
 struct pool_head *pool2_channel;
 
@@ -28,7 +27,7 @@ struct pool_head *pool2_channel;
 /* perform minimal intializations, report 0 in case of error, 1 if OK. */
 int init_channel()
 {
-       pool2_channel = create_pool("channel", sizeof(struct channel) + global.tune.bufsize, MEM_F_SHARED);
+       pool2_channel = create_pool("channel", sizeof(struct channel), MEM_F_SHARED);
        return pool2_channel != NULL;
 }
 
@@ -53,17 +52,17 @@ unsigned long long channel_forward(struct channel *chn, unsigned long long bytes
         * once anyway.
         */
        if (bytes <= ~0U) {
-               if (bytes32 <= chn->buf.i) {
+               if (bytes32 <= chn->buf->i) {
                        /* OK this amount of bytes might be forwarded at once */
                        if (!bytes32)
                                return 0;
-                       b_adv(&chn->buf, bytes32);
+                       b_adv(chn->buf, bytes32);
                        return bytes;
                }
        }
 
-       forwarded = chn->buf.i;
-       b_adv(&chn->buf, chn->buf.i);
+       forwarded = chn->buf->i;
+       b_adv(chn->buf, chn->buf->i);
 
        /* Note: the case below is the only case where we may return
         * a byte count that does not fit into a 32-bit number.
@@ -105,7 +104,7 @@ int bo_inject(struct channel *chn, const char *msg, int len)
        if (len == 0)
                return -1;
 
-       if (len > chn->buf.size) {
+       if (len > chn->buf->size) {
                /* we can't write this chunk and will never be able to, because
                 * it is larger than the buffer. This must be reported as an
                 * error. Then we return -2 so that writers that don't care can
@@ -114,14 +113,14 @@ int bo_inject(struct channel *chn, const char *msg, int len)
                return -2;
        }
 
-       max = buffer_realign(&chn->buf);
+       max = buffer_realign(chn->buf);
 
        if (len > max)
                return max;
 
-       memcpy(chn->buf.p, msg, len);
-       chn->buf.o += len;
-       chn->buf.p = b_ptr(&chn->buf, len);
+       memcpy(chn->buf->p, msg, len);
+       chn->buf->o += len;
+       chn->buf->p = b_ptr(chn->buf, len);
        chn->total += len;
        return -1;
 }
@@ -140,15 +139,15 @@ int bi_putchr(struct channel *chn, char c)
        if (channel_full(chn))
                return -1;
 
-       *bi_end(&chn->buf) = c;
+       *bi_end(chn->buf) = c;
 
-       chn->buf.i++;
+       chn->buf->i++;
        chn->flags |= CF_READ_PARTIAL;
 
        if (chn->to_forward >= 1) {
                if (chn->to_forward != CHN_INFINITE_FORWARD)
                        chn->to_forward--;
-               b_adv(&chn->buf, 1);
+               b_adv(chn->buf, 1);
        }
 
        chn->total++;
@@ -171,7 +170,7 @@ int bi_putblk(struct channel *chn, const char *blk, int len)
                return -2;
 
        max = buffer_max_len(chn);
-       if (unlikely(len > max - buffer_len(&chn->buf))) {
+       if (unlikely(len > max - buffer_len(chn->buf))) {
                /* we can't write this chunk right now because the buffer is
                 * almost full or because the block is too large. Return the
                 * available space or -2 if impossible.
@@ -186,12 +185,12 @@ int bi_putblk(struct channel *chn, const char *blk, int len)
                return 0;
 
        /* OK so the data fits in the buffer in one or two blocks */
-       max = buffer_contig_space_with_res(&chn->buf, chn->buf.size - max);
-       memcpy(bi_end(&chn->buf), blk, MIN(len, max));
+       max = buffer_contig_space_with_res(chn->buf, chn->buf->size - max);
+       memcpy(bi_end(chn->buf), blk, MIN(len, max));
        if (len > max)
-               memcpy(chn->buf.data, blk + max, len - max);
+               memcpy(chn->buf->data, blk + max, len - max);
 
-       chn->buf.i += len;
+       chn->buf->i += len;
        chn->total += len;
        if (chn->to_forward) {
                unsigned long fwd = len;
@@ -200,7 +199,7 @@ int bi_putblk(struct channel *chn, const char *blk, int len)
                                fwd = chn->to_forward;
                        chn->to_forward -= fwd;
                }
-               b_adv(&chn->buf, fwd);
+               b_adv(chn->buf, fwd);
        }
 
        /* notify that some data was read from the SI into the buffer */
@@ -233,10 +232,10 @@ int bo_getline(struct channel *chn, char *str, int len)
                goto out;
        }
 
-       p = bo_ptr(&chn->buf);
+       p = bo_ptr(chn->buf);
 
-       if (max > chn->buf.o) {
-               max = chn->buf.o;
+       if (max > chn->buf->o) {
+               max = chn->buf->o;
                str[max-1] = 0;
        }
        while (max) {
@@ -246,9 +245,9 @@ int bo_getline(struct channel *chn, char *str, int len)
 
                if (*p == '\n')
                        break;
-               p = buffer_wrap_add(&chn->buf, p + 1);
+               p = buffer_wrap_add(chn->buf, p + 1);
        }
-       if (ret > 0 && ret < len && ret < chn->buf.o &&
+       if (ret > 0 && ret < len && ret < chn->buf->o &&
            *(str-1) != '\n' &&
            !(chn->flags & (CF_SHUTW|CF_SHUTW_NOW)))
                ret = 0;
@@ -273,25 +272,25 @@ int bo_getblk(struct channel *chn, char *blk, int len, int offset)
        if (chn->flags & CF_SHUTW)
                return -1;
 
-       if (len + offset > chn->buf.o) {
+       if (len + offset > chn->buf->o) {
                if (chn->flags & (CF_SHUTW|CF_SHUTW_NOW))
                        return -1;
                return 0;
        }
 
-       firstblock = chn->buf.data + chn->buf.size - bo_ptr(&chn->buf);
+       firstblock = chn->buf->data + chn->buf->size - bo_ptr(chn->buf);
        if (firstblock > offset) {
                if (firstblock >= len + offset) {
-                       memcpy(blk, bo_ptr(&chn->buf) + offset, len);
+                       memcpy(blk, bo_ptr(chn->buf) + offset, len);
                        return len;
                }
 
-               memcpy(blk, bo_ptr(&chn->buf) + offset, firstblock - offset);
-               memcpy(blk + firstblock - offset, chn->buf.data, len - firstblock + offset);
+               memcpy(blk, bo_ptr(chn->buf) + offset, firstblock - offset);
+               memcpy(blk + firstblock - offset, chn->buf->data, len - firstblock + offset);
                return len;
        }
 
-       memcpy(blk, chn->buf.data + offset - firstblock, len);
+       memcpy(blk, chn->buf->data + offset - firstblock, len);
        return len;
 }
 
index d11d38084f152c99f27f1a3cbcda8eb4c023efef..fd7d4221505ed04388ebcb61b0b46afd2dc372c2 100644 (file)
@@ -1462,7 +1462,7 @@ static void cli_io_handler(struct stream_interface *si)
                        /* ensure we have some output room left in the event we
                         * would want to return some info right after parsing.
                         */
-                       if (buffer_almost_full(&si->ib->buf))
+                       if (buffer_almost_full(si->ib->buf))
                                break;
 
                        reql = bo_getline(si->ob, trash, trashlen);
@@ -1576,7 +1576,7 @@ static void cli_io_handler(struct stream_interface *si)
                         * buffer is empty. This still allows pipelined requests
                         * to be sent in non-interactive mode.
                         */
-                       if ((res->flags & (CF_SHUTW|CF_SHUTW_NOW)) || (!si->applet.st1 && !req->buf.o)) {
+                       if ((res->flags & (CF_SHUTW|CF_SHUTW_NOW)) || (!si->applet.st1 && !req->buf->o)) {
                                si->applet.st0 = STAT_CLI_END;
                                continue;
                        }
@@ -1618,7 +1618,7 @@ static void cli_io_handler(struct stream_interface *si)
  out:
        DPRINTF(stderr, "%s@%d: st=%d, rqf=%x, rpf=%x, rqh=%d, rqs=%d, rh=%d, rs=%d\n",
                __FUNCTION__, __LINE__,
-               si->state, req->flags, res->flags, req->buf.i, req->buf.o, res->buf.i, res->buf.o);
+               si->state, req->flags, res->flags, req->buf->i, req->buf->o, res->buf->i, res->buf->o);
 
        if (unlikely(si->state == SI_ST_DIS || si->state == SI_ST_CLO)) {
                /* check that we have released everything then unregister */
@@ -2178,7 +2178,7 @@ static int stats_dump_http(struct stream_interface *si, struct uri_auth *uri)
        case STAT_ST_LIST:
                /* dump proxies */
                while (si->applet.ctx.stats.px) {
-                       if (buffer_almost_full(&rep->buf))
+                       if (buffer_almost_full(rep->buf))
                                return 0;
                        px = si->applet.ctx.stats.px;
                        /* skip the disabled proxies, global frontend and non-networked ones */
@@ -2494,7 +2494,7 @@ static int stats_dump_proxy(struct stream_interface *si, struct proxy *px, struc
        case STAT_PX_ST_LI:
                /* stats.l has been initialized above */
                for (; si->applet.ctx.stats.l != &px->conf.listeners; si->applet.ctx.stats.l = l->by_fe.n) {
-                       if (buffer_almost_full(&rep->buf))
+                       if (buffer_almost_full(rep->buf))
                                return 0;
 
                        l = LIST_ELEM(si->applet.ctx.stats.l, struct listener *, by_fe);
@@ -2632,7 +2632,7 @@ static int stats_dump_proxy(struct stream_interface *si, struct proxy *px, struc
                for (; si->applet.ctx.stats.sv != NULL; si->applet.ctx.stats.sv = sv->next) {
                        int sv_state; /* 0=DOWN, 1=going up, 2=going down, 3=UP, 4,5=NOLB, 6=unchecked */
 
-                       if (buffer_almost_full(&rep->buf))
+                       if (buffer_almost_full(rep->buf))
                                return 0;
 
                        sv = si->applet.ctx.stats.sv;
@@ -3453,7 +3453,7 @@ static int stats_dump_full_sess_to_buffer(struct stream_interface *si)
                             "      an_exp=%s",
                             sess->req,
                             sess->req->flags, sess->req->analysers,
-                            sess->req->buf.i, sess->req->buf.o,
+                            sess->req->buf->i, sess->req->buf->o,
                             sess->req->pipe ? sess->req->pipe->data : 0,
                             sess->req->to_forward,
                             sess->req->analyse_exp ?
@@ -3472,8 +3472,8 @@ static int stats_dump_full_sess_to_buffer(struct stream_interface *si)
                             sess->req->wex ?
                             human_time(TICKS_TO_MS(sess->req->wex - now_ms),
                                        TICKS_TO_MS(1000)) : "<NEVER>",
-                            sess->req->buf.data,
-                            (int)(sess->req->buf.p - sess->req->buf.data),
+                            sess->req->buf->data,
+                            (int)(sess->req->buf->p - sess->req->buf->data),
                             sess->txn.req.next,
                             sess->req->total);
 
@@ -3482,7 +3482,7 @@ static int stats_dump_full_sess_to_buffer(struct stream_interface *si)
                             "      an_exp=%s",
                             sess->rep,
                             sess->rep->flags, sess->rep->analysers,
-                            sess->rep->buf.i, sess->rep->buf.o,
+                            sess->rep->buf->i, sess->rep->buf->o,
                             sess->rep->pipe ? sess->rep->pipe->data : 0,
                             sess->rep->to_forward,
                             sess->rep->analyse_exp ?
@@ -3501,8 +3501,8 @@ static int stats_dump_full_sess_to_buffer(struct stream_interface *si)
                             sess->rep->wex ?
                             human_time(TICKS_TO_MS(sess->rep->wex - now_ms),
                                        TICKS_TO_MS(1000)) : "<NEVER>",
-                            sess->rep->buf.data,
-                            (int)(sess->rep->buf.p - sess->rep->buf.data),
+                            sess->rep->buf->data,
+                            (int)(sess->rep->buf->p - sess->rep->buf->data),
                             sess->txn.rsp.next,
                             sess->rep->total);
 
@@ -3623,7 +3623,7 @@ static int stats_dump_sess_to_buffer(struct stream_interface *si)
                        chunk_printf(&msg,
                                     " rq[f=%06xh,i=%d,an=%02xh,rx=%s",
                                     curr_sess->req->flags,
-                                    curr_sess->req->buf.i,
+                                    curr_sess->req->buf->i,
                                     curr_sess->req->analysers,
                                     curr_sess->req->rex ?
                                     human_time(TICKS_TO_MS(curr_sess->req->rex - now_ms),
@@ -3644,7 +3644,7 @@ static int stats_dump_sess_to_buffer(struct stream_interface *si)
                        chunk_printf(&msg,
                                     " rp[f=%06xh,i=%d,an=%02xh,rx=%s",
                                     curr_sess->rep->flags,
-                                    curr_sess->rep->buf.i,
+                                    curr_sess->rep->buf->i,
                                     curr_sess->rep->analysers,
                                     curr_sess->rep->rex ?
                                     human_time(TICKS_TO_MS(curr_sess->rep->rex - now_ms),
index 1cad8e4cc39869f7979cf7d2473d6345e78385fe..6c80f6b10c4918d1a11a73e6e24964f045cecf5c 100644 (file)
@@ -628,6 +628,7 @@ void init(int argc, char **argv)
 
        /* now we know the buffer size, we can initialize the channels and buffers */
        init_channel();
+       init_buffer();
 
        if (have_appsession)
                appsession_init();
@@ -1112,6 +1113,7 @@ void deinit(void)
        }
 
        pool_destroy2(pool2_session);
+       pool_destroy2(pool2_buffer);
        pool_destroy2(pool2_channel);
        pool_destroy2(pool2_requri);
        pool_destroy2(pool2_task);
index f0306130fb43f9b5cccc320b45fca9f5890e7e12..f3ca6f7e049669faa6804e096964a6e8e824d57a 100644 (file)
@@ -1221,7 +1221,10 @@ static struct session *peer_session_create(struct peer *peer, struct peer_sessio
        if ((s->req = pool_alloc2(pool2_channel)) == NULL)
                goto out_fail_req; /* no memory */
 
-       s->req->buf.size = global.tune.bufsize;
+       if ((s->req->buf = pool_alloc2(pool2_buffer)) == NULL)
+               goto out_fail_req_buf; /* no memory */
+
+       s->req->buf->size = global.tune.bufsize;
        channel_init(s->req);
        s->req->prod = &s->si[0];
        s->req->cons = &s->si[1];
@@ -1244,7 +1247,10 @@ static struct session *peer_session_create(struct peer *peer, struct peer_sessio
        if ((s->rep = pool_alloc2(pool2_channel)) == NULL)
                goto out_fail_rep; /* no memory */
 
-       s->rep->buf.size = global.tune.bufsize;
+       if ((s->rep->buf = pool_alloc2(pool2_buffer)) == NULL)
+               goto out_fail_rep_buf; /* no memory */
+
+       s->rep->buf->size = global.tune.bufsize;
        channel_init(s->rep);
        s->rep->prod = &s->si[1];
        s->rep->cons = &s->si[0];
@@ -1278,7 +1284,11 @@ static struct session *peer_session_create(struct peer *peer, struct peer_sessio
        return s;
 
        /* Error unrolling */
+ out_fail_rep_buf:
+       pool_free2(pool2_channel, s->rep);
  out_fail_rep:
+       pool_free2(pool2_buffer, s->req->buf);
+ out_fail_req_buf:
        pool_free2(pool2_channel, s->req);
  out_fail_req:
        task_free(t);
index 1b52c51ed24731974fd25da8142303ad977fdc98..66dc87d0952fccea34b35f9f8e287bea288bb4bc 100644 (file)
@@ -394,14 +394,14 @@ static void http_silent_debug(int line, struct session *s)
                         "[%04d] req: p=%d(%d) s=%d bf=%08x an=%08x data=%p size=%d l=%d w=%p r=%p o=%p sm=%d fw=%ld tf=%08x\n",
                         line,
                         s->si[0].state, s->si[0].fd, s->txn.req.msg_state, s->req->flags, s->req->analysers,
-                        s->req->buf.data, s->req->buf.size, s->req->l, s->req->w, s->req->r, s->req->buf.p, s->req->buf.o, s->req->to_forward, s->txn.flags);
+                        s->req->buf->data, s->req->buf->size, s->req->l, s->req->w, s->req->r, s->req->buf->p, s->req->buf->o, s->req->to_forward, s->txn.flags);
        write(-1, trash, size);
        size = 0;
        size += snprintf(trash + size, trashlen - size,
                         " %04d  rep: p=%d(%d) s=%d bf=%08x an=%08x data=%p size=%d l=%d w=%p r=%p o=%p sm=%d fw=%ld\n",
                         line,
                         s->si[1].state, s->si[1].fd, s->txn.rsp.msg_state, s->rep->flags, s->rep->analysers,
-                        s->rep->buf.data, s->rep->buf.size, s->rep->l, s->rep->w, s->rep->r, s->rep->buf.p, s->rep->buf.o, s->rep->to_forward);
+                        s->rep->buf->data, s->rep->buf->size, s->rep->l, s->rep->w, s->rep->r, s->rep->buf->p, s->rep->buf->o, s->rep->to_forward);
 
        write(-1, trash, size);
 }
@@ -421,7 +421,7 @@ int http_header_add_tail(struct http_msg *msg, struct hdr_idx *hdr_idx, const ch
        int bytes, len;
 
        len = strlen(text);
-       bytes = buffer_insert_line2(&msg->chn->buf, msg->chn->buf.p + msg->eoh, text, len);
+       bytes = buffer_insert_line2(msg->chn->buf, msg->chn->buf->p + msg->eoh, text, len);
        if (!bytes)
                return -1;
        http_msg_move_end(msg, bytes);
@@ -441,7 +441,7 @@ int http_header_add_tail2(struct http_msg *msg,
 {
        int bytes;
 
-       bytes = buffer_insert_line2(&msg->chn->buf, msg->chn->buf.p + msg->eoh, text, len);
+       bytes = buffer_insert_line2(msg->chn->buf, msg->chn->buf->p + msg->eoh, text, len);
        if (!bytes)
                return -1;
        http_msg_move_end(msg, bytes);
@@ -610,7 +610,7 @@ int http_remove_header2(struct http_msg *msg, struct hdr_idx *idx, struct hdr_ct
        hdr = &idx->v[cur_idx];
        if (sol[ctx->del] == ':' && ctx->val + ctx->vlen + ctx->tws == hdr->len) {
                /* This was the only value of the header, we must now remove it entirely. */
-               delta = buffer_replace2(&msg->chn->buf, sol, sol + hdr->len + hdr->cr + 1, NULL, 0);
+               delta = buffer_replace2(msg->chn->buf, sol, sol + hdr->len + hdr->cr + 1, NULL, 0);
                http_msg_move_end(msg, delta);
                idx->used--;
                hdr->len = 0;   /* unused entry */
@@ -630,7 +630,7 @@ int http_remove_header2(struct http_msg *msg, struct hdr_idx *idx, struct hdr_ct
         */
 
        skip_comma = (ctx->val + ctx->vlen + ctx->tws == hdr->len) ? 0 : 1;
-       delta = buffer_replace2(&msg->chn->buf, sol + ctx->del + skip_comma,
+       delta = buffer_replace2(msg->chn->buf, sol + ctx->del + skip_comma,
                                sol + ctx->val + ctx->vlen + ctx->tws + skip_comma,
                                NULL, 0);
        hdr->len += delta;
@@ -712,7 +712,7 @@ http_get_path(struct http_txn *txn)
 {
        char *ptr, *end;
 
-       ptr = txn->req.chn->buf.p + txn->req.sl.rq.u;
+       ptr = txn->req.chn->buf->p + txn->req.sl.rq.u;
        end = ptr + txn->req.sl.rq.u_l;
 
        if (ptr >= end)
@@ -787,12 +787,12 @@ void perform_http_redirect(struct session *s, struct stream_interface *si)
         * to temporarily rewind the buffer.
         */
        txn = &s->txn;
-       b_rew(&s->req->buf, rewind = s->req->buf.o);
+       b_rew(s->req->buf, rewind = s->req->buf->o);
 
        path = http_get_path(txn);
-       len = buffer_count(&s->req->buf, path, b_ptr(&s->req->buf, txn->req.sl.rq.u + txn->req.sl.rq.u_l));
+       len = buffer_count(s->req->buf, path, b_ptr(s->req->buf, txn->req.sl.rq.u + txn->req.sl.rq.u_l));
 
-       b_adv(&s->req->buf, rewind);
+       b_adv(s->req->buf, rewind);
 
        if (!path)
                return;
@@ -962,7 +962,7 @@ const char *http_parse_stsline(struct http_msg *msg,
                               unsigned int state, const char *ptr, const char *end,
                               unsigned int *ret_ptr, unsigned int *ret_state)
 {
-       const char *msg_start = msg->chn->buf.p;
+       const char *msg_start = msg->chn->buf->p;
 
        switch (state)  {
        case HTTP_MSG_RPVER:
@@ -1072,7 +1072,7 @@ const char *http_parse_reqline(struct http_msg *msg,
                               unsigned int state, const char *ptr, const char *end,
                               unsigned int *ret_ptr, unsigned int *ret_state)
 {
-       const char *msg_start = msg->chn->buf.p;
+       const char *msg_start = msg->chn->buf->p;
 
        switch (state)  {
        case HTTP_MSG_RQMETH:
@@ -1234,7 +1234,7 @@ get_http_auth(struct session *s)
                len = strlen(h);
        }
 
-       if (!http_find_header2(h, len, s->req->buf.p, &txn->hdr_idx, &ctx))
+       if (!http_find_header2(h, len, s->req->buf->p, &txn->hdr_idx, &ctx))
                return 0;
 
        h = ctx.line + ctx.val;
@@ -1293,7 +1293,7 @@ void http_msg_analyzer(struct http_msg *msg, struct hdr_idx *idx)
        struct buffer *buf;
 
        state = msg->msg_state;
-       buf = &msg->chn->buf;
+       buf = msg->chn->buf;
        ptr = buf->p + msg->next;
        end = buf->p + buf->i;
 
@@ -1603,22 +1603,22 @@ static int http_upgrade_v09_to_v10(struct http_txn *txn)
        if (msg->sl.rq.v_l != 0)
                return 1;
 
-       cur_end = msg->chn->buf.p + msg->sl.rq.l;
+       cur_end = msg->chn->buf->p + msg->sl.rq.l;
        delta = 0;
 
        if (msg->sl.rq.u_l == 0) {
                /* if no URI was set, add "/" */
-               delta = buffer_replace2(&msg->chn->buf, cur_end, cur_end, " /", 2);
+               delta = buffer_replace2(msg->chn->buf, cur_end, cur_end, " /", 2);
                cur_end += delta;
                http_msg_move_end(msg, delta);
        }
        /* add HTTP version */
-       delta = buffer_replace2(&msg->chn->buf, cur_end, cur_end, " HTTP/1.0\r\n", 11);
+       delta = buffer_replace2(msg->chn->buf, cur_end, cur_end, " HTTP/1.0\r\n", 11);
        http_msg_move_end(msg, delta);
        cur_end += delta;
        cur_end = (char *)http_parse_reqline(msg,
                                             HTTP_MSG_RQMETH,
-                                            msg->chn->buf.p, cur_end + 1,
+                                            msg->chn->buf->p, cur_end + 1,
                                             NULL, NULL);
        if (unlikely(!cur_end))
                return 0;
@@ -1656,7 +1656,7 @@ void http_parse_connection_header(struct http_txn *txn, struct http_msg *msg, in
 
        ctx.idx = 0;
        txn->flags &= ~(TX_CON_KAL_SET|TX_CON_CLO_SET);
-       while (http_find_header2(hdr_val, hdr_len, msg->chn->buf.p, &txn->hdr_idx, &ctx)) {
+       while (http_find_header2(hdr_val, hdr_len, msg->chn->buf->p, &txn->hdr_idx, &ctx)) {
                if (ctx.vlen >= 10 && word_match(ctx.line + ctx.val, ctx.vlen, "keep-alive", 10)) {
                        txn->flags |= TX_HDR_CONN_KAL;
                        if (to_del & 2)
@@ -1697,7 +1697,7 @@ void http_change_connection_header(struct http_txn *txn, struct http_msg *msg, i
        }
 
        txn->flags &= ~(TX_CON_CLO_SET | TX_CON_KAL_SET);
-       while (http_find_header2(hdr_val, hdr_len, msg->chn->buf.p, &txn->hdr_idx, &ctx)) {
+       while (http_find_header2(hdr_val, hdr_len, msg->chn->buf->p, &txn->hdr_idx, &ctx)) {
                if (ctx.vlen >= 10 && word_match(ctx.line + ctx.val, ctx.vlen, "keep-alive", 10)) {
                        if (wanted & TX_CON_KAL_SET)
                                txn->flags |= TX_CON_KAL_SET;
@@ -1747,7 +1747,7 @@ void http_change_connection_header(struct http_txn *txn, struct http_msg *msg, i
  */
 int http_parse_chunk_size(struct http_msg *msg)
 {
-       const struct buffer *buf = &msg->chn->buf;
+       const struct buffer *buf = msg->chn->buf;
        const char *ptr = b_ptr(buf, msg->next);
        const char *ptr_old = ptr;
        const char *end = buf->data + buf->size;
@@ -1857,7 +1857,7 @@ int http_parse_chunk_size(struct http_msg *msg)
  */
 int http_forward_trailers(struct http_msg *msg)
 {
-       const struct buffer *buf = &msg->chn->buf;
+       const struct buffer *buf = msg->chn->buf;
 
        /* we have msg->next which points to next line. Look for CRLF. */
        while (1) {
@@ -1931,7 +1931,7 @@ int http_forward_trailers(struct http_msg *msg)
  */
 int http_skip_chunk_crlf(struct http_msg *msg)
 {
-       const struct buffer *buf = &msg->chn->buf;
+       const struct buffer *buf = msg->chn->buf;
        const char *ptr;
        int bytes;
 
@@ -1984,9 +1984,9 @@ int http_wait_for_request(struct session *s, struct channel *req, int an_bit)
         * For the parsing, we use a 28 states FSM.
         *
         * Here is the information we currently have :
-        *   req->buf.p             = beginning of request
-        *   req->buf.p + msg->eoh  = end of processed headers / start of current one
-        *   req->buf.p + req->buf.i    = end of input data
+        *   req->buf->p             = beginning of request
+        *   req->buf->p + msg->eoh  = end of processed headers / start of current one
+        *   req->buf->p + req->buf->i    = end of input data
         *   msg->eol           = end of current header or line (LF or CRLF)
         *   msg->next          = first non-visited byte
         *
@@ -2008,7 +2008,7 @@ int http_wait_for_request(struct session *s, struct channel *req, int an_bit)
                req,
                req->rex, req->wex,
                req->flags,
-               req->buf.i,
+               req->buf->i,
                req->analysers);
 
        /* we're speaking HTTP here, so let's speak HTTP to the client */
@@ -2019,12 +2019,12 @@ int http_wait_for_request(struct session *s, struct channel *req, int an_bit)
         * protected area is affected, because we may have to move processed
         * data later, which is much more complicated.
         */
-       if (buffer_not_empty(&req->buf) && msg->msg_state < HTTP_MSG_ERROR) {
+       if (buffer_not_empty(req->buf) && msg->msg_state < HTTP_MSG_ERROR) {
                if ((txn->flags & TX_NOT_FIRST) &&
                    unlikely(channel_full(req) ||
-                            bi_end(&req->buf) < b_ptr(&req->buf, msg->next) ||
-                            bi_end(&req->buf) > req->buf.data + req->buf.size - global.tune.maxrewrite)) {
-                       if (req->buf.o) {
+                            bi_end(req->buf) < b_ptr(req->buf, msg->next) ||
+                            bi_end(req->buf) > req->buf->data + req->buf->size - global.tune.maxrewrite)) {
+                       if (req->buf->o) {
                                if (req->flags & (CF_SHUTW|CF_SHUTW_NOW|CF_WRITE_ERROR|CF_WRITE_TIMEOUT))
                                        goto failed_keep_alive;
                                /* some data has still not left the buffer, wake us once that's done */
@@ -2032,9 +2032,9 @@ int http_wait_for_request(struct session *s, struct channel *req, int an_bit)
                                req->flags |= CF_READ_DONTWAIT; /* try to get back here ASAP */
                                return 0;
                        }
-                       if (bi_end(&req->buf) < b_ptr(&req->buf, msg->next) ||
-                           bi_end(&req->buf) > req->buf.data + req->buf.size - global.tune.maxrewrite)
-                               buffer_slow_realign(&msg->chn->buf);
+                       if (bi_end(req->buf) < b_ptr(req->buf, msg->next) ||
+                           bi_end(req->buf) > req->buf->data + req->buf->size - global.tune.maxrewrite)
+                               buffer_slow_realign(msg->chn->buf);
                }
 
                /* Note that we have the same problem with the response ; we
@@ -2046,9 +2046,9 @@ int http_wait_for_request(struct session *s, struct channel *req, int an_bit)
                 */
                if ((txn->flags & TX_NOT_FIRST) &&
                    unlikely(channel_full(s->rep) ||
-                            bi_end(&s->rep->buf) < b_ptr(&s->rep->buf, txn->rsp.next) ||
-                            bi_end(&s->rep->buf) > s->rep->buf.data + s->rep->buf.size - global.tune.maxrewrite)) {
-                       if (s->rep->buf.o) {
+                            bi_end(s->rep->buf) < b_ptr(s->rep->buf, txn->rsp.next) ||
+                            bi_end(s->rep->buf) > s->rep->buf->data + s->rep->buf->size - global.tune.maxrewrite)) {
+                       if (s->rep->buf->o) {
                                if (s->rep->flags & (CF_SHUTW|CF_SHUTW_NOW|CF_WRITE_ERROR|CF_WRITE_TIMEOUT))
                                        goto failed_keep_alive;
                                /* don't let a connection request be initiated */
@@ -2059,7 +2059,7 @@ int http_wait_for_request(struct session *s, struct channel *req, int an_bit)
                        }
                }
 
-               if (likely(msg->next < req->buf.i)) /* some unparsed data are available */
+               if (likely(msg->next < req->buf->i)) /* some unparsed data are available */
                        http_msg_analyzer(msg, &txn->hdr_idx);
        }
 
@@ -2069,12 +2069,12 @@ int http_wait_for_request(struct session *s, struct channel *req, int an_bit)
                     (msg->msg_state >= HTTP_MSG_BODY || msg->msg_state == HTTP_MSG_ERROR))) {
                char *eol, *sol;
 
-               sol = req->buf.p;
+               sol = req->buf->p;
                /* this is a bit complex : in case of error on the request line,
                 * we know that rq.l is still zero, so we display only the part
                 * up to the end of the line (truncated by debug_hdr).
                 */
-               eol = sol + (msg->sl.rq.l ? msg->sl.rq.l : req->buf.i);
+               eol = sol + (msg->sl.rq.l ? msg->sl.rq.l : req->buf->i);
                debug_hdr("clireq", s, sol, eol);
 
                sol += hdr_idx_first_pos(&txn->hdr_idx);
@@ -2121,7 +2121,7 @@ int http_wait_for_request(struct session *s, struct channel *req, int an_bit)
                 *    later, so the session will never terminate. We
                 *    must terminate it now.
                 */
-               if (unlikely(buffer_full(&req->buf, global.tune.maxrewrite))) {
+               if (unlikely(buffer_full(req->buf, global.tune.maxrewrite))) {
                        /* FIXME: check if URI is set and return Status
                         * 414 Request URI too long instead.
                         */
@@ -2129,7 +2129,7 @@ int http_wait_for_request(struct session *s, struct channel *req, int an_bit)
                        session_inc_http_err_ctr(s);
                        proxy_inc_fe_req_ctr(s->fe);
                        if (msg->err_pos < 0)
-                               msg->err_pos = req->buf.i;
+                               msg->err_pos = req->buf->i;
                        goto return_bad_req;
                }
 
@@ -2221,7 +2221,7 @@ int http_wait_for_request(struct session *s, struct channel *req, int an_bit)
                req->flags |= CF_READ_DONTWAIT; /* try to get back here ASAP */
                s->rep->flags &= ~CF_EXPECT_MORE; /* speed up sending a previous response */
 #ifdef TCP_QUICKACK
-               if (s->listener->options & LI_O_NOQUICKACK && req->buf.i) {
+               if (s->listener->options & LI_O_NOQUICKACK && req->buf->i) {
                        /* We need more data, we have to re-enable quick-ack in case we
                         * previously disabled it, otherwise we might cause the client
                         * to delay next data.
@@ -2268,7 +2268,7 @@ int http_wait_for_request(struct session *s, struct channel *req, int an_bit)
 
        /* OK now we have a complete HTTP request with indexed headers. Let's
         * complete the request parsing by setting a few fields we will need
-        * later. At this point, we have the last CRLF at req->buf.data + msg->eoh.
+        * later. At this point, we have the last CRLF at req->buf->data + msg->eoh.
         * If the request is in HTTP/0.9 form, the rule is still true, and eoh
         * points to the CRLF of the request line. msg->next points to the first
         * byte after the last LF. msg->sov points to the first byte of data.
@@ -2295,7 +2295,7 @@ int http_wait_for_request(struct session *s, struct channel *req, int an_bit)
        /*
         * 1: identify the method
         */
-       txn->meth = find_http_meth(req->buf.p, msg->sl.rq.m_l);
+       txn->meth = find_http_meth(req->buf->p, msg->sl.rq.m_l);
 
        /* we can make use of server redirect on GET and HEAD */
        if (txn->meth == HTTP_METH_GET || txn->meth == HTTP_METH_HEAD)
@@ -2308,7 +2308,7 @@ int http_wait_for_request(struct session *s, struct channel *req, int an_bit)
         */
        if (unlikely((s->fe->monitor_uri_len != 0) &&
                     (s->fe->monitor_uri_len == msg->sl.rq.u_l) &&
-                    !memcmp(req->buf.p + msg->sl.rq.u,
+                    !memcmp(req->buf->p + msg->sl.rq.u,
                             s->fe->monitor_uri,
                             s->fe->monitor_uri_len))) {
                /*
@@ -2353,7 +2353,7 @@ int http_wait_for_request(struct session *s, struct channel *req, int an_bit)
 
                        if (urilen >= REQURI_LEN)
                                urilen = REQURI_LEN - 1;
-                       memcpy(txn->uri, req->buf.p, urilen);
+                       memcpy(txn->uri, req->buf->p, urilen);
                        txn->uri[urilen] = 0;
 
                        if (!(s->logs.logwait &= ~LW_REQ))
@@ -2373,9 +2373,9 @@ int http_wait_for_request(struct session *s, struct channel *req, int an_bit)
 
        /* ... and check if the request is HTTP/1.1 or above */
        if ((msg->sl.rq.v_l == 8) &&
-           ((req->buf.p[msg->sl.rq.v + 5] > '1') ||
-            ((req->buf.p[msg->sl.rq.v + 5] == '1') &&
-             (req->buf.p[msg->sl.rq.v + 7] >= '1'))))
+           ((req->buf->p[msg->sl.rq.v + 5] > '1') ||
+            ((req->buf->p[msg->sl.rq.v + 5] == '1') &&
+             (req->buf->p[msg->sl.rq.v + 7] >= '1'))))
                msg->flags |= HTTP_MSGF_VER_11;
 
        /* "connection" has not been parsed yet */
@@ -2391,7 +2391,7 @@ int http_wait_for_request(struct session *s, struct channel *req, int an_bit)
         * CONNECT ip:port.
         */
        if ((s->fe->options2 & PR_O2_USE_PXHDR) &&
-           req->buf.p[msg->sl.rq.u] != '/' && req->buf.p[msg->sl.rq.u] != '*')
+           req->buf->p[msg->sl.rq.u] != '/' && req->buf->p[msg->sl.rq.u] != '*')
                txn->flags |= TX_USE_PX_CONN;
 
        /* transfer length unknown*/
@@ -2399,7 +2399,7 @@ int http_wait_for_request(struct session *s, struct channel *req, int an_bit)
 
        /* 5: we may need to capture headers */
        if (unlikely((s->logs.logwait & LW_REQHDR) && txn->req.cap))
-               capture_headers(req->buf.p, &txn->hdr_idx,
+               capture_headers(req->buf->p, &txn->hdr_idx,
                                txn->req.cap, s->fe->req_cap);
 
        /* 6: determine the transfer-length.
@@ -2444,7 +2444,7 @@ int http_wait_for_request(struct session *s, struct channel *req, int an_bit)
        ctx.idx = 0;
        /* set TE_CHNK and XFER_LEN only if "chunked" is seen last */
        while ((msg->flags & HTTP_MSGF_VER_11) &&
-              http_find_header2("Transfer-Encoding", 17, req->buf.p, &txn->hdr_idx, &ctx)) {
+              http_find_header2("Transfer-Encoding", 17, req->buf->p, &txn->hdr_idx, &ctx)) {
                if (ctx.vlen == 7 && strncasecmp(ctx.line + ctx.val, "chunked", 7) == 0)
                        msg->flags |= (HTTP_MSGF_TE_CHNK | HTTP_MSGF_XFER_LEN);
                else if (msg->flags & HTTP_MSGF_TE_CHNK) {
@@ -2457,26 +2457,26 @@ int http_wait_for_request(struct session *s, struct channel *req, int an_bit)
 
        ctx.idx = 0;
        while (!(msg->flags & HTTP_MSGF_TE_CHNK) && !use_close_only &&
-              http_find_header2("Content-Length", 14, req->buf.p, &txn->hdr_idx, &ctx)) {
+              http_find_header2("Content-Length", 14, req->buf->p, &txn->hdr_idx, &ctx)) {
                signed long long cl;
 
                if (!ctx.vlen) {
-                       msg->err_pos = ctx.line + ctx.val - req->buf.p;
+                       msg->err_pos = ctx.line + ctx.val - req->buf->p;
                        goto return_bad_req;
                }
 
                if (strl2llrc(ctx.line + ctx.val, ctx.vlen, &cl)) {
-                       msg->err_pos = ctx.line + ctx.val - req->buf.p;
+                       msg->err_pos = ctx.line + ctx.val - req->buf->p;
                        goto return_bad_req; /* parse failure */
                }
 
                if (cl < 0) {
-                       msg->err_pos = ctx.line + ctx.val - req->buf.p;
+                       msg->err_pos = ctx.line + ctx.val - req->buf->p;
                        goto return_bad_req;
                }
 
                if ((msg->flags & HTTP_MSGF_CNT_LEN) && (msg->chunk_len != cl)) {
-                       msg->err_pos = ctx.line + ctx.val - req->buf.p;
+                       msg->err_pos = ctx.line + ctx.val - req->buf->p;
                        goto return_bad_req; /* already specified, was different */
                }
 
@@ -2541,17 +2541,17 @@ int http_process_req_stat_post(struct stream_interface *si, struct http_txn *txn
        char *st_cur_param = NULL;
        char *st_next_param = NULL;
 
-       first_param = req->buf.p + txn->req.eoh + 2;
+       first_param = req->buf->p + txn->req.eoh + 2;
        end_params  = first_param + txn->req.body_len;
 
        cur_param = next_param = end_params;
 
-       if (end_params >= req->buf.data + req->buf.size - global.tune.maxrewrite) {
+       if (end_params >= req->buf->data + req->buf->size - global.tune.maxrewrite) {
                /* Prevent buffer overflow */
                si->applet.ctx.stats.st_code = STAT_STATUS_EXCD;
                return 1;
        }
-       else if (end_params > req->buf.p + req->buf.i) {
+       else if (end_params > req->buf->p + req->buf->i) {
                /* we need more data */
                si->applet.ctx.stats.st_code = STAT_STATUS_NONE;
                return 0;
@@ -2803,7 +2803,7 @@ int http_process_req_common(struct session *s, struct channel *req, int an_bit,
                req,
                req->rex, req->wex,
                req->flags,
-               req->buf.i,
+               req->buf->i,
                req->analysers);
 
        /* first check whether we have some ACLs set to block this request */
@@ -3012,7 +3012,7 @@ int http_process_req_common(struct session *s, struct channel *req, int an_bit,
                                                struct hdr_ctx ctx;
                                                ctx.idx = 0;
                                                /* Expect is allowed in 1.1, look for it */
-                                               if (http_find_header2("Expect", 6, req->buf.p, &txn->hdr_idx, &ctx) &&
+                                               if (http_find_header2("Expect", 6, req->buf->p, &txn->hdr_idx, &ctx) &&
                                                    unlikely(ctx.vlen == 12 && strncasecmp(ctx.line+ctx.val, "100-continue", 12) == 0)) {
                                                        bo_inject(s->rep, http_100_chunk.str, http_100_chunk.len);
                                                }
@@ -3088,7 +3088,7 @@ int http_process_req_common(struct session *s, struct channel *req, int an_bit,
                                host = "";
                                hostlen = 0;
                                ctx.idx = 0;
-                               if (http_find_header2("Host", 4, txn->req.chn->buf.p + txn->req.sol, &txn->hdr_idx, &ctx)) {
+                               if (http_find_header2("Host", 4, txn->req.chn->buf->p + txn->req.sol, &txn->hdr_idx, &ctx)) {
                                        host = ctx.line + ctx.val;
                                        hostlen = ctx.vlen;
                                }
@@ -3096,7 +3096,7 @@ int http_process_req_common(struct session *s, struct channel *req, int an_bit,
                                path = http_get_path(txn);
                                /* build message using path */
                                if (path) {
-                                       pathlen = txn->req.sl.rq.u_l + (req->buf.p + txn->req.sl.rq.u) - path;
+                                       pathlen = txn->req.sl.rq.u_l + (req->buf->p + txn->req.sl.rq.u) - path;
                                        if (rule->flags & REDIRECT_FLAG_DROP_QS) {
                                                int qs = 0;
                                                while (qs < pathlen) {
@@ -3150,7 +3150,7 @@ int http_process_req_common(struct session *s, struct channel *req, int an_bit,
                                path = http_get_path(txn);
                                /* build message using path */
                                if (path) {
-                                       pathlen = txn->req.sl.rq.u_l + (req->buf.p + txn->req.sl.rq.u) - path;
+                                       pathlen = txn->req.sl.rq.u_l + (req->buf->p + txn->req.sl.rq.u) - path;
                                        if (rule->flags & REDIRECT_FLAG_DROP_QS) {
                                                int qs = 0;
                                                while (qs < pathlen) {
@@ -3241,7 +3241,7 @@ int http_process_req_common(struct session *s, struct channel *req, int an_bit,
                                rdr.len += 4;
                                bo_inject(req->prod->ob, rdr.str, rdr.len);
                                /* "eat" the request */
-                               bi_fast_delete(&req->buf, msg->sov);
+                               bi_fast_delete(req->buf, msg->sov);
                                msg->sov = 0;
                                req->analysers = AN_REQ_HTTP_XFER_BODY;
                                s->rep->analysers = AN_RES_HTTP_XFER_BODY;
@@ -3325,7 +3325,7 @@ int http_process_request(struct session *s, struct channel *req, int an_bit)
                req,
                req->rex, req->wex,
                req->flags,
-               req->buf.i,
+               req->buf->i,
                req->analysers);
 
        /*
@@ -3340,7 +3340,7 @@ int http_process_request(struct session *s, struct channel *req, int an_bit)
         * parsing incoming request.
         */
        if ((s->be->options & PR_O_HTTP_PROXY) && !(s->flags & SN_ADDR_SET)) {
-               url2sa(req->buf.p + msg->sl.rq.u, msg->sl.rq.u_l, &s->req->cons->conn.addr.to);
+               url2sa(req->buf->p + msg->sl.rq.u, msg->sl.rq.u_l, &s->req->cons->conn.addr.to);
        }
 
        /*
@@ -3360,7 +3360,7 @@ int http_process_request(struct session *s, struct channel *req, int an_bit)
 
        /* It needs to look into the URI unless persistence must be ignored */
        if ((txn->sessid == NULL) && s->be->appsession_name && !(s->flags & SN_IGNORE_PRST)) {
-               get_srv_from_appsession(s, req->buf.p + msg->sl.rq.u, msg->sl.rq.u_l);
+               get_srv_from_appsession(s, req->buf->p + msg->sl.rq.u, msg->sl.rq.u_l);
        }
 
        /* add unique-id if "header-unique-id" is specified */
@@ -3385,7 +3385,7 @@ int http_process_request(struct session *s, struct channel *req, int an_bit)
                if (!((s->fe->options | s->be->options) & PR_O_FF_ALWAYS) &&
                        http_find_header2(s->be->fwdfor_hdr_len ? s->be->fwdfor_hdr_name : s->fe->fwdfor_hdr_name,
                                          s->be->fwdfor_hdr_len ? s->be->fwdfor_hdr_len : s->fe->fwdfor_hdr_len,
-                                         req->buf.p, &txn->hdr_idx, &ctx)) {
+                                         req->buf->p, &txn->hdr_idx, &ctx)) {
                        /* The header is set to be added only if none is present
                         * and we found it, so don't do anything.
                         */
@@ -3539,7 +3539,7 @@ int http_process_request(struct session *s, struct channel *req, int an_bit)
                 */
                if ((s->listener->options & LI_O_NOQUICKACK) &&
                    ((msg->flags & HTTP_MSGF_TE_CHNK) ||
-                    (msg->body_len > req->buf.i - txn->req.eoh - 2)))
+                    (msg->body_len > req->buf->i - txn->req.eoh - 2)))
                        setsockopt(si_fd(&s->si[0]), IPPROTO_TCP, TCP_QUICKACK, &one, sizeof(one));
 #endif
        }
@@ -3657,7 +3657,7 @@ int http_process_request_body(struct session *s, struct channel *req, int an_bit
                        struct hdr_ctx ctx;
                        ctx.idx = 0;
                        /* Expect is allowed in 1.1, look for it */
-                       if (http_find_header2("Expect", 6, req->buf.p, &txn->hdr_idx, &ctx) &&
+                       if (http_find_header2("Expect", 6, req->buf->p, &txn->hdr_idx, &ctx) &&
                            unlikely(ctx.vlen == 12 && strncasecmp(ctx.line+ctx.val, "100-continue", 12) == 0)) {
                                bo_inject(s->rep, http_100_chunk.str, http_100_chunk.len);
                        }
@@ -3667,7 +3667,7 @@ int http_process_request_body(struct session *s, struct channel *req, int an_bit
 
        if (msg->msg_state < HTTP_MSG_CHUNK_SIZE) {
                /* we have msg->sov which points to the first byte of message body.
-                * req->buf.p still points to the beginning of the message and msg->sol
+                * req->buf->p still points to the beginning of the message and msg->sol
                 * is still null. We must save the body in msg->next because it
                 * survives buffer re-alignments.
                 */
@@ -3702,12 +3702,12 @@ int http_process_request_body(struct session *s, struct channel *req, int an_bit
        if (msg->body_len < limit)
                limit = msg->body_len;
 
-       if (req->buf.i - msg->sov >= limit)    /* we have enough bytes now */
+       if (req->buf->i - msg->sov >= limit)    /* we have enough bytes now */
                goto http_end;
 
  missing_data:
        /* we get here if we need to wait for more data */
-       if (buffer_full(&req->buf, global.tune.maxrewrite)) {
+       if (buffer_full(req->buf, global.tune.maxrewrite)) {
                session_inc_http_err_ctr(s);
                goto return_bad_req;
        }
@@ -3724,7 +3724,7 @@ int http_process_request_body(struct session *s, struct channel *req, int an_bit
        }
 
        /* we get here if we need to wait for more data */
-       if (!(req->flags & (CF_SHUTR | CF_READ_ERROR)) && !buffer_full(&req->buf, global.tune.maxrewrite)) {
+       if (!(req->flags & (CF_SHUTR | CF_READ_ERROR)) && !buffer_full(req->buf, global.tune.maxrewrite)) {
                /* Not enough data. We'll re-use the http-request
                 * timeout here. Ideally, we should set the timeout
                 * relative to the accept() date. We just set the
@@ -3779,14 +3779,14 @@ int http_send_name_header(struct http_txn *txn, struct proxy* be, const char* sr
 
        ctx.idx = 0;
 
-       old_o = chn->buf.o;
+       old_o = chn->buf->o;
        if (old_o) {
                /* The request was already skipped, let's restore it */
-               b_rew(&chn->buf, old_o);
+               b_rew(chn->buf, old_o);
        }
 
-       old_i = chn->buf.i;
-       while (http_find_header2(hdr_name, hdr_name_len, txn->req.chn->buf.p, &txn->hdr_idx, &ctx)) {
+       old_i = chn->buf->i;
+       while (http_find_header2(hdr_name, hdr_name_len, txn->req.chn->buf->p, &txn->hdr_idx, &ctx)) {
                /* remove any existing values from the header */
                http_remove_header2(&txn->req, &txn->hdr_idx, &ctx);
        }
@@ -3805,7 +3805,7 @@ int http_send_name_header(struct http_txn *txn, struct proxy* be, const char* sr
                 * data to be forwarded in order to take into account the size
                 * variations.
                 */
-               b_adv(&chn->buf, old_o + chn->buf.i - old_i);
+               b_adv(chn->buf, old_o + chn->buf->i - old_i);
        }
 
        return 0;
@@ -3855,8 +3855,8 @@ void http_end_txn_clean_session(struct session *s)
        }
 
        /* don't count other requests' data */
-       s->logs.bytes_in  -= s->req->buf.i;
-       s->logs.bytes_out -= s->rep->buf.i;
+       s->logs.bytes_in  -= s->req->buf->i;
+       s->logs.bytes_out -= s->rep->buf->i;
 
        /* let's do a final log if we need it */
        if (s->logs.logwait &&
@@ -3875,8 +3875,8 @@ void http_end_txn_clean_session(struct session *s)
        s->logs.prx_queue_size = 0;  /* we get the number of pending conns before us */
        s->logs.srv_queue_size = 0; /* we will get this number soon */
 
-       s->logs.bytes_in = s->req->total = s->req->buf.i;
-       s->logs.bytes_out = s->rep->total = s->rep->buf.i;
+       s->logs.bytes_in = s->req->total = s->req->buf->i;
+       s->logs.bytes_out = s->rep->total = s->rep->buf->i;
 
        if (s->pend_pos)
                pendconn_free(s->pend_pos);
@@ -3922,10 +3922,10 @@ void http_end_txn_clean_session(struct session *s)
         * because the request will wait for it to flush a little
         * bit before proceeding.
         */
-       if (s->req->buf.i) {
-               if (s->rep->buf.o &&
-                   !buffer_full(&s->rep->buf, global.tune.maxrewrite) &&
-                   bi_end(&s->rep->buf) <= s->rep->buf.data + s->rep->buf.size - global.tune.maxrewrite)
+       if (s->req->buf->i) {
+               if (s->rep->buf->o &&
+                   !buffer_full(s->rep->buf, global.tune.maxrewrite) &&
+                   bi_end(s->rep->buf) <= s->rep->buf->data + s->rep->buf->size - global.tune.maxrewrite)
                        s->rep->flags |= CF_EXPECT_MORE;
        }
 
@@ -4281,7 +4281,7 @@ int http_request_forward_body(struct session *s, struct channel *req, int an_bit
                return 0;
 
        if ((req->flags & (CF_READ_ERROR|CF_READ_TIMEOUT|CF_WRITE_ERROR|CF_WRITE_TIMEOUT)) ||
-           ((req->flags & CF_SHUTW) && (req->to_forward || req->buf.o))) {
+           ((req->flags & CF_SHUTW) && (req->to_forward || req->buf->o))) {
                /* Output closed while we were sending data. We must abort and
                 * wake the other side up.
                 */
@@ -4301,7 +4301,7 @@ int http_request_forward_body(struct session *s, struct channel *req, int an_bit
 
        if (msg->msg_state < HTTP_MSG_CHUNK_SIZE) {
                /* we have msg->sov which points to the first byte of message body.
-                * req->buf.p still points to the beginning of the message and msg->sol
+                * req->buf->p still points to the beginning of the message and msg->sol
                 * is still null. We must save the body in msg->next because it
                 * survives buffer re-alignments.
                 */
@@ -4553,7 +4553,7 @@ int http_wait_for_response(struct session *s, struct channel *rep, int an_bit)
                rep,
                rep->rex, rep->wex,
                rep->flags,
-               rep->buf.i,
+               rep->buf->i,
                rep->analysers);
 
        /*
@@ -4565,9 +4565,9 @@ int http_wait_for_response(struct session *s, struct channel *rep, int an_bit)
         * For the parsing, we use a 28 states FSM.
         *
         * Here is the information we currently have :
-        *   rep->buf.p             = beginning of response
-        *   rep->buf.p + msg->eoh  = end of processed headers / start of current one
-        *   rep->buf.p + rep->buf.i    = end of input data
+        *   rep->buf->p             = beginning of response
+        *   rep->buf->p + msg->eoh  = end of processed headers / start of current one
+        *   rep->buf->p + rep->buf->i    = end of input data
         *   msg->eol           = end of current header or line (LF or CRLF)
         *   msg->next          = first non-visited byte
         */
@@ -4577,11 +4577,11 @@ int http_wait_for_response(struct session *s, struct channel *rep, int an_bit)
         * protected area is affected, because we may have to move processed
         * data later, which is much more complicated.
         */
-       if (buffer_not_empty(&rep->buf) && msg->msg_state < HTTP_MSG_ERROR) {
+       if (buffer_not_empty(rep->buf) && msg->msg_state < HTTP_MSG_ERROR) {
                if (unlikely(channel_full(rep) ||
-                            bi_end(&rep->buf) < b_ptr(&rep->buf, msg->next) ||
-                            bi_end(&rep->buf) > rep->buf.data + rep->buf.size - global.tune.maxrewrite)) {
-                       if (rep->buf.o) {
+                            bi_end(rep->buf) < b_ptr(rep->buf, msg->next) ||
+                            bi_end(rep->buf) > rep->buf->data + rep->buf->size - global.tune.maxrewrite)) {
+                       if (rep->buf->o) {
                                /* some data has still not left the buffer, wake us once that's done */
                                if (rep->flags & (CF_SHUTW|CF_SHUTW_NOW|CF_WRITE_ERROR|CF_WRITE_TIMEOUT))
                                        goto abort_response;
@@ -4589,11 +4589,11 @@ int http_wait_for_response(struct session *s, struct channel *rep, int an_bit)
                                rep->flags |= CF_READ_DONTWAIT; /* try to get back here ASAP */
                                return 0;
                        }
-                       if (rep->buf.i <= rep->buf.size - global.tune.maxrewrite)
-                               buffer_slow_realign(&msg->chn->buf);
+                       if (rep->buf->i <= rep->buf->size - global.tune.maxrewrite)
+                               buffer_slow_realign(msg->chn->buf);
                }
 
-               if (likely(msg->next < rep->buf.i))
+               if (likely(msg->next < rep->buf->i))
                        http_msg_analyzer(msg, &txn->hdr_idx);
        }
 
@@ -4603,8 +4603,8 @@ int http_wait_for_response(struct session *s, struct channel *rep, int an_bit)
                     (msg->msg_state >= HTTP_MSG_BODY || msg->msg_state == HTTP_MSG_ERROR))) {
                char *eol, *sol;
 
-               sol = rep->buf.p;
-               eol = sol + (msg->sl.st.l ? msg->sl.st.l : rep->buf.i);
+               sol = rep->buf->p;
+               eol = sol + (msg->sl.st.l ? msg->sl.st.l : rep->buf->i);
                debug_hdr("srvrep", s, sol, eol);
 
                sol += hdr_idx_first_pos(&txn->hdr_idx);
@@ -4663,9 +4663,9 @@ int http_wait_for_response(struct session *s, struct channel *rep, int an_bit)
                }
 
                /* too large response does not fit in buffer. */
-               else if (buffer_full(&rep->buf, global.tune.maxrewrite)) {
+               else if (buffer_full(rep->buf, global.tune.maxrewrite)) {
                        if (msg->err_pos < 0)
-                               msg->err_pos = rep->buf.i;
+                               msg->err_pos = rep->buf->i;
                        goto hdr_response_bad;
                }
 
@@ -4777,7 +4777,7 @@ int http_wait_for_response(struct session *s, struct channel *rep, int an_bit)
        /*
         * 1: get the status code
         */
-       n = rep->buf.p[msg->sl.st.c] - '0';
+       n = rep->buf->p[msg->sl.st.c] - '0';
        if (n < 1 || n > 5)
                n = 0;
        /* when the client triggers a 4xx from the server, it's most often due
@@ -4793,8 +4793,8 @@ int http_wait_for_response(struct session *s, struct channel *rep, int an_bit)
 
        /* check if the response is HTTP/1.1 or above */
        if ((msg->sl.st.v_l == 8) &&
-           ((rep->buf.p[5] > '1') ||
-            ((rep->buf.p[5] == '1') && (rep->buf.p[7] >= '1'))))
+           ((rep->buf->p[5] > '1') ||
+            ((rep->buf->p[5] == '1') && (rep->buf->p[7] >= '1'))))
                msg->flags |= HTTP_MSGF_VER_11;
 
        /* "connection" has not been parsed yet */
@@ -4803,7 +4803,7 @@ int http_wait_for_response(struct session *s, struct channel *rep, int an_bit)
        /* transfer length unknown*/
        msg->flags &= ~HTTP_MSGF_XFER_LEN;
 
-       txn->status = strl2ui(rep->buf.p + msg->sl.st.c, msg->sl.st.c_l);
+       txn->status = strl2ui(rep->buf->p + msg->sl.st.c, msg->sl.st.c_l);
 
        /* Adjust server's health based on status code. Note: status codes 501
         * and 505 are triggered on demand by client request, so we must not
@@ -4851,7 +4851,7 @@ int http_wait_for_response(struct session *s, struct channel *rep, int an_bit)
         */
        s->logs.logwait &= ~LW_RESP;
        if (unlikely((s->logs.logwait & LW_RSPHDR) && txn->rsp.cap))
-               capture_headers(rep->buf.p, &txn->hdr_idx,
+               capture_headers(rep->buf->p, &txn->hdr_idx,
                                txn->rsp.cap, s->fe->rsp_cap);
 
        /* 4: determine the transfer-length.
@@ -4909,7 +4909,7 @@ int http_wait_for_response(struct session *s, struct channel *rep, int an_bit)
        use_close_only = 0;
        ctx.idx = 0;
        while ((msg->flags & HTTP_MSGF_VER_11) &&
-              http_find_header2("Transfer-Encoding", 17, rep->buf.p, &txn->hdr_idx, &ctx)) {
+              http_find_header2("Transfer-Encoding", 17, rep->buf->p, &txn->hdr_idx, &ctx)) {
                if (ctx.vlen == 7 && strncasecmp(ctx.line + ctx.val, "chunked", 7) == 0)
                        msg->flags |= (HTTP_MSGF_TE_CHNK | HTTP_MSGF_XFER_LEN);
                else if (msg->flags & HTTP_MSGF_TE_CHNK) {
@@ -4923,26 +4923,26 @@ int http_wait_for_response(struct session *s, struct channel *rep, int an_bit)
        /* FIXME: below we should remove the content-length header(s) in case of chunked encoding */
        ctx.idx = 0;
        while (!(msg->flags & HTTP_MSGF_TE_CHNK) && !use_close_only &&
-              http_find_header2("Content-Length", 14, rep->buf.p, &txn->hdr_idx, &ctx)) {
+              http_find_header2("Content-Length", 14, rep->buf->p, &txn->hdr_idx, &ctx)) {
                signed long long cl;
 
                if (!ctx.vlen) {
-                       msg->err_pos = ctx.line + ctx.val - rep->buf.p;
+                       msg->err_pos = ctx.line + ctx.val - rep->buf->p;
                        goto hdr_response_bad;
                }
 
                if (strl2llrc(ctx.line + ctx.val, ctx.vlen, &cl)) {
-                       msg->err_pos = ctx.line + ctx.val - rep->buf.p;
+                       msg->err_pos = ctx.line + ctx.val - rep->buf->p;
                        goto hdr_response_bad; /* parse failure */
                }
 
                if (cl < 0) {
-                       msg->err_pos = ctx.line + ctx.val - rep->buf.p;
+                       msg->err_pos = ctx.line + ctx.val - rep->buf->p;
                        goto hdr_response_bad;
                }
 
                if ((msg->flags & HTTP_MSGF_CNT_LEN) && (msg->chunk_len != cl)) {
-                       msg->err_pos = ctx.line + ctx.val - rep->buf.p;
+                       msg->err_pos = ctx.line + ctx.val - rep->buf->p;
                        goto hdr_response_bad; /* already specified, was different */
                }
 
@@ -4980,7 +4980,7 @@ int http_process_res_common(struct session *t, struct channel *rep, int an_bit,
                rep,
                rep->rex, rep->wex,
                rep->flags,
-               rep->buf.i,
+               rep->buf->i,
                rep->analysers);
 
        if (unlikely(msg->msg_state < HTTP_MSG_BODY))   /* we need more data */
@@ -5349,7 +5349,7 @@ int http_response_forward_body(struct session *s, struct channel *res, int an_bi
                return 0;
 
        if ((res->flags & (CF_READ_ERROR|CF_READ_TIMEOUT|CF_WRITE_ERROR|CF_WRITE_TIMEOUT)) ||
-           ((res->flags & CF_SHUTW) && (res->to_forward || res->buf.o)) ||
+           ((res->flags & CF_SHUTW) && (res->to_forward || res->buf->o)) ||
            !s->req->analysers) {
                /* Output closed while we were sending data. We must abort and
                 * wake the other side up.
@@ -5364,7 +5364,7 @@ int http_response_forward_body(struct session *s, struct channel *res, int an_bi
 
        if (msg->msg_state < HTTP_MSG_CHUNK_SIZE) {
                /* we have msg->sov which points to the first byte of message body.
-                * rep->buf.p still points to the beginning of the message and msg->sol
+                * rep->buf->p still points to the beginning of the message and msg->sol
                 * is still null. We must save the body in msg->next because it
                 * survives buffer re-alignments.
                 */
@@ -5579,7 +5579,7 @@ int apply_filter_to_req_headers(struct session *t, struct channel *req, struct h
 
        last_hdr = 0;
 
-       cur_next = req->buf.p + hdr_idx_first_pos(&txn->hdr_idx);
+       cur_next = req->buf->p + hdr_idx_first_pos(&txn->hdr_idx);
        old_idx = 0;
 
        while (!last_hdr) {
@@ -5658,7 +5658,7 @@ int apply_filter_to_req_headers(struct session *t, struct channel *req, struct h
 
                        case ACT_REPLACE:
                                len = exp_replace(trash, cur_ptr, exp->replace, pmatch);
-                               delta = buffer_replace2(&req->buf, cur_ptr, cur_end, trash, len);
+                               delta = buffer_replace2(req->buf, cur_ptr, cur_end, trash, len);
                                /* FIXME: if the user adds a newline in the replacement, the
                                 * index will not be recalculated for now, and the new line
                                 * will not be counted as a new header.
@@ -5671,7 +5671,7 @@ int apply_filter_to_req_headers(struct session *t, struct channel *req, struct h
                                break;
 
                        case ACT_REMOVE:
-                               delta = buffer_replace2(&req->buf, cur_ptr, cur_next, NULL, 0);
+                               delta = buffer_replace2(req->buf, cur_ptr, cur_next, NULL, 0);
                                cur_next += delta;
 
                                http_msg_move_end(&txn->req, delta);
@@ -5723,7 +5723,7 @@ int apply_filter_to_req_line(struct session *t, struct channel *req, struct hdr_
 
        done = 0;
 
-       cur_ptr = req->buf.p;
+       cur_ptr = req->buf->p;
        cur_end = cur_ptr + txn->req.sl.rq.l;
 
        /* Now we have the request line between cur_ptr and cur_end */
@@ -5783,7 +5783,7 @@ int apply_filter_to_req_line(struct session *t, struct channel *req, struct hdr_
                case ACT_REPLACE:
                        *cur_end = term; /* restore the string terminator */
                        len = exp_replace(trash, cur_ptr, exp->replace, pmatch);
-                       delta = buffer_replace2(&req->buf, cur_ptr, cur_end, trash, len);
+                       delta = buffer_replace2(req->buf, cur_ptr, cur_end, trash, len);
                        /* FIXME: if the user adds a newline in the replacement, the
                         * index will not be recalculated for now, and the new line
                         * will not be counted as a new header.
@@ -6036,7 +6036,7 @@ void manage_client_side_cookies(struct session *t, struct channel *req)
 
        /* Iterate through the headers, we start with the start line. */
        old_idx = 0;
-       hdr_next = req->buf.p + hdr_idx_first_pos(&txn->hdr_idx);
+       hdr_next = req->buf->p + hdr_idx_first_pos(&txn->hdr_idx);
 
        while ((cur_idx = txn->hdr_idx.v[old_idx].next)) {
                struct hdr_idx_elem *cur_hdr;
@@ -6164,7 +6164,7 @@ void manage_client_side_cookies(struct session *t, struct channel *req)
                                 */
                                preserve_hdr = 1;
                                if (del_from != NULL) {
-                                       int delta = del_hdr_value(&req->buf, &del_from, prev);
+                                       int delta = del_hdr_value(req->buf, &del_from, prev);
                                        val_end  += delta;
                                        next     += delta;
                                        hdr_end  += delta;
@@ -6187,13 +6187,13 @@ void manage_client_side_cookies(struct session *t, struct channel *req)
                                int stripped_after = 0;
 
                                if (att_end != equal) {
-                                       stripped_before = buffer_replace2(&req->buf, att_end, equal, NULL, 0);
+                                       stripped_before = buffer_replace2(req->buf, att_end, equal, NULL, 0);
                                        equal   += stripped_before;
                                        val_beg += stripped_before;
                                }
 
                                if (val_beg > equal + 1) {
-                                       stripped_after = buffer_replace2(&req->buf, equal + 1, val_beg, NULL, 0);
+                                       stripped_after = buffer_replace2(req->buf, equal + 1, val_beg, NULL, 0);
                                        val_beg += stripped_after;
                                        stripped_before += stripped_after;
                                }
@@ -6374,7 +6374,7 @@ void manage_client_side_cookies(struct session *t, struct channel *req)
                                if ((t->be->ck_opts & PR_CK_PFX) && (delim != val_end)) {
                                        int delta; /* negative */
 
-                                       delta = buffer_replace2(&req->buf, val_beg, delim + 1, NULL, 0);
+                                       delta = buffer_replace2(req->buf, val_beg, delim + 1, NULL, 0);
                                        val_end  += delta;
                                        next     += delta;
                                        hdr_end  += delta;
@@ -6397,7 +6397,7 @@ void manage_client_side_cookies(struct session *t, struct channel *req)
                                preserve_hdr = 1;
 
                                if (del_from != NULL) {
-                                       int delta = del_hdr_value(&req->buf, &del_from, prev);
+                                       int delta = del_hdr_value(req->buf, &del_from, prev);
                                        if (att_beg >= del_from)
                                                att_beg += delta;
                                        if (att_end >= del_from)
@@ -6450,11 +6450,11 @@ void manage_client_side_cookies(struct session *t, struct channel *req)
                if (del_from) {
                        int delta;
                        if (preserve_hdr) {
-                               delta = del_hdr_value(&req->buf, &del_from, hdr_end);
+                               delta = del_hdr_value(req->buf, &del_from, hdr_end);
                                hdr_end = del_from;
                                cur_hdr->len += delta;
                        } else {
-                               delta = buffer_replace2(&req->buf, hdr_beg, hdr_next, NULL, 0);
+                               delta = buffer_replace2(req->buf, hdr_beg, hdr_next, NULL, 0);
 
                                /* FIXME: this should be a separate function */
                                txn->hdr_idx.v[old_idx].next = cur_hdr->next;
@@ -6486,7 +6486,7 @@ int apply_filter_to_resp_headers(struct session *t, struct channel *rtr, struct
 
        last_hdr = 0;
 
-       cur_next = rtr->buf.p + hdr_idx_first_pos(&txn->hdr_idx);
+       cur_next = rtr->buf->p + hdr_idx_first_pos(&txn->hdr_idx);
        old_idx = 0;
 
        while (!last_hdr) {
@@ -6532,7 +6532,7 @@ int apply_filter_to_resp_headers(struct session *t, struct channel *rtr, struct
 
                        case ACT_REPLACE:
                                len = exp_replace(trash, cur_ptr, exp->replace, pmatch);
-                               delta = buffer_replace2(&rtr->buf, cur_ptr, cur_end, trash, len);
+                               delta = buffer_replace2(rtr->buf, cur_ptr, cur_end, trash, len);
                                /* FIXME: if the user adds a newline in the replacement, the
                                 * index will not be recalculated for now, and the new line
                                 * will not be counted as a new header.
@@ -6545,7 +6545,7 @@ int apply_filter_to_resp_headers(struct session *t, struct channel *rtr, struct
                                break;
 
                        case ACT_REMOVE:
-                               delta = buffer_replace2(&rtr->buf, cur_ptr, cur_next, NULL, 0);
+                               delta = buffer_replace2(rtr->buf, cur_ptr, cur_next, NULL, 0);
                                cur_next += delta;
 
                                http_msg_move_end(&txn->rsp, delta);
@@ -6594,7 +6594,7 @@ int apply_filter_to_sts_line(struct session *t, struct channel *rtr, struct hdr_
 
        done = 0;
 
-       cur_ptr = rtr->buf.p;
+       cur_ptr = rtr->buf->p;
        cur_end = cur_ptr + txn->rsp.sl.st.l;
 
        /* Now we have the status line between cur_ptr and cur_end */
@@ -6622,7 +6622,7 @@ int apply_filter_to_sts_line(struct session *t, struct channel *rtr, struct hdr_
                case ACT_REPLACE:
                        *cur_end = term; /* restore the string terminator */
                        len = exp_replace(trash, cur_ptr, exp->replace, pmatch);
-                       delta = buffer_replace2(&rtr->buf, cur_ptr, cur_end, trash, len);
+                       delta = buffer_replace2(rtr->buf, cur_ptr, cur_end, trash, len);
                        /* FIXME: if the user adds a newline in the replacement, the
                         * index will not be recalculated for now, and the new line
                         * will not be counted as a new header.
@@ -6640,7 +6640,7 @@ int apply_filter_to_sts_line(struct session *t, struct channel *rtr, struct hdr_
                        /* we have a full respnse and we know that we have either a CR
                         * or an LF at <ptr>.
                         */
-                       txn->status = strl2ui(rtr->buf.p + txn->rsp.sl.st.c, txn->rsp.sl.st.c_l);
+                       txn->status = strl2ui(rtr->buf->p + txn->rsp.sl.st.c, txn->rsp.sl.st.c_l);
                        hdr_idx_set_start(&txn->hdr_idx, txn->rsp.sl.st.l, *cur_end == '\r');
                        /* there is no point trying this regex on headers */
                        return 1;
@@ -6727,7 +6727,7 @@ void manage_server_side_cookies(struct session *t, struct channel *res)
         * we start with the start line.
         */
        old_idx = 0;
-       hdr_next = res->buf.p + hdr_idx_first_pos(&txn->hdr_idx);
+       hdr_next = res->buf->p + hdr_idx_first_pos(&txn->hdr_idx);
 
        while ((cur_idx = txn->hdr_idx.v[old_idx].next)) {
                struct hdr_idx_elem *cur_hdr;
@@ -6877,13 +6877,13 @@ void manage_server_side_cookies(struct session *t, struct channel *res)
                                int stripped_after = 0;
 
                                if (att_end != equal) {
-                                       stripped_before = buffer_replace2(&res->buf, att_end, equal, NULL, 0);
+                                       stripped_before = buffer_replace2(res->buf, att_end, equal, NULL, 0);
                                        equal   += stripped_before;
                                        val_beg += stripped_before;
                                }
 
                                if (val_beg > equal + 1) {
-                                       stripped_after = buffer_replace2(&res->buf, equal + 1, val_beg, NULL, 0);
+                                       stripped_after = buffer_replace2(res->buf, equal + 1, val_beg, NULL, 0);
                                        val_beg += stripped_after;
                                        stripped_before += stripped_after;
                                }
@@ -6941,7 +6941,7 @@ void manage_server_side_cookies(struct session *t, struct channel *res)
                                        /* this cookie must be deleted */
                                        if (*prev == ':' && next == hdr_end) {
                                                /* whole header */
-                                               delta = buffer_replace2(&res->buf, hdr_beg, hdr_next, NULL, 0);
+                                               delta = buffer_replace2(res->buf, hdr_beg, hdr_next, NULL, 0);
                                                txn->hdr_idx.v[old_idx].next = cur_hdr->next;
                                                txn->hdr_idx.used--;
                                                cur_hdr->len = 0;
@@ -6953,7 +6953,7 @@ void manage_server_side_cookies(struct session *t, struct channel *res)
                                                 */
                                        } else {
                                                /* just remove the value */
-                                               int delta = del_hdr_value(&res->buf, &prev, next);
+                                               int delta = del_hdr_value(res->buf, &prev, next);
                                                next      = prev;
                                                hdr_end  += delta;
                                                hdr_next += delta;
@@ -6968,7 +6968,7 @@ void manage_server_side_cookies(struct session *t, struct channel *res)
                                        /* replace bytes val_beg->val_end with the cookie name associated
                                         * with this server since we know it.
                                         */
-                                       delta = buffer_replace2(&res->buf, val_beg, val_end, srv->cookie, srv->cklen);
+                                       delta = buffer_replace2(res->buf, val_beg, val_end, srv->cookie, srv->cklen);
                                        next     += delta;
                                        hdr_end  += delta;
                                        hdr_next += delta;
@@ -6982,7 +6982,7 @@ void manage_server_side_cookies(struct session *t, struct channel *res)
                                        /* insert the cookie name associated with this server
                                         * before existing cookie, and insert a delimiter between them..
                                         */
-                                       delta = buffer_replace2(&res->buf, val_beg, val_beg, srv->cookie, srv->cklen + 1);
+                                       delta = buffer_replace2(res->buf, val_beg, val_beg, srv->cookie, srv->cklen + 1);
                                        next     += delta;
                                        hdr_end  += delta;
                                        hdr_next += delta;
@@ -7092,7 +7092,7 @@ void check_response_for_cacheability(struct session *t, struct channel *rtr)
         * we start with the start line.
         */
        cur_idx = 0;
-       cur_next = rtr->buf.p + hdr_idx_first_pos(&txn->hdr_idx);
+       cur_next = rtr->buf->p + hdr_idx_first_pos(&txn->hdr_idx);
 
        while ((cur_idx = txn->hdr_idx.v[cur_idx].next)) {
                struct hdr_idx_elem *cur_hdr;
@@ -7246,7 +7246,7 @@ int stats_check_uri(struct stream_interface *si, struct http_txn *txn, struct pr
 {
        struct uri_auth *uri_auth = backend->uri_auth;
        struct http_msg *msg = &txn->req;
-       const char *uri = msg->chn->buf.p+ msg->sl.rq.u;
+       const char *uri = msg->chn->buf->p+ msg->sl.rq.u;
        const char *h;
 
        if (!uri_auth)
@@ -7331,14 +7331,14 @@ void http_capture_bad_message(struct error_snapshot *es, struct session *s,
        struct channel *chn = msg->chn;
        int len1, len2;
 
-       es->len = MIN(chn->buf.i, sizeof(es->buf));
-       len1 = chn->buf.data + chn->buf.size - chn->buf.p;
+       es->len = MIN(chn->buf->i, sizeof(es->buf));
+       len1 = chn->buf->data + chn->buf->size - chn->buf->p;
        len1 = MIN(len1, es->len);
        len2 = es->len - len1; /* remaining data if buffer wraps */
 
-       memcpy(es->buf, chn->buf.p, len1);
+       memcpy(es->buf, chn->buf->p, len1);
        if (len2)
-               memcpy(es->buf + len1, chn->buf.data, len2);
+               memcpy(es->buf + len1, chn->buf->data, len2);
 
        if (msg->err_pos >= 0)
                es->pos = msg->err_pos;
@@ -7356,8 +7356,8 @@ void http_capture_bad_message(struct error_snapshot *es, struct session *s,
        es->s_flags = s->flags;
        es->t_flags = s->txn.flags;
        es->m_flags = msg->flags;
-       es->b_out = chn->buf.o;
-       es->b_wrap = chn->buf.data + chn->buf.size - chn->buf.p;
+       es->b_out = chn->buf->o;
+       es->b_wrap = chn->buf->data + chn->buf->size - chn->buf->p;
        es->b_tot = chn->total;
        es->m_clen = msg->chunk_len;
        es->m_blen = msg->body_len;
@@ -7390,7 +7390,7 @@ unsigned int http_get_hdr(const struct http_msg *msg, const char *hname, int hle
 
        if (occ >= 0) {
                /* search from the beginning */
-               while (http_find_header2(hname, hlen, msg->chn->buf.p, idx, ctx)) {
+               while (http_find_header2(hname, hlen, msg->chn->buf->p, idx, ctx)) {
                        occ--;
                        if (occ <= 0) {
                                *vptr = ctx->line + ctx->val;
@@ -7406,7 +7406,7 @@ unsigned int http_get_hdr(const struct http_msg *msg, const char *hname, int hle
                return 0;
 
        found = hist_ptr = 0;
-       while (http_find_header2(hname, hlen, msg->chn->buf.p, idx, ctx)) {
+       while (http_find_header2(hname, hlen, msg->chn->buf->p, idx, ctx)) {
                ptr_hist[hist_ptr] = ctx->line + ctx->val;
                len_hist[hist_ptr] = ctx->vlen;
                if (++hist_ptr >= MAX_HDR_HISTORY)
@@ -7555,8 +7555,8 @@ void http_reset_txn(struct session *s)
         * a HEAD with some data, or sending more than the advertised
         * content-length.
         */
-       if (unlikely(s->rep->buf.i))
-               s->rep->buf.i = 0;
+       if (unlikely(s->rep->buf->i))
+               s->rep->buf->i = 0;
 
        s->req->rto = s->fe->timeout.client;
        s->req->wto = TICK_ETERNITY;
@@ -7683,19 +7683,19 @@ acl_prefetch_http(struct proxy *px, struct session *s, void *l7, unsigned int op
 
                if (unlikely(txn->req.msg_state < HTTP_MSG_BODY)) {
                        if ((msg->msg_state == HTTP_MSG_ERROR) ||
-                           buffer_full(&s->req->buf, global.tune.maxrewrite)) {
+                           buffer_full(s->req->buf, global.tune.maxrewrite)) {
                                smp->data.uint = 0;
                                return -1;
                        }
 
                        /* Try to decode HTTP request */
-                       if (likely(msg->next < s->req->buf.i))
+                       if (likely(msg->next < s->req->buf->i))
                                http_msg_analyzer(msg, &txn->hdr_idx);
 
                        /* Still no valid request ? */
                        if (unlikely(msg->msg_state < HTTP_MSG_BODY)) {
                                if ((msg->msg_state == HTTP_MSG_ERROR) ||
-                                   buffer_full(&s->req->buf, global.tune.maxrewrite)) {
+                                   buffer_full(s->req->buf, global.tune.maxrewrite)) {
                                        smp->data.uint = 0;
                                        return -1;
                                }
@@ -7708,7 +7708,7 @@ acl_prefetch_http(struct proxy *px, struct session *s, void *l7, unsigned int op
                         * preparation to perform so that further checks can rely
                         * on HTTP tests.
                         */
-                       txn->meth = find_http_meth(msg->chn->buf.p, msg->sl.rq.m_l);
+                       txn->meth = find_http_meth(msg->chn->buf->p, msg->sl.rq.m_l);
                        if (txn->meth == HTTP_METH_GET || txn->meth == HTTP_METH_HEAD)
                                s->flags |= SN_REDIRECTABLE;
 
@@ -7789,7 +7789,7 @@ acl_fetch_meth(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
                        return 0;
                smp->type = SMP_T_CSTR;
                smp->data.str.len = txn->req.sl.rq.m_l;
-               smp->data.str.str = txn->req.chn->buf.p;
+               smp->data.str.str = txn->req.chn->buf->p;
        }
        smp->flags = SMP_F_VOL_1ST;
        return 1;
@@ -7848,7 +7848,7 @@ acl_fetch_rqver(struct proxy *px, struct session *l4, void *l7, unsigned int opt
        CHECK_HTTP_MESSAGE_FIRST();
 
        len = txn->req.sl.rq.v_l;
-       ptr = txn->req.chn->buf.p + txn->req.sl.rq.v;
+       ptr = txn->req.chn->buf->p + txn->req.sl.rq.v;
 
        while ((len-- > 0) && (*ptr++ != '/'));
        if (len <= 0)
@@ -7873,7 +7873,7 @@ acl_fetch_stver(struct proxy *px, struct session *l4, void *l7, unsigned int opt
        CHECK_HTTP_MESSAGE_FIRST();
 
        len = txn->rsp.sl.st.v_l;
-       ptr = txn->rsp.chn->buf.p;
+       ptr = txn->rsp.chn->buf->p;
 
        while ((len-- > 0) && (*ptr++ != '/'));
        if (len <= 0)
@@ -7899,7 +7899,7 @@ acl_fetch_stcode(struct proxy *px, struct session *l4, void *l7, unsigned int op
        CHECK_HTTP_MESSAGE_FIRST();
 
        len = txn->rsp.sl.st.c_l;
-       ptr = txn->rsp.chn->buf.p + txn->rsp.sl.st.c;
+       ptr = txn->rsp.chn->buf->p + txn->rsp.sl.st.c;
 
        smp->type = SMP_T_UINT;
        smp->data.uint = __strl2ui(ptr, len);
@@ -7918,7 +7918,7 @@ smp_fetch_url(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
 
        smp->type = SMP_T_CSTR;
        smp->data.str.len = txn->req.sl.rq.u_l;
-       smp->data.str.str = txn->req.chn->buf.p + txn->req.sl.rq.u;
+       smp->data.str.str = txn->req.chn->buf->p + txn->req.sl.rq.u;
        smp->flags = SMP_F_VOL_1ST;
        return 1;
 }
@@ -7932,7 +7932,7 @@ smp_fetch_url_ip(struct proxy *px, struct session *l4, void *l7, unsigned int op
        CHECK_HTTP_MESSAGE_FIRST();
 
        /* Parse HTTP request */
-       url2sa(txn->req.chn->buf.p + txn->req.sl.rq.u, txn->req.sl.rq.u_l, &l4->req->cons->conn.addr.to);
+       url2sa(txn->req.chn->buf->p + txn->req.sl.rq.u, txn->req.sl.rq.u_l, &l4->req->cons->conn.addr.to);
        if (((struct sockaddr_in *)&l4->req->cons->conn.addr.to)->sin_family != AF_INET)
                return 0;
        smp->type = SMP_T_IPV4;
@@ -7958,7 +7958,7 @@ smp_fetch_url_port(struct proxy *px, struct session *l4, void *l7, unsigned int
        CHECK_HTTP_MESSAGE_FIRST();
 
        /* Same optimization as url_ip */
-       url2sa(txn->req.chn->buf.p + txn->req.sl.rq.u, txn->req.sl.rq.u_l, &l4->req->cons->conn.addr.to);
+       url2sa(txn->req.chn->buf->p + txn->req.sl.rq.u, txn->req.sl.rq.u_l, &l4->req->cons->conn.addr.to);
        smp->type = SMP_T_UINT;
        smp->data.uint = ntohs(((struct sockaddr_in *)&l4->req->cons->conn.addr.to)->sin_port);
 
@@ -8040,7 +8040,7 @@ smp_fetch_hdr_cnt(struct proxy *px, struct session *l4, void *l7, unsigned int o
 
        ctx.idx = 0;
        cnt = 0;
-       while (http_find_header2(args->data.str.str, args->data.str.len, msg->chn->buf.p, idx, &ctx))
+       while (http_find_header2(args->data.str.str, args->data.str.len, msg->chn->buf->p, idx, &ctx))
                cnt++;
 
        smp->type = SMP_T_UINT;
@@ -8101,7 +8101,7 @@ smp_fetch_path(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
 
        CHECK_HTTP_MESSAGE_FIRST();
 
-       end = txn->req.chn->buf.p + txn->req.sl.rq.u + txn->req.sl.rq.u_l;
+       end = txn->req.chn->buf->p + txn->req.sl.rq.u + txn->req.sl.rq.u_l;
        ptr = http_get_path(txn);
        if (!ptr)
                return 0;
@@ -8135,7 +8135,7 @@ smp_fetch_base(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
        CHECK_HTTP_MESSAGE_FIRST();
 
        ctx.idx = 0;
-       if (!http_find_header2("Host", 4, txn->req.chn->buf.p + txn->req.sol, &txn->hdr_idx, &ctx) ||
+       if (!http_find_header2("Host", 4, txn->req.chn->buf->p + txn->req.sol, &txn->hdr_idx, &ctx) ||
            !ctx.vlen)
                return smp_fetch_path(px, l4, l7, opt, args, smp);
 
@@ -8146,7 +8146,7 @@ smp_fetch_base(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
        smp->data.str.len = ctx.vlen;
 
        /* now retrieve the path */
-       end = txn->req.chn->buf.p + txn->req.sol + txn->req.sl.rq.u + txn->req.sl.rq.u_l;
+       end = txn->req.chn->buf->p + txn->req.sol + txn->req.sl.rq.u + txn->req.sl.rq.u_l;
        beg = http_get_path(txn);
        if (!beg)
                beg = end;
@@ -8382,7 +8382,7 @@ smp_fetch_cookie(struct proxy *px, struct session *l4, void *l7, unsigned int op
         * next one.
         */
 
-       sol = msg->chn->buf.p;
+       sol = msg->chn->buf->p;
        if (!(smp->flags & SMP_F_NOT_LAST)) {
                /* search for the header from the beginning, we must first initialize
                 * the search parameters.
@@ -8464,7 +8464,7 @@ acl_fetch_cookie_cnt(struct proxy *px, struct session *l4, void *l7, unsigned in
                hdr_name_len = 10;
        }
 
-       sol = msg->chn->buf.p;
+       sol = msg->chn->buf->p;
        val_end = val_beg = NULL;
        ctx.idx = 0;
        cnt = 0;
@@ -8622,7 +8622,7 @@ smp_fetch_url_param(struct proxy *px, struct session *l4, void *l7, unsigned int
        if (args[1].type)
                delim = *args[1].data.str.str;
 
-       if (!find_url_param_value(msg->chn->buf.p + msg->sl.rq.u, msg->sl.rq.u_l,
+       if (!find_url_param_value(msg->chn->buf->p + msg->sl.rq.u, msg->sl.rq.u_l,
                                  args->data.str.str, args->data.str.len,
                                  &smp->data.str.str, &smp->data.str.len,
                                  delim))
index 7185a0a400104b1dd392bfb18d94e1cac6f9196b..d0424d98f5493d5482e86812f58223cbdca81e50 100644 (file)
@@ -792,7 +792,7 @@ int tcp_inspect_request(struct session *s, struct channel *req, int an_bit)
                req,
                req->rex, req->wex,
                req->flags,
-               req->buf.i,
+               req->buf->i,
                req->analysers);
 
        /* We don't know whether we have enough data, so must proceed
@@ -805,7 +805,7 @@ int tcp_inspect_request(struct session *s, struct channel *req, int an_bit)
         * - if one rule returns KO, then return KO
         */
 
-       if ((req->flags & CF_SHUTR) || buffer_full(&req->buf, global.tune.maxrewrite) ||
+       if ((req->flags & CF_SHUTR) || buffer_full(req->buf, global.tune.maxrewrite) ||
            !s->be->tcp_req.inspect_delay || tick_is_expired(req->analyse_exp, now_ms))
                partial = SMP_OPT_FINAL;
        else
@@ -911,7 +911,7 @@ int tcp_inspect_response(struct session *s, struct channel *rep, int an_bit)
                rep,
                rep->rex, rep->wex,
                rep->flags,
-               rep->buf.i,
+               rep->buf->i,
                rep->analysers);
 
        /* We don't know whether we have enough data, so must proceed
@@ -1400,11 +1400,11 @@ smp_fetch_rdp_cookie(struct proxy *px, struct session *l4, void *l7, unsigned in
        smp->flags = 0;
        smp->type = SMP_T_CSTR;
 
-       bleft = l4->req->buf.i;
+       bleft = l4->req->buf->i;
        if (bleft <= 11)
                goto too_short;
 
-       data = (const unsigned char *)l4->req->buf.p + 11;
+       data = (const unsigned char *)l4->req->buf->p + 11;
        bleft -= 11;
 
        if (bleft <= 7)
@@ -1595,11 +1595,11 @@ smp_fetch_payload_lv(struct proxy *px, struct session *l4, void *l7, unsigned in
        if (!chn)
                return 0;
 
-       if (len_offset + len_size > chn->buf.i)
+       if (len_offset + len_size > chn->buf->i)
                goto too_short;
 
        for (i = 0; i < len_size; i++) {
-               buf_size = (buf_size << 8) + ((unsigned char *)chn->buf.p)[i + len_offset];
+               buf_size = (buf_size << 8) + ((unsigned char *)chn->buf->p)[i + len_offset];
        }
 
        /* buf offset may be implicit, absolute or relative */
@@ -1609,18 +1609,18 @@ smp_fetch_payload_lv(struct proxy *px, struct session *l4, void *l7, unsigned in
        else if (arg_p[2].type == ARGT_SINT)
                buf_offset += arg_p[2].data.sint;
 
-       if (!buf_size || buf_size > chn->buf.size || buf_offset + buf_size > chn->buf.size) {
+       if (!buf_size || buf_size > chn->buf->size || buf_offset + buf_size > chn->buf->size) {
                /* will never match */
                smp->flags = 0;
                return 0;
        }
 
-       if (buf_offset + buf_size > chn->buf.i)
+       if (buf_offset + buf_size > chn->buf->i)
                goto too_short;
 
        /* init chunk as read only */
        smp->type = SMP_T_CBIN;
-       chunk_initlen(&smp->data.str, chn->buf.p + buf_offset, 0, buf_size);
+       chunk_initlen(&smp->data.str, chn->buf->p + buf_offset, 0, buf_size);
        smp->flags = SMP_F_VOLATILE;
        return 1;
 
@@ -1645,18 +1645,18 @@ smp_fetch_payload(struct proxy *px, struct session *l4, void *l7, unsigned int o
        if (!chn)
                return 0;
 
-       if (!buf_size || buf_size > chn->buf.size || buf_offset + buf_size > chn->buf.size) {
+       if (!buf_size || buf_size > chn->buf->size || buf_offset + buf_size > chn->buf->size) {
                /* will never match */
                smp->flags = 0;
                return 0;
        }
 
-       if (buf_offset + buf_size > chn->buf.i)
+       if (buf_offset + buf_size > chn->buf->i)
                goto too_short;
 
        /* init chunk as read only */
        smp->type = SMP_T_CBIN;
-       chunk_initlen(&smp->data.str, chn->buf.p + buf_offset, 0, buf_size);
+       chunk_initlen(&smp->data.str, chn->buf->p + buf_offset, 0, buf_size);
        smp->flags = SMP_F_VOLATILE;
        return 1;
 
index b15440795c892291cb2117222005e716c7400d4d..ce99e782489d915a5fa270605c4c2914503e758a 100644 (file)
@@ -15,6 +15,7 @@
 #include <fcntl.h>
 
 #include <common/config.h>
+#include <common/buffer.h>
 #include <common/debug.h>
 #include <common/memory.h>
 
@@ -419,11 +420,17 @@ int session_complete(struct session *s)
        if (unlikely((s->req = pool_alloc2(pool2_channel)) == NULL))
                goto out_free_task; /* no memory */
 
-       if (unlikely((s->rep = pool_alloc2(pool2_channel)) == NULL))
+       if (unlikely((s->req->buf = pool_alloc2(pool2_buffer)) == NULL))
                goto out_free_req; /* no memory */
 
+       if (unlikely((s->rep = pool_alloc2(pool2_channel)) == NULL))
+               goto out_free_req_buf; /* no memory */
+
+       if (unlikely((s->rep->buf = pool_alloc2(pool2_buffer)) == NULL))
+               goto out_free_rep; /* no memory */
+
        /* initialize the request buffer */
-       s->req->buf.size = global.tune.bufsize;
+       s->req->buf->size = global.tune.bufsize;
        channel_init(s->req);
        s->req->prod = &s->si[0];
        s->req->cons = &s->si[1];
@@ -440,7 +447,7 @@ int session_complete(struct session *s)
        s->req->analyse_exp = TICK_ETERNITY;
 
        /* initialize response buffer */
-       s->rep->buf.size = global.tune.bufsize;
+       s->rep->buf->size = global.tune.bufsize;
        channel_init(s->rep);
        s->rep->prod = &s->si[1];
        s->rep->cons = &s->si[0];
@@ -485,7 +492,7 @@ int session_complete(struct session *s)
                 * finished (=0, eg: monitoring), in both situations,
                 * we can release everything and close.
                 */
-               goto out_free_rep;
+               goto out_free_rep_buf;
        }
 
        /* if logs require transport layer information, note it on the connection */
@@ -503,8 +510,12 @@ int session_complete(struct session *s)
        return 1;
 
        /* Error unrolling */
+ out_free_rep_buf:
+       pool_free2(pool2_buffer, s->rep->buf);
  out_free_rep:
        pool_free2(pool2_channel, s->rep);
+ out_free_req_buf:
+       pool_free2(pool2_buffer, s->req->buf);
  out_free_req:
        pool_free2(pool2_channel, s->req);
  out_free_task:
@@ -547,6 +558,9 @@ static void session_free(struct session *s)
        if (s->rep->pipe)
                put_pipe(s->rep->pipe);
 
+       pool_free2(pool2_buffer, s->req->buf);
+       pool_free2(pool2_buffer, s->rep->buf);
+
        pool_free2(pool2_channel, s->req);
        pool_free2(pool2_channel, s->rep);
 
@@ -587,6 +601,7 @@ static void session_free(struct session *s)
 
        /* We may want to free the maximum amount of pools if the proxy is stopping */
        if (fe && unlikely(fe->state == PR_STSTOPPED)) {
+               pool_flush2(pool2_buffer);
                pool_flush2(pool2_channel);
                pool_flush2(pool2_hdr_idx);
                pool_flush2(pool2_requri);
@@ -915,7 +930,7 @@ static void sess_update_stream_int(struct session *s, struct stream_interface *s
                s->req, s->rep,
                s->req->rex, s->rep->wex,
                s->req->flags, s->rep->flags,
-               s->req->buf.i, s->req->buf.o, s->rep->buf.i, s->rep->buf.o, s->rep->cons->state, s->req->cons->state);
+               s->req->buf->i, s->req->buf->o, s->rep->buf->i, s->rep->buf->o, s->rep->cons->state, s->req->cons->state);
 
        if (si->state == SI_ST_ASS) {
                /* Server assigned to connection request, we have to try to connect now */
@@ -1103,7 +1118,7 @@ static void sess_prepare_conn_req(struct session *s, struct stream_interface *si
                s->req, s->rep,
                s->req->rex, s->rep->wex,
                s->req->flags, s->rep->flags,
-               s->req->buf.i, s->req->buf.o, s->rep->buf.i, s->rep->buf.o, s->rep->cons->state, s->req->cons->state);
+               s->req->buf->i, s->req->buf->o, s->rep->buf->i, s->rep->buf->o, s->rep->cons->state, s->req->cons->state);
 
        if (si->state != SI_ST_REQ)
                return;
@@ -1152,7 +1167,7 @@ static int process_switching_rules(struct session *s, struct channel *req, int a
                req,
                req->rex, req->wex,
                req->flags,
-               req->buf.i,
+               req->buf->i,
                req->analysers);
 
        /* now check whether we have some switching rules for this request */
@@ -1247,7 +1262,7 @@ static int process_server_rules(struct session *s, struct channel *req, int an_b
                req,
                req->rex, req->wex,
                req->flags,
-               req->buf.i + req->buf.o,
+               req->buf->i + req->buf->o,
                req->analysers);
 
        if (!(s->flags & SN_ASSIGNED)) {
@@ -1296,7 +1311,7 @@ static int process_sticking_rules(struct session *s, struct channel *req, int an
                req,
                req->rex, req->wex,
                req->flags,
-               req->buf.i,
+               req->buf->i,
                req->analysers);
 
        list_for_each_entry(rule, &px->sticking_rules, list) {
@@ -1386,7 +1401,7 @@ static int process_store_rules(struct session *s, struct channel *rep, int an_bi
                rep,
                rep->rex, rep->wex,
                rep->flags,
-               rep->buf.i,
+               rep->buf->i,
                rep->analysers);
 
        list_for_each_entry(rule, &px->storersp_rules, list) {
@@ -1633,7 +1648,7 @@ struct task *process_session(struct task *t)
                s->req, s->rep,
                s->req->rex, s->rep->wex,
                s->req->flags, s->rep->flags,
-               s->req->buf.i, s->req->buf.o, s->rep->buf.i, s->rep->buf.o, s->rep->cons->state, s->req->cons->state,
+               s->req->buf->i, s->req->buf->o, s->rep->buf->i, s->rep->buf->o, s->rep->cons->state, s->req->cons->state,
                s->rep->cons->err_type, s->req->cons->err_type,
                s->req->cons->conn_retries);
 
@@ -2036,7 +2051,7 @@ struct task *process_session(struct task *t)
                channel_auto_read(s->req);
                channel_auto_connect(s->req);
                channel_auto_close(s->req);
-               buffer_flush(&s->req->buf);
+               buffer_flush(s->req->buf);
 
                /* We'll let data flow between the producer (if still connected)
                 * to the consumer (which might possibly not be connected yet).
@@ -2172,7 +2187,7 @@ struct task *process_session(struct task *t)
                 */
                channel_auto_read(s->rep);
                channel_auto_close(s->rep);
-               buffer_flush(&s->rep->buf);
+               buffer_flush(s->rep->buf);
 
                /* We'll let data flow between the producer (if still connected)
                 * to the consumer.
index fd427b34e6d5129aa0f2ce858f18efeac783841c..c74f4536182319bf8f8e8f3bd59e7afc3a39aef0 100644 (file)
@@ -617,7 +617,7 @@ static int si_conn_wake_cb(struct connection *conn)
         */
        if (((si->ib->flags & CF_READ_PARTIAL) && !channel_is_empty(si->ib)) &&
            (si->ib->pipe /* always try to send spliced data */ ||
-            (si->ib->buf.i == 0 && (si->ib->cons->flags & SI_FL_WAIT_DATA)))) {
+            (si->ib->buf->i == 0 && (si->ib->cons->flags & SI_FL_WAIT_DATA)))) {
                int last_len = si->ib->pipe ? si->ib->pipe->data : 0;
 
                si_chk_snd(si->ib->cons);
@@ -691,7 +691,7 @@ static int si_conn_send_loop(struct connection *conn)
        /* At this point, the pipe is empty, but we may still have data pending
         * in the normal buffer.
         */
-       if (!chn->buf.o)
+       if (!chn->buf->o)
                return 0;
 
        /* when we're in this loop, we already know that there is no spliced
@@ -716,13 +716,13 @@ static int si_conn_send_loop(struct connection *conn)
                    ((chn->flags & (CF_SHUTW|CF_SHUTW_NOW|CF_HIJACK)) == CF_SHUTW_NOW))
                        send_flag |= MSG_MORE;
 
-               ret = conn->xprt->snd_buf(conn, &chn->buf, send_flag);
+               ret = conn->xprt->snd_buf(conn, chn->buf, send_flag);
                if (ret <= 0)
                        break;
 
                chn->flags |= CF_WRITE_PARTIAL;
 
-               if (!chn->buf.o) {
+               if (!chn->buf->o) {
                        /* Always clear both flags once everything has been sent, they're one-shot */
                        chn->flags &= ~(CF_EXPECT_MORE | CF_SEND_DONTWAIT);
                        break;
@@ -970,7 +970,7 @@ static void si_conn_recv_cb(struct connection *conn)
         */
        if (conn->xprt->rcv_pipe &&
            chn->to_forward >= MIN_SPLICE_FORWARD && chn->flags & CF_KERN_SPLICING) {
-               if (buffer_not_empty(&chn->buf)) {
+               if (buffer_not_empty(chn->buf)) {
                        /* We're embarrassed, there are already data pending in
                         * the buffer and we don't want to have them at two
                         * locations at a time. Let's indicate we need some
@@ -1028,7 +1028,7 @@ static void si_conn_recv_cb(struct connection *conn)
                        break;
                }
 
-               ret = conn->xprt->rcv_buf(conn, &chn->buf, max);
+               ret = conn->xprt->rcv_buf(conn, chn->buf, max);
                if (ret <= 0)
                        break;
 
@@ -1042,7 +1042,7 @@ static void si_conn_recv_cb(struct connection *conn)
                                        fwd = chn->to_forward;
                                chn->to_forward -= fwd;
                        }
-                       b_adv(&chn->buf, fwd);
+                       b_adv(chn->buf, fwd);
                }
 
                chn->flags |= CF_READ_PARTIAL;
@@ -1052,7 +1052,7 @@ static void si_conn_recv_cb(struct connection *conn)
                        /* The buffer is now full, there's no point in going through
                         * the loop again.
                         */
-                       if (!(chn->flags & CF_STREAMER_FAST) && (cur_read == buffer_len(&chn->buf))) {
+                       if (!(chn->flags & CF_STREAMER_FAST) && (cur_read == buffer_len(chn->buf))) {
                                chn->xfer_small = 0;
                                chn->xfer_large++;
                                if (chn->xfer_large >= 3) {
@@ -1064,7 +1064,7 @@ static void si_conn_recv_cb(struct connection *conn)
                                }
                        }
                        else if ((chn->flags & (CF_STREAMER | CF_STREAMER_FAST)) &&
-                                (cur_read <= chn->buf.size / 2)) {
+                                (cur_read <= chn->buf->size / 2)) {
                                chn->xfer_large = 0;
                                chn->xfer_small++;
                                if (chn->xfer_small >= 2) {
@@ -1094,7 +1094,7 @@ static void si_conn_recv_cb(struct connection *conn)
                 */
                if (ret < max) {
                        if ((chn->flags & (CF_STREAMER | CF_STREAMER_FAST)) &&
-                           (cur_read <= chn->buf.size / 2)) {
+                           (cur_read <= chn->buf->size / 2)) {
                                chn->xfer_large = 0;
                                chn->xfer_small++;
                                if (chn->xfer_small >= 3) {