]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
REORG/MAJOR: move session's req and resp channels back into the session
authorWilly Tarreau <w@1wt.eu>
Thu, 27 Nov 2014 19:45:39 +0000 (20:45 +0100)
committerWilly Tarreau <w@1wt.eu>
Wed, 11 Mar 2015 19:41:46 +0000 (20:41 +0100)
The channels were pointers to outside structs and this is not needed
anymore since the buffers have moved, but this complicates operations.
Move them back into the session so that both channels and stream interfaces
are always allocated for a session. Some places (some early sample fetch
functions) used to validate that a channel was NULL prior to dereferencing
it. Now instead we check if chn->buf is NULL and we force it to remain NULL
until the channel is initialized.

12 files changed:
include/types/session.h
src/backend.c
src/dumpstats.c
src/frontend.c
src/hlua.c
src/log.c
src/payload.c
src/peers.c
src/proto_http.c
src/proto_tcp.c
src/proxy.c
src/session.c

index 8aa20bd88c6d448a74d2f3492a00d0fc64eaf84f..78664fb2a44404ad49eee928a2248be65b44bb9a 100644 (file)
@@ -107,8 +107,8 @@ struct session {
        unsigned int uniq_id;                   /* unique ID used for the traces */
        enum obj_type *target;                  /* target to use for this session ; for mini-sess: incoming connection */
 
-       struct channel *req;                    /* request buffer */
-       struct channel *rep;                    /* response buffer */
+       struct channel req;                     /* request channel */
+       struct channel res;                     /* response channel */
 
        struct proxy *fe;                       /* the proxy this session depends on for the client side */
        struct proxy *be;                       /* the proxy this session depends on for the server side */
index fc4f0c341aa19edfe5a441a7caa4ff25aa0f1094..a8178aaefc86f3d76466196f65e37a62ad2ad294 100644 (file)
@@ -301,7 +301,7 @@ struct server *get_server_ph_post(struct session *s)
 {
        unsigned int hash = 0;
        struct http_txn *txn  = &s->txn;
-       struct channel   *req = s->req;
+       struct channel  *req  = &s->req;
        struct http_msg *msg  = &txn->req;
        struct proxy    *px   = s->be;
        unsigned int     plen = px->url_param_len;
@@ -393,7 +393,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, -http_hdr_rewind(&txn->req)), &txn->hdr_idx, &ctx);
+       http_find_header2(px->hh_name, plen, b_ptr(s->req.buf, -http_hdr_rewind(&txn->req)), &txn->hdr_idx, &ctx);
 
        /* if the header is not found or empty, let's fallback to round robin */
        if (!ctx.idx || !ctx.vlen)
@@ -466,12 +466,12 @@ struct server *get_server_rch(struct session *s)
 
        memset(&smp, 0, sizeof(smp));
 
-       b_rew(s->req->buf, rewind = s->req->buf->o);
+       b_rew(s->req.buf, rewind = s->req.buf->o);
 
        ret = fetch_rdp_cookie_name(s, &smp, px->hh_name, px->hh_len);
        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;
@@ -548,7 +548,7 @@ int assign_server(struct session *s)
 
        srv = NULL;
        s->target = NULL;
-       conn = objt_conn(s->req->cons->end);
+       conn = objt_conn(s->req.cons->end);
 
        if (conn &&
            (conn->flags & CO_FL_CONNECTED) &&
@@ -607,7 +607,7 @@ int assign_server(struct session *s)
 
                        switch (s->be->lbprm.algo & BE_LB_PARM) {
                        case BE_LB_HASH_SRC:
-                               conn = objt_conn(s->req->prod->end);
+                               conn = objt_conn(s->req.prod->end);
                                if (conn && conn->addr.from.ss_family == AF_INET) {
                                        srv = get_server_sh(s->be,
                                                            (void *)&((struct sockaddr_in *)&conn->addr.from)->sin_addr,
@@ -630,7 +630,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, -http_uri_rewind(&s->txn.req)),
+                                                   b_ptr(s->req.buf, -http_uri_rewind(&s->txn.req)),
                                                    s->txn.req.sl.rq.u_l);
                                break;
 
@@ -640,7 +640,7 @@ int assign_server(struct session *s)
                                        break;
 
                                srv = get_server_ph(s->be,
-                                                   b_ptr(s->req->buf, -http_uri_rewind(&s->txn.req)),
+                                                   b_ptr(s->req.buf, -http_uri_rewind(&s->txn.req)),
                                                    s->txn.req.sl.rq.u_l);
 
                                if (!srv && s->txn.meth == HTTP_METH_POST)
@@ -698,7 +698,7 @@ int assign_server(struct session *s)
                s->target = &s->be->obj_type;
        }
        else if ((s->be->options & PR_O_HTTP_PROXY) &&
-                (conn = objt_conn(s->req->cons->end)) &&
+                (conn = objt_conn(s->req.cons->end)) &&
                 is_addr(&conn->addr.to)) {
                /* in proxy mode, we need a valid destination address */
                s->target = &s->be->obj_type;
@@ -746,8 +746,8 @@ int assign_server(struct session *s)
  */
 int assign_server_address(struct session *s)
 {
-       struct connection *cli_conn = objt_conn(s->req->prod->end);
-       struct connection *srv_conn = objt_conn(s->req->cons->end);
+       struct connection *cli_conn = objt_conn(s->req.prod->end);
+       struct connection *srv_conn = objt_conn(s->req.cons->end);
 
 #ifdef DEBUG_FULL
        fprintf(stderr,"assign_server_address : s=%p\n",s);
@@ -942,7 +942,7 @@ int assign_server_and_queue(struct session *s)
 /* If an explicit source binding is specified on the server and/or backend, and
  * this source makes use of the transparent proxy, then it is extracted now and
  * assigned to the session's pending connection. This function assumes that an
- * outgoing connection has already been assigned to s->req->cons->end.
+ * outgoing connection has already been assigned to s->req.cons->end.
  */
 static void assign_tproxy_address(struct session *s)
 {
@@ -950,7 +950,7 @@ static void assign_tproxy_address(struct session *s)
        struct server *srv = objt_server(s->target);
        struct conn_src *src;
        struct connection *cli_conn;
-       struct connection *srv_conn = objt_conn(s->req->cons->end);
+       struct connection *srv_conn = objt_conn(s->req.cons->end);
 
        if (srv && srv->conn_src.opts & CO_SRC_BIND)
                src = &srv->conn_src;
@@ -966,7 +966,7 @@ static void assign_tproxy_address(struct session *s)
        case CO_SRC_TPROXY_CLI:
        case CO_SRC_TPROXY_CIP:
                /* FIXME: what can we do if the client connects in IPv6 or unix socket ? */
-               cli_conn = objt_conn(s->req->prod->end);
+               cli_conn = objt_conn(s->req.prod->end);
                if (cli_conn)
                        srv_conn->addr.from = cli_conn->addr.from;
                else
@@ -983,13 +983,13 @@ static void assign_tproxy_address(struct session *s)
                        ((struct sockaddr_in *)&srv_conn->addr.from)->sin_port = 0;
                        ((struct sockaddr_in *)&srv_conn->addr.from)->sin_addr.s_addr = 0;
 
-                       b_rew(s->req->buf, rewind = http_hdr_rewind(&s->txn.req));
+                       b_rew(s->req.buf, rewind = http_hdr_rewind(&s->txn.req));
                        if (http_get_hdr(&s->txn.req, src->bind_hdr_name, src->bind_hdr_len,
                                         &s->txn.hdr_idx, src->bind_hdr_occ, NULL, &vptr, &vlen)) {
                                ((struct sockaddr_in *)&srv_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:
@@ -1001,7 +1001,7 @@ static void assign_tproxy_address(struct session *s)
 
 /*
  * This function initiates a connection to the server assigned to this session
- * (s->target, s->req->cons->addr.to). It will assign a server if none
+ * (s->target, s->req.cons->addr.to). It will assign a server if none
  * is assigned yet.
  * It can return one of :
  *  - SN_ERR_NONE if everything's OK
@@ -1012,7 +1012,7 @@ static void assign_tproxy_address(struct session *s)
  *  - SN_ERR_INTERNAL for any other purely internal errors
  * Additionnally, in the case of SN_ERR_RESOURCE, an emergency log will be emitted.
  * The server-facing stream interface is expected to hold a pre-allocated connection
- * in s->req->cons->conn.
+ * in s->req.cons->conn.
  */
 int connect_server(struct session *s)
 {
@@ -1022,7 +1022,7 @@ int connect_server(struct session *s)
        int reuse = 0;
        int err;
 
-       srv_conn = objt_conn(s->req->cons->end);
+       srv_conn = objt_conn(s->req.cons->end);
        if (srv_conn)
                reuse = s->target == srv_conn->target;
 
@@ -1043,7 +1043,7 @@ int connect_server(struct session *s)
                }
        }
 
-       srv_conn = si_alloc_conn(s->req->cons, reuse);
+       srv_conn = si_alloc_conn(s->req.cons, reuse);
        if (!srv_conn)
                return SN_ERR_RESOURCE;
 
@@ -1064,7 +1064,7 @@ int connect_server(struct session *s)
                else if (obj_type(s->target) == OBJ_TYPE_PROXY) {
                        /* proxies exclusively run on raw_sock right now */
                        conn_prepare(srv_conn, protocol_by_family(srv_conn->addr.to.ss_family), &raw_sock);
-                       if (!objt_conn(s->req->cons->end) || !objt_conn(s->req->cons->end)->ctrl)
+                       if (!objt_conn(s->req.cons->end) || !objt_conn(s->req.cons->end)->ctrl)
                                return SN_ERR_INTERNAL;
                }
                else
@@ -1074,36 +1074,36 @@ int connect_server(struct session *s)
                srv_conn->send_proxy_ofs = 0;
                if (objt_server(s->target) && objt_server(s->target)->pp_opts) {
                        srv_conn->send_proxy_ofs = 1; /* must compute size */
-                       cli_conn = objt_conn(s->req->prod->end);
+                       cli_conn = objt_conn(s->req.prod->end);
                        if (cli_conn)
                                conn_get_to_addr(cli_conn);
                }
 
-               si_attach_conn(s->req->cons, srv_conn);
+               si_attach_conn(s->req.cons, srv_conn);
 
                assign_tproxy_address(s);
        }
        else {
                /* the connection is being reused, just re-attach it */
-               si_attach_conn(s->req->cons, srv_conn);
+               si_attach_conn(s->req.cons, srv_conn);
                s->flags |= SN_SRV_REUSED;
        }
 
        /* flag for logging source ip/port */
        if (s->fe->options2 & PR_O2_SRC_ADDR)
-               s->req->cons->flags |= SI_FL_SRC_ADDR;
+               s->req.cons->flags |= SI_FL_SRC_ADDR;
 
        /* disable lingering */
        if (s->be->options & PR_O_TCP_NOLING)
-               s->req->cons->flags |= SI_FL_NOLINGER;
+               s->req.cons->flags |= SI_FL_NOLINGER;
 
-       err = si_connect(s->req->cons);
+       err = si_connect(s->req.cons);
 
        if (err != SN_ERR_NONE)
                return err;
 
        /* set connect timeout */
-       s->req->cons->exp = tick_add_ifset(now_ms, s->be->timeout.connect);
+       s->req.cons->exp = tick_add_ifset(now_ms, s->be->timeout.connect);
 
        srv = objt_server(s->target);
        if (srv) {
@@ -1157,8 +1157,8 @@ int srv_redispatch_connect(struct session *s)
                        goto redispatch;
                }
 
-               if (!s->req->cons->err_type) {
-                       s->req->cons->err_type = SI_ET_QUEUE_ERR;
+               if (!s->req.cons->err_type) {
+                       s->req.cons->err_type = SI_ET_QUEUE_ERR;
                }
 
                srv->counters.failed_conns++;
@@ -1167,23 +1167,23 @@ int srv_redispatch_connect(struct session *s)
 
        case SRV_STATUS_NOSRV:
                /* note: it is guaranteed that srv == NULL here */
-               if (!s->req->cons->err_type) {
-                       s->req->cons->err_type = SI_ET_CONN_ERR;
+               if (!s->req.cons->err_type) {
+                       s->req.cons->err_type = SI_ET_CONN_ERR;
                }
 
                s->be->be_counters.failed_conns++;
                return 1;
 
        case SRV_STATUS_QUEUED:
-               s->req->cons->exp = tick_add_ifset(now_ms, s->be->timeout.queue);
-               s->req->cons->state = SI_ST_QUE;
+               s->req.cons->exp = tick_add_ifset(now_ms, s->be->timeout.queue);
+               s->req.cons->state = SI_ST_QUE;
                /* do nothing else and do not wake any other session up */
                return 1;
 
        case SRV_STATUS_INTERNAL:
        default:
-               if (!s->req->cons->err_type) {
-                       s->req->cons->err_type = SI_ET_CONN_OTHER;
+               if (!s->req.cons->err_type) {
+                       s->req.cons->err_type = SI_ET_CONN_OTHER;
                }
 
                if (srv)
index 133332fbf07192dde25e6372a51cd36b56481c9f..a98eba46f60f4066f5cdce90a87dcabf4bf42bd4 100644 (file)
@@ -246,11 +246,11 @@ static int stats_accept(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->req->flags |= CF_READ_DONTWAIT; /* we plan to read small requests */
+       s->req.flags |= CF_READ_DONTWAIT; /* we plan to read small requests */
 
        if (s->listener->timeout) {
-               s->req->rto = *s->listener->timeout;
-               s->rep->wto = *s->listener->timeout;
+               s->req.rto = *s->listener->timeout;
+               s->res.wto = *s->listener->timeout;
        }
        return 1;
 }
@@ -1488,7 +1488,7 @@ static int stats_sock_parse_request(struct stream_interface *si, char *line)
                                        return 1;
                                }
 
-                               s->req->rto = s->rep->wto = 1 + MS_TO_TICKS(timeout*1000);
+                               s->req.rto = s->res.wto = 1 + MS_TO_TICKS(timeout*1000);
                                return 1;
                        }
                        else {
@@ -5208,60 +5208,60 @@ static int stats_dump_full_sess_to_buffer(struct stream_interface *si, struct se
                chunk_appendf(&trash,
                             "  req=%p (f=0x%06x an=0x%x pipe=%d tofwd=%d total=%lld)\n"
                             "      an_exp=%s",
-                            sess->req,
-                            sess->req->flags, sess->req->analysers,
-                            sess->req->pipe ? sess->req->pipe->data : 0,
-                            sess->req->to_forward, sess->req->total,
-                            sess->req->analyse_exp ?
-                            human_time(TICKS_TO_MS(sess->req->analyse_exp - now_ms),
+                            &sess->req,
+                            sess->req.flags, sess->req.analysers,
+                            sess->req.pipe ? sess->req.pipe->data : 0,
+                            sess->req.to_forward, sess->req.total,
+                            sess->req.analyse_exp ?
+                            human_time(TICKS_TO_MS(sess->req.analyse_exp - now_ms),
                                        TICKS_TO_MS(1000)) : "<NEVER>");
 
                chunk_appendf(&trash,
                             " rex=%s",
-                            sess->req->rex ?
-                            human_time(TICKS_TO_MS(sess->req->rex - now_ms),
+                            sess->req.rex ?
+                            human_time(TICKS_TO_MS(sess->req.rex - now_ms),
                                        TICKS_TO_MS(1000)) : "<NEVER>");
 
                chunk_appendf(&trash,
                             " wex=%s\n"
                             "      buf=%p data=%p o=%d p=%d req.next=%d i=%d size=%d\n",
-                            sess->req->wex ?
-                            human_time(TICKS_TO_MS(sess->req->wex - now_ms),
+                            sess->req.wex ?
+                            human_time(TICKS_TO_MS(sess->req.wex - now_ms),
                                        TICKS_TO_MS(1000)) : "<NEVER>",
-                            sess->req->buf,
-                            sess->req->buf->data, sess->req->buf->o,
-                            (int)(sess->req->buf->p - sess->req->buf->data),
-                            sess->txn.req.next, sess->req->buf->i,
-                            sess->req->buf->size);
+                            sess->req.buf,
+                            sess->req.buf->data, sess->req.buf->o,
+                            (int)(sess->req.buf->p - sess->req.buf->data),
+                            sess->txn.req.next, sess->req.buf->i,
+                            sess->req.buf->size);
 
                chunk_appendf(&trash,
                             "  res=%p (f=0x%06x an=0x%x pipe=%d tofwd=%d total=%lld)\n"
                             "      an_exp=%s",
-                            sess->rep,
-                            sess->rep->flags, sess->rep->analysers,
-                            sess->rep->pipe ? sess->rep->pipe->data : 0,
-                            sess->rep->to_forward, sess->rep->total,
-                            sess->rep->analyse_exp ?
-                            human_time(TICKS_TO_MS(sess->rep->analyse_exp - now_ms),
+                            &sess->res,
+                            sess->res.flags, sess->res.analysers,
+                            sess->res.pipe ? sess->res.pipe->data : 0,
+                            sess->res.to_forward, sess->res.total,
+                            sess->res.analyse_exp ?
+                            human_time(TICKS_TO_MS(sess->res.analyse_exp - now_ms),
                                        TICKS_TO_MS(1000)) : "<NEVER>");
 
                chunk_appendf(&trash,
                             " rex=%s",
-                            sess->rep->rex ?
-                            human_time(TICKS_TO_MS(sess->rep->rex - now_ms),
+                            sess->res.rex ?
+                            human_time(TICKS_TO_MS(sess->res.rex - now_ms),
                                        TICKS_TO_MS(1000)) : "<NEVER>");
 
                chunk_appendf(&trash,
                             " wex=%s\n"
                             "      buf=%p data=%p o=%d p=%d rsp.next=%d i=%d size=%d\n",
-                            sess->rep->wex ?
-                            human_time(TICKS_TO_MS(sess->rep->wex - now_ms),
+                            sess->res.wex ?
+                            human_time(TICKS_TO_MS(sess->res.wex - now_ms),
                                        TICKS_TO_MS(1000)) : "<NEVER>",
-                            sess->rep->buf,
-                            sess->rep->buf->data, sess->rep->buf->o,
-                            (int)(sess->rep->buf->p - sess->rep->buf->data),
-                            sess->txn.rsp.next, sess->rep->buf->i,
-                            sess->rep->buf->size);
+                            sess->res.buf,
+                            sess->res.buf->data, sess->res.buf->o,
+                            (int)(sess->res.buf->p - sess->res.buf->data),
+                            sess->txn.rsp.next, sess->res.buf->i,
+                            sess->res.buf->size);
 
                if (bi_putchk(si->ib, &trash) == -1)
                        return 0;
@@ -5613,44 +5613,44 @@ static int stats_dump_sess_to_buffer(struct stream_interface *si)
 
                        chunk_appendf(&trash,
                                     " rq[f=%06xh,i=%d,an=%02xh,rx=%s",
-                                    curr_sess->req->flags,
-                                    curr_sess->req->buf->i,
-                                    curr_sess->req->analysers,
-                                    curr_sess->req->rex ?
-                                    human_time(TICKS_TO_MS(curr_sess->req->rex - now_ms),
+                                    curr_sess->req.flags,
+                                    curr_sess->req.buf->i,
+                                    curr_sess->req.analysers,
+                                    curr_sess->req.rex ?
+                                    human_time(TICKS_TO_MS(curr_sess->req.rex - now_ms),
                                                TICKS_TO_MS(1000)) : "");
 
                        chunk_appendf(&trash,
                                     ",wx=%s",
-                                    curr_sess->req->wex ?
-                                    human_time(TICKS_TO_MS(curr_sess->req->wex - now_ms),
+                                    curr_sess->req.wex ?
+                                    human_time(TICKS_TO_MS(curr_sess->req.wex - now_ms),
                                                TICKS_TO_MS(1000)) : "");
 
                        chunk_appendf(&trash,
                                     ",ax=%s]",
-                                    curr_sess->req->analyse_exp ?
-                                    human_time(TICKS_TO_MS(curr_sess->req->analyse_exp - now_ms),
+                                    curr_sess->req.analyse_exp ?
+                                    human_time(TICKS_TO_MS(curr_sess->req.analyse_exp - now_ms),
                                                TICKS_TO_MS(1000)) : "");
 
                        chunk_appendf(&trash,
                                     " rp[f=%06xh,i=%d,an=%02xh,rx=%s",
-                                    curr_sess->rep->flags,
-                                    curr_sess->rep->buf->i,
-                                    curr_sess->rep->analysers,
-                                    curr_sess->rep->rex ?
-                                    human_time(TICKS_TO_MS(curr_sess->rep->rex - now_ms),
+                                    curr_sess->res.flags,
+                                    curr_sess->res.buf->i,
+                                    curr_sess->res.analysers,
+                                    curr_sess->res.rex ?
+                                    human_time(TICKS_TO_MS(curr_sess->res.rex - now_ms),
                                                TICKS_TO_MS(1000)) : "");
 
                        chunk_appendf(&trash,
                                     ",wx=%s",
-                                    curr_sess->rep->wex ?
-                                    human_time(TICKS_TO_MS(curr_sess->rep->wex - now_ms),
+                                    curr_sess->res.wex ?
+                                    human_time(TICKS_TO_MS(curr_sess->res.wex - now_ms),
                                                TICKS_TO_MS(1000)) : "");
 
                        chunk_appendf(&trash,
                                     ",ax=%s]",
-                                    curr_sess->rep->analyse_exp ?
-                                    human_time(TICKS_TO_MS(curr_sess->rep->analyse_exp - now_ms),
+                                    curr_sess->res.analyse_exp ?
+                                    human_time(TICKS_TO_MS(curr_sess->res.analyse_exp - now_ms),
                                                TICKS_TO_MS(1000)) : "");
 
                        conn = objt_conn(curr_sess->si[0].end);
index c5301af1926c8621bd39f9df0109d8e9669a6a55..48dabe89864d3d6f5b2abb14eba8f844fcfd0bc2 100644 (file)
@@ -189,16 +189,16 @@ int frontend_accept(struct session *s)
        }
 
        if (s->fe->mode == PR_MODE_HTTP)
-               s->req->flags |= CF_READ_DONTWAIT; /* one read is usually enough */
+               s->req.flags |= CF_READ_DONTWAIT; /* one read is usually enough */
 
        /* note: this should not happen anymore since there's always at least the switching rules */
-       if (!s->req->analysers) {
-               channel_auto_connect(s->req);  /* don't wait to establish connection */
-               channel_auto_close(s->req);    /* let the producer forward close requests */
+       if (!s->req.analysers) {
+               channel_auto_connect(&s->req);  /* don't wait to establish connection */
+               channel_auto_close(&s->req);    /* let the producer forward close requests */
        }
 
-       s->req->rto = s->fe->timeout.client;
-       s->rep->wto = s->fe->timeout.client;
+       s->req.rto = s->fe->timeout.client;
+       s->res.wto = s->fe->timeout.client;
 
        /* everything's OK, let's go on */
        return 1;
index 9a6bd33b0338614dbc9baff9474bf84af983ab11..0fe625a25e9885c51532e1bb82d7f541f8290b9f 100644 (file)
@@ -1424,7 +1424,7 @@ static int hlua_socket_write_yield(struct lua_State *L,int status, lua_KContext
        sent = MAY_LJMP(luaL_checkinteger(L, 3));
 
        /* Check for connection close. */
-       if (!socket->s || channel_output_closed(socket->s->req)) {
+       if (!socket->s || channel_output_closed(&socket->s->req)) {
                lua_pushinteger(L, -1);
                return 1;
        }
@@ -1440,9 +1440,9 @@ static int hlua_socket_write_yield(struct lua_State *L,int status, lua_KContext
        /* Check if the buffer is avalaible because HAProxy doesn't allocate
         * the request buffer if its not required.
         */
-       if (socket->s->req->buf->size == 0) {
-               if (!session_alloc_recv_buffer(socket->s, &socket->s->req->buf)) {
-                       socket->s->req->prod->flags |= SI_FL_WAIT_ROOM;
+       if (socket->s->req.buf->size == 0) {
+               if (!session_alloc_recv_buffer(socket->s, &socket->s->req.buf)) {
+                       socket->s->req.prod->flags |= SI_FL_WAIT_ROOM;
                        goto hlua_socket_write_yield_return;
                }
        }
@@ -1700,7 +1700,7 @@ __LJMP static int hlua_socket_connect_yield(struct lua_State *L, int status, lua
        struct appctx *appctx;
 
        /* Check for connection close. */
-       if (!hlua || !socket->s || channel_output_closed(socket->s->req)) {
+       if (!hlua || !socket->s || channel_output_closed(&socket->s->req)) {
                lua_pushnil(L);
                lua_pushstring(L, "Can't connect");
                return 2;
@@ -1737,7 +1737,7 @@ __LJMP static int hlua_socket_connect(struct lua_State *L)
        ip      = MAY_LJMP(luaL_checkstring(L, 2));
        port    = MAY_LJMP(luaL_checkinteger(L, 3));
 
-       conn = si_alloc_conn(socket->s->req->cons, 0);
+       conn = si_alloc_conn(socket->s->req.cons, 0);
        if (!conn)
                WILL_LJMP(luaL_error(L, "connect: internal error"));
 
@@ -1794,10 +1794,10 @@ __LJMP static int hlua_socket_settimeout(struct lua_State *L)
        socket = MAY_LJMP(hlua_checksocket(L, 1));
        tmout = MAY_LJMP(luaL_checkinteger(L, 2)) * 1000;
 
-       socket->s->req->rto = tmout;
-       socket->s->req->wto = tmout;
-       socket->s->rep->rto = tmout;
-       socket->s->rep->wto = tmout;
+       socket->s->req.rto = tmout;
+       socket->s->req.wto = tmout;
+       socket->s->res.rto = tmout;
+       socket->s->res.wto = tmout;
 
        return 0;
 }
@@ -1847,26 +1847,14 @@ __LJMP static int hlua_socket_new(lua_State *L)
                goto out_free_session;
        }
 
-       socket->s->req = pool_alloc2(pool2_channel);
-       if (!socket->s->req) {
-               hlua_pusherror(L, "socket: out of memory");
-               goto out_fail_req;
-       }
-
-       socket->s->req->buf = pool_alloc2(pool2_buffer);
-       if (!socket->s->req->buf) {
+       socket->s->req.buf = pool_alloc2(pool2_buffer);
+       if (!socket->s->req.buf) {
                hlua_pusherror(L, "socket: out of memory");
                goto out_fail_req_buf;
        }
 
-       socket->s->rep = pool_alloc2(pool2_channel);
-       if (!socket->s->rep) {
-               hlua_pusherror(L, "socket: out of memory");
-               goto out_fail_rep;
-       }
-
-       socket->s->rep->buf = pool_alloc2(pool2_buffer);
-       if (!socket->s->rep->buf) {
+       socket->s->res.buf = pool_alloc2(pool2_buffer);
+       if (!socket->s->res.buf) {
                hlua_pusherror(L, "socket: out of memory");
                goto out_fail_rep_buf;
        }
@@ -1909,8 +1897,8 @@ __LJMP static int hlua_socket_new(lua_State *L)
         * Initialize the attached buffers
         *
         */
-       socket->s->req->buf->size = global.tune.bufsize;
-       socket->s->rep->buf->size = global.tune.bufsize;
+       socket->s->req.buf->size = global.tune.bufsize;
+       socket->s->res.buf->size = global.tune.bufsize;
 
        /*
         *
@@ -1921,34 +1909,34 @@ __LJMP static int hlua_socket_new(lua_State *L)
        /* This function reset the struct. It must be called
         * before the configuration.
         */
-       channel_init(socket->s->req);
-       channel_init(socket->s->rep);
+       channel_init(&socket->s->req);
+       channel_init(&socket->s->res);
 
-       socket->s->req->prod = &socket->s->si[0];
-       socket->s->req->cons = &socket->s->si[1];
+       socket->s->req.prod = &socket->s->si[0];
+       socket->s->req.cons = &socket->s->si[1];
 
-       socket->s->rep->prod = &socket->s->si[1];
-       socket->s->rep->cons = &socket->s->si[0];
+       socket->s->res.prod = &socket->s->si[1];
+       socket->s->res.cons = &socket->s->si[0];
 
-       socket->s->si[0].ib = socket->s->req;
-       socket->s->si[0].ob = socket->s->rep;
+       socket->s->si[0].ib = &socket->s->req;
+       socket->s->si[0].ob = &socket->s->res;
 
-       socket->s->si[1].ib = socket->s->rep;
-       socket->s->si[1].ob = socket->s->req;
+       socket->s->si[1].ib = &socket->s->res;
+       socket->s->si[1].ob = &socket->s->req;
 
-       socket->s->req->analysers = 0;
-       socket->s->req->rto = socket_proxy.timeout.client;
-       socket->s->req->wto = socket_proxy.timeout.server;
-       socket->s->req->rex = TICK_ETERNITY;
-       socket->s->req->wex = TICK_ETERNITY;
-       socket->s->req->analyse_exp = TICK_ETERNITY;
+       socket->s->req.analysers = 0;
+       socket->s->req.rto = socket_proxy.timeout.client;
+       socket->s->req.wto = socket_proxy.timeout.server;
+       socket->s->req.rex = TICK_ETERNITY;
+       socket->s->req.wex = TICK_ETERNITY;
+       socket->s->req.analyse_exp = TICK_ETERNITY;
 
-       socket->s->rep->analysers = 0;
-       socket->s->rep->rto = socket_proxy.timeout.server;
-       socket->s->rep->wto = socket_proxy.timeout.client;
-       socket->s->rep->rex = TICK_ETERNITY;
-       socket->s->rep->wex = TICK_ETERNITY;
-       socket->s->rep->analyse_exp = TICK_ETERNITY;
+       socket->s->res.analysers = 0;
+       socket->s->res.rto = socket_proxy.timeout.server;
+       socket->s->res.wto = socket_proxy.timeout.client;
+       socket->s->res.rex = TICK_ETERNITY;
+       socket->s->res.wex = TICK_ETERNITY;
+       socket->s->res.analyse_exp = TICK_ETERNITY;
 
        /*
         *
@@ -2009,10 +1997,10 @@ __LJMP static int hlua_socket_new(lua_State *L)
         */
 
        /* The data producer is already connected. It is the applet. */
-       socket->s->req->flags = CF_READ_ATTACHED;
+       socket->s->req.flags = CF_READ_ATTACHED;
 
-       channel_auto_connect(socket->s->req); /* don't wait to establish connection */
-       channel_auto_close(socket->s->req); /* let the producer forward close requests */
+       channel_auto_connect(&socket->s->req); /* don't wait to establish connection */
+       channel_auto_close(&socket->s->req); /* let the producer forward close requests */
 
        si_reset(&socket->s->si[0], socket->s->task);
        si_set_state(&socket->s->si[0], SI_ST_EST); /* connection established (resource exists) */
@@ -2052,14 +2040,10 @@ __LJMP static int hlua_socket_new(lua_State *L)
        return 1;
 
 out_fail_conn1:
-       pool_free2(pool2_buffer, socket->s->rep->buf);
+       pool_free2(pool2_buffer, socket->s->res.buf);
 out_fail_rep_buf:
-       pool_free2(pool2_channel, socket->s->rep);
-out_fail_rep:
-       pool_free2(pool2_buffer, socket->s->req->buf);
+       pool_free2(pool2_buffer, socket->s->req.buf);
 out_fail_req_buf:
-       pool_free2(pool2_channel, socket->s->req);
-out_fail_req:
        task_free(socket->s->task);
 out_free_session:
        pool_free2(pool2_session, socket->s);
@@ -2405,7 +2389,7 @@ __LJMP static int hlua_channel_send_yield(lua_State *L, int status, lua_KContext
                 * must set the flag WAKERESWR. This flag required the task
                 * wake up if any activity is detected on the response buffer.
                 */
-               if (chn->chn == chn->s->rep)
+               if (chn->chn == &chn->s->res)
                        HLUA_SET_WAKERESWR(hlua);
                else
                        HLUA_SET_WAKEREQWR(hlua);
@@ -2467,7 +2451,7 @@ __LJMP static int hlua_channel_forward_yield(lua_State *L, int status, lua_KCont
                 * must set the flag WAKERESWR. This flag required the task
                 * wake up if any activity is detected on the response buffer.
                 */
-               if (chn->chn == chn->s->rep)
+               if (chn->chn == &chn->s->res)
                        HLUA_SET_WAKERESWR(hlua);
                else
                        HLUA_SET_WAKEREQWR(hlua);
@@ -2849,13 +2833,13 @@ static int hlua_txn_new(lua_State *L, struct session *s, struct proxy *p, void *
 
        /* Create the "req" field that contains the request channel object. */
        lua_pushstring(L, "req");
-       if (!hlua_channel_new(L, s, s->req))
+       if (!hlua_channel_new(L, s, &s->req))
                return 0;
        lua_settable(L, -3);
 
        /* Create the "res" field that contains the response channel object. */
        lua_pushstring(L, "res");
-       if (!hlua_channel_new(L, s, s->rep))
+       if (!hlua_channel_new(L, s, &s->res))
                return 0;
        lua_settable(L, -3);
 
@@ -2904,7 +2888,7 @@ static int hlua_session_get_headers(lua_State *L)
 
        /* Build array of headers. */
        old_idx = 0;
-       cur_next = sess->req->buf->p + hdr_idx_first_pos(&sess->txn.hdr_idx);
+       cur_next = sess->req.buf->p + hdr_idx_first_pos(&sess->txn.hdr_idx);
 
        while (1) {
                cur_idx = sess->txn.hdr_idx.v[old_idx].next;
@@ -3606,21 +3590,21 @@ static int hlua_request_act_wrapper(struct hlua_rule *rule, struct proxy *px,
                /* Set timeout in the required channel. */
                if (s->hlua.wake_time != TICK_ETERNITY) {
                        if (analyzer & (AN_REQ_INSPECT_FE|AN_REQ_HTTP_PROCESS_FE))
-                               s->req->analyse_exp = s->hlua.wake_time;
+                               s->req.analyse_exp = s->hlua.wake_time;
                        else if (analyzer & (AN_RES_INSPECT|AN_RES_HTTP_PROCESS_BE))
-                               s->rep->analyse_exp = s->hlua.wake_time;
+                               s->res.analyse_exp = s->hlua.wake_time;
                }
                /* Some actions can be wake up when a "write" event
                 * is detected on a response channel. This is useful
                 * only for actions targetted on the requests.
                 */
                if (HLUA_IS_WAKERESWR(&s->hlua)) {
-                       s->rep->flags |= CF_WAKE_WRITE;
+                       s->res.flags |= CF_WAKE_WRITE;
                        if ((analyzer & (AN_REQ_INSPECT_FE|AN_REQ_HTTP_PROCESS_FE)))
-                               s->rep->analysers |= analyzer;
+                               s->res.analysers |= analyzer;
                }
                if (HLUA_IS_WAKEREQWR(&s->hlua))
-                       s->req->flags |= CF_WAKE_WRITE;
+                       s->req.flags |= CF_WAKE_WRITE;
                return 0;
 
        /* finished with error. */
index f7d160dcfd70ee6ad84bcbf37657b960bbfc70d6..77c7b71a2428e9267da2b65e218391b37c283b02 100644 (file)
--- a/src/log.c
+++ b/src/log.c
@@ -984,7 +984,7 @@ int build_logline(struct session *s, char *dst, size_t maxsize, struct list *lis
                                break;
 
                        case LOG_FMT_CLIENTIP:  // %ci
-                               conn = objt_conn(s->req->prod->end);
+                               conn = objt_conn(s->req.prod->end);
                                if (conn)
                                        ret = lf_ip(tmplog, (struct sockaddr *)&conn->addr.from, dst + maxsize - tmplog, tmp);
                                else
@@ -996,7 +996,7 @@ int build_logline(struct session *s, char *dst, size_t maxsize, struct list *lis
                                break;
 
                        case LOG_FMT_CLIENTPORT:  // %cp
-                               conn = objt_conn(s->req->prod->end);
+                               conn = objt_conn(s->req.prod->end);
                                if (conn) {
                                        if (conn->addr.from.ss_family == AF_UNIX) {
                                                ret = ltoa_o(s->listener->luid, tmplog, dst + maxsize - tmplog);
@@ -1015,7 +1015,7 @@ int build_logline(struct session *s, char *dst, size_t maxsize, struct list *lis
                                break;
 
                        case LOG_FMT_FRONTENDIP: // %fi
-                               conn = objt_conn(s->req->prod->end);
+                               conn = objt_conn(s->req.prod->end);
                                if (conn) {
                                        conn_get_to_addr(conn);
                                        ret = lf_ip(tmplog, (struct sockaddr *)&conn->addr.to, dst + maxsize - tmplog, tmp);
@@ -1030,7 +1030,7 @@ int build_logline(struct session *s, char *dst, size_t maxsize, struct list *lis
                                break;
 
                        case  LOG_FMT_FRONTENDPORT: // %fp
-                               conn = objt_conn(s->req->prod->end);
+                               conn = objt_conn(s->req.prod->end);
                                if (conn) {
                                        conn_get_to_addr(conn);
                                        if (conn->addr.to.ss_family == AF_UNIX)
@@ -1048,7 +1048,7 @@ int build_logline(struct session *s, char *dst, size_t maxsize, struct list *lis
                                break;
 
                        case LOG_FMT_BACKENDIP:  // %bi
-                               conn = objt_conn(s->req->cons->end);
+                               conn = objt_conn(s->req.cons->end);
                                if (conn)
                                        ret = lf_ip(tmplog, (struct sockaddr *)&conn->addr.from, dst + maxsize - tmplog, tmp);
                                else
@@ -1061,7 +1061,7 @@ int build_logline(struct session *s, char *dst, size_t maxsize, struct list *lis
                                break;
 
                        case LOG_FMT_BACKENDPORT:  // %bp
-                               conn = objt_conn(s->req->cons->end);
+                               conn = objt_conn(s->req.cons->end);
                                if (conn)
                                        ret = lf_port(tmplog, (struct sockaddr *)&conn->addr.from, dst + maxsize - tmplog, tmp);
                                else
@@ -1074,7 +1074,7 @@ int build_logline(struct session *s, char *dst, size_t maxsize, struct list *lis
                                break;
 
                        case LOG_FMT_SERVERIP: // %si
-                               conn = objt_conn(s->req->cons->end);
+                               conn = objt_conn(s->req.cons->end);
                                if (conn)
                                        ret = lf_ip(tmplog, (struct sockaddr *)&conn->addr.to, dst + maxsize - tmplog, tmp);
                                else
@@ -1087,7 +1087,7 @@ int build_logline(struct session *s, char *dst, size_t maxsize, struct list *lis
                                break;
 
                        case LOG_FMT_SERVERPORT: // %sp
-                               conn = objt_conn(s->req->cons->end);
+                               conn = objt_conn(s->req.cons->end);
                                if (conn)
                                        ret = lf_port(tmplog, (struct sockaddr *)&conn->addr.to, dst + maxsize - tmplog, tmp);
                                else
@@ -1386,8 +1386,8 @@ int build_logline(struct session *s, char *dst, size_t maxsize, struct list *lis
                        case LOG_FMT_RETRIES:  // %rq
                                if (s->flags & SN_REDISP)
                                        LOGCHAR('+');
-                               ret = ltoa_o((s->req->cons->conn_retries>0) ?
-                                               (be->conn_retries - s->req->cons->conn_retries) :
+                               ret = ltoa_o((s->req.cons->conn_retries>0) ?
+                                               (be->conn_retries - s->req.cons->conn_retries) :
                                                be->conn_retries, tmplog, dst + maxsize - tmplog);
                                if (ret == NULL)
                                        goto out;
@@ -1611,7 +1611,7 @@ void sess_log(struct session *s)
        err = (s->flags & SN_REDISP) ||
               ((s->flags & SN_ERR_MASK) > SN_ERR_LOCAL) ||
              (((s->flags & SN_ERR_MASK) == SN_ERR_NONE) &&
-              (s->req->cons->conn_retries != s->be->conn_retries)) ||
+              (s->req.cons->conn_retries != s->be->conn_retries)) ||
              ((s->fe->mode == PR_MODE_HTTP) && s->txn.status >= 500);
 
        if (!err && (s->fe->options2 & PR_O2_NOLOGNORM))
index 53c997285087a64f0d703519d8d64db47bb2ef22..b5d8478bab98c6aa5c6bbc0af4ba27974fe59133 100644 (file)
@@ -46,9 +46,13 @@ static int
 smp_fetch_len(struct proxy *px, struct session *s, void *l7, unsigned int opt,
                   const struct arg *args, struct sample *smp, const char *kw, void *private)
 {
-       struct channel *chn = ((opt & SMP_OPT_DIR) == SMP_OPT_DIR_RES) ? s->rep : s->req;
+       struct channel *chn;
+
+       if (!s)
+               return 0;
 
-       if (!s || !chn)
+       chn = ((opt & SMP_OPT_DIR) == SMP_OPT_DIR_RES) ? &s->res : &s->req;
+       if (!chn->buf)
                return 0;
 
        smp->type = SMP_T_UINT;
@@ -70,9 +74,8 @@ smp_fetch_ssl_hello_type(struct proxy *px, struct session *s, void *l7, unsigned
        if (!s)
                goto not_ssl_hello;
 
-       chn = ((opt & SMP_OPT_DIR) == SMP_OPT_DIR_RES) ? s->rep : s->req;
-
-       if (!chn)
+       chn = ((opt & SMP_OPT_DIR) == SMP_OPT_DIR_RES) ? &s->res : &s->req;
+       if (!chn->buf)
                goto not_ssl_hello;
 
        bleft = chn->buf->i;
@@ -137,15 +140,15 @@ smp_fetch_req_ssl_ver(struct proxy *px, struct session *s, void *l7, unsigned in
        int version, bleft, msg_len;
        const unsigned char *data;
 
-       if (!s || !s->req)
+       if (!s || !s->req.buf)
                return 0;
 
        msg_len = 0;
-       bleft = s->req->buf->i;
+       bleft = s->req.buf->i;
        if (!bleft)
                goto too_short;
 
-       data = (const unsigned char *)s->req->buf->p;
+       data = (const unsigned char *)s->req.buf->p;
        if ((*data >= 0x14 && *data <= 0x17) || (*data == 0xFF)) {
                /* SSLv3 header format */
                if (bleft < 5)
@@ -213,8 +216,8 @@ smp_fetch_req_ssl_ver(struct proxy *px, struct session *s, void *l7, unsigned in
         * all the part of the request which fits in a buffer is already
         * there.
         */
-       if (msg_len > channel_recv_limit(s->req) + s->req->buf->data - s->req->buf->p)
-               msg_len = channel_recv_limit(s->req) + s->req->buf->data - s->req->buf->p;
+       if (msg_len > channel_recv_limit(&s->req) + s->req.buf->data - s->req.buf->p)
+               msg_len = channel_recv_limit(&s->req) + s->req.buf->data - s->req.buf->p;
 
        if (bleft < msg_len)
                goto too_short;
@@ -277,9 +280,8 @@ smp_fetch_ssl_hello_sni(struct proxy *px, struct session *s, void *l7, unsigned
        if (!s)
                goto not_ssl_hello;
 
-       chn = ((opt & SMP_OPT_DIR) == SMP_OPT_DIR_RES) ? s->rep : s->req;
-
-       if (!chn)
+       chn = ((opt & SMP_OPT_DIR) == SMP_OPT_DIR_RES) ? &s->res : &s->req;
+       if (!chn->buf)
                goto not_ssl_hello;
 
        bleft = chn->buf->i;
@@ -413,17 +415,17 @@ fetch_rdp_cookie_name(struct session *s, struct sample *smp, const char *cname,
        int bleft;
        const unsigned char *data;
 
-       if (!s || !s->req)
+       if (!s || !s->req.buf)
                return 0;
 
        smp->flags = SMP_F_CONST;
        smp->type = SMP_T_STR;
 
-       bleft = s->req->buf->i;
+       bleft = s->req.buf->i;
        if (bleft <= 11)
                goto too_short;
 
-       data = (const unsigned char *)s->req->buf->p + 11;
+       data = (const unsigned char *)s->req.buf->p + 11;
        bleft -= 11;
 
        if (bleft <= 7)
@@ -543,9 +545,8 @@ smp_fetch_payload_lv(struct proxy *px, struct session *s, void *l7, unsigned int
        if (!s)
                return 0;
 
-       chn = ((opt & SMP_OPT_DIR) == SMP_OPT_DIR_RES) ? s->rep : s->req;
-
-       if (!chn)
+       chn = ((opt & SMP_OPT_DIR) == SMP_OPT_DIR_RES) ? &s->res : &s->req;
+       if (!chn->buf)
                return 0;
 
        if (len_offset + len_size > chn->buf->i)
@@ -594,9 +595,8 @@ smp_fetch_payload(struct proxy *px, struct session *s, void *l7, unsigned int op
        if (!s)
                return 0;
 
-       chn = ((opt & SMP_OPT_DIR) == SMP_OPT_DIR_RES) ? s->rep : s->req;
-
-       if (!chn)
+       chn = ((opt & SMP_OPT_DIR) == SMP_OPT_DIR_RES) ? &s->res : &s->req;
+       if (!chn->buf)
                return 0;
 
        if (buf_size > chn->buf->size || buf_offset + buf_size > chn->buf->size) {
index 2357c0cabef143b3ce6b9e65df5f182011628bac..c87c8a50433be27669b5c588cd0f52d75b5613e3 100644 (file)
 #include <proto/proto_http.h>
 #include <proto/proxy.h>
 #include <proto/session.h>
+#include <proto/signal.h>
+#include <proto/stick_table.h>
 #include <proto/stream_interface.h>
 #include <proto/task.h>
-#include <proto/stick_table.h>
-#include <proto/signal.h>
 
 
 /*******************************/
@@ -1105,11 +1105,11 @@ int peer_accept(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->req->flags |= CF_READ_DONTWAIT; /* we plan to read small requests */
+       s->req.flags |= CF_READ_DONTWAIT; /* we plan to read small requests */
 
        if (s->listener->timeout) {
-               s->req->rto = *s->listener->timeout;
-               s->rep->wto = *s->listener->timeout;
+               s->req.rto = *s->listener->timeout;
+               s->res.wto = *s->listener->timeout;
        }
        return 1;
 }
@@ -1161,8 +1161,7 @@ static struct session *peer_session_create(struct peer *peer, struct peer_sessio
         * when the default backend is assigned.
         */
        s->be = s->fe = p;
-
-       s->req = s->rep = NULL; /* will be allocated later */
+       s->req.buf = s->res.buf = NULL;
 
        si_reset(&s->si[0], t);
        si_set_state(&s->si[0], SI_ST_EST);
@@ -1235,48 +1234,42 @@ static struct session *peer_session_create(struct peer *peer, struct peer_sessio
        txn->hdr_idx.v = NULL;
        txn->hdr_idx.size = txn->hdr_idx.used = 0;
 
-       if ((s->req = pool_alloc2(pool2_channel)) == NULL)
-               goto out_fail_req; /* no memory */
-
-       channel_init(s->req);
-       s->req->prod = &s->si[0];
-       s->req->cons = &s->si[1];
-       s->si[0].ib = s->si[1].ob = s->req;
+       channel_init(&s->req);
+       s->req.prod = &s->si[0];
+       s->req.cons = &s->si[1];
+       s->si[0].ib = s->si[1].ob = &s->req;
 
-       s->req->flags |= CF_READ_ATTACHED; /* the producer is already connected */
+       s->req.flags |= CF_READ_ATTACHED; /* the producer is already connected */
 
        /* activate default analysers enabled for this listener */
-       s->req->analysers = l->analysers;
+       s->req.analysers = l->analysers;
 
        /* note: this should not happen anymore since there's always at least the switching rules */
-       if (!s->req->analysers) {
-               channel_auto_connect(s->req);/* don't wait to establish connection */
-               channel_auto_close(s->req);/* let the producer forward close requests */
+       if (!s->req.analysers) {
+               channel_auto_connect(&s->req);/* don't wait to establish connection */
+               channel_auto_close(&s->req);/* let the producer forward close requests */
        }
 
-       s->req->rto = s->fe->timeout.client;
-       s->req->wto = s->be->timeout.server;
-
-       if ((s->rep = pool_alloc2(pool2_channel)) == NULL)
-               goto out_fail_rep; /* no memory */
+       s->req.rto = s->fe->timeout.client;
+       s->req.wto = s->be->timeout.server;
 
-       channel_init(s->rep);
-       s->rep->prod = &s->si[1];
-       s->rep->cons = &s->si[0];
-       s->si[0].ob = s->si[1].ib = s->rep;
+       channel_init(&s->res);
+       s->res.prod = &s->si[1];
+       s->res.cons = &s->si[0];
+       s->si[0].ob = s->si[1].ib = &s->res;
 
-       s->rep->rto = s->be->timeout.server;
-       s->rep->wto = s->fe->timeout.client;
+       s->res.rto = s->be->timeout.server;
+       s->res.wto = s->fe->timeout.client;
 
-       s->req->rex = TICK_ETERNITY;
-       s->req->wex = TICK_ETERNITY;
-       s->req->analyse_exp = TICK_ETERNITY;
-       s->rep->rex = TICK_ETERNITY;
-       s->rep->wex = TICK_ETERNITY;
-       s->rep->analyse_exp = TICK_ETERNITY;
+       s->req.rex = TICK_ETERNITY;
+       s->req.wex = TICK_ETERNITY;
+       s->req.analyse_exp = TICK_ETERNITY;
+       s->res.rex = TICK_ETERNITY;
+       s->res.wex = TICK_ETERNITY;
+       s->res.analyse_exp = TICK_ETERNITY;
        t->expire = TICK_ETERNITY;
 
-       s->rep->flags |= CF_READ_DONTWAIT;
+       s->res.flags |= CF_READ_DONTWAIT;
 
        /* it is important not to call the wakeup function directly but to
         * pass through task_wakeup(), because this one knows how to apply
@@ -1294,10 +1287,6 @@ static struct session *peer_session_create(struct peer *peer, struct peer_sessio
        return s;
 
        /* Error unrolling */
- out_fail_rep:
-       pool_free2(pool2_channel, s->req);
- out_fail_req:
-       conn_free(conn);
  out_fail_conn1:
        task_free(t);
  out_free_session:
index f0f4cba49cedaebffbbb9fa44d0e0c6b79d8e8a9..a88c77c25d01f448697645e46851f3f4cee51a1d 100644 (file)
@@ -1001,12 +1001,12 @@ void http_perform_server_redirect(struct session *s, struct stream_interface *si
         * to temporarily rewind the buffer.
         */
        txn = &s->txn;
-       b_rew(s->req->buf, rewind = http_hdr_rewind(&txn->req));
+       b_rew(s->req.buf, rewind = http_hdr_rewind(&txn->req));
 
        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;
@@ -1460,7 +1460,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;
@@ -2514,7 +2514,7 @@ void http_adjust_conn_mode(struct session *s, struct http_txn *txn, struct http_
 /* This stream analyser waits for a complete HTTP request. It returns 1 if the
  * processing can continue on next analysers, or zero if it either needs more
  * data or wants to immediately abort the request (eg: timeout, error, ...). It
- * is tied to AN_REQ_WAIT_HTTP and may may remove itself from s->req->analysers
+ * is tied to AN_REQ_WAIT_HTTP and may may remove itself from s->req.analysers
  * when it has nothing left to do, and may remove any analyser when it wants to
  * abort.
  */
@@ -2588,17 +2588,17 @@ int http_wait_for_request(struct session *s, struct channel *req, int an_bit)
                 * keep-alive requests.
                 */
                if ((txn->flags & TX_NOT_FIRST) &&
-                   unlikely(!channel_is_rewritable(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) {
-                               if (s->rep->flags & (CF_SHUTW|CF_SHUTW_NOW|CF_WRITE_ERROR|CF_WRITE_TIMEOUT))
+                   unlikely(!channel_is_rewritable(&s->res) ||
+                            bi_end(s->res.buf) < b_ptr(s->res.buf, txn->rsp.next) ||
+                            bi_end(s->res.buf) > s->res.buf->data + s->res.buf->size - global.tune.maxrewrite)) {
+                       if (s->res.buf->o) {
+                               if (s->res.flags & (CF_SHUTW|CF_SHUTW_NOW|CF_WRITE_ERROR|CF_WRITE_TIMEOUT))
                                        goto failed_keep_alive;
                                /* don't let a connection request be initiated */
                                channel_dont_connect(req);
-                               s->rep->flags &= ~CF_EXPECT_MORE; /* speed up sending a previous response */
-                               s->rep->flags |= CF_WAKE_WRITE;
-                               s->rep->analysers |= an_bit; /* wake us up once it changes */
+                               s->res.flags &= ~CF_EXPECT_MORE; /* speed up sending a previous response */
+                               s->res.flags |= CF_WAKE_WRITE;
+                               s->res.analysers |= an_bit; /* wake us up once it changes */
                                return 0;
                        }
                }
@@ -2765,14 +2765,14 @@ int http_wait_for_request(struct session *s, struct channel *req, int an_bit)
 
                channel_dont_connect(req);
                req->flags |= CF_READ_DONTWAIT; /* try to get back here ASAP */
-               s->rep->flags &= ~CF_EXPECT_MORE; /* speed up sending a previous response */
+               s->res.flags &= ~CF_EXPECT_MORE; /* speed up sending a previous response */
 #ifdef TCP_QUICKACK
-               if (s->listener->options & LI_O_NOQUICKACK && req->buf->i && objt_conn(s->req->prod->end) && conn_ctrl_ready(__objt_conn(s->req->prod->end))) {
+               if (s->listener->options & LI_O_NOQUICKACK && req->buf->i && objt_conn(s->req.prod->end) && conn_ctrl_ready(__objt_conn(s->req.prod->end))) {
                        /* 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.
                         */
-                       setsockopt(__objt_conn(s->req->prod->end)->t.sock.fd, IPPROTO_TCP, TCP_QUICKACK, &one, sizeof(one));
+                       setsockopt(__objt_conn(s->req.prod->end)->t.sock.fd, IPPROTO_TCP, TCP_QUICKACK, &one, sizeof(one));
                }
 #endif
 
@@ -2808,7 +2808,7 @@ int http_wait_for_request(struct session *s, struct channel *req, int an_bit)
                req->analysers = 0;
                s->logs.logwait = 0;
                s->logs.level = 0;
-               s->rep->flags &= ~CF_EXPECT_MORE; /* speed up sending a previous response */
+               s->res.flags &= ~CF_EXPECT_MORE; /* speed up sending a previous response */
                stream_int_retnclose(req->prod, NULL);
                return 0;
        }
@@ -3094,7 +3094,7 @@ int http_wait_for_request(struct session *s, struct channel *req, int an_bit)
 int http_handle_stats(struct session *s, struct channel *req)
 {
        struct stats_admin_rule *stats_admin_rule;
-       struct stream_interface *si = s->rep->prod;
+       struct stream_interface *si = s->res.prod;
        struct http_txn *txn = &s->txn;
        struct http_msg *msg = &txn->req;
        struct uri_auth *uri_auth = s->be->uri_auth;
@@ -3440,13 +3440,13 @@ resume_execution:
                        break;
 
                case HTTP_REQ_ACT_SET_TOS:
-                       if ((cli_conn = objt_conn(s->req->prod->end)) && conn_ctrl_ready(cli_conn))
+                       if ((cli_conn = objt_conn(s->req.prod->end)) && conn_ctrl_ready(cli_conn))
                                inet_set_tos(cli_conn->t.sock.fd, cli_conn->addr.from, rule->arg.tos);
                        break;
 
                case HTTP_REQ_ACT_SET_MARK:
 #ifdef SO_MARK
-                       if ((cli_conn = objt_conn(s->req->prod->end)) && conn_ctrl_ready(cli_conn))
+                       if ((cli_conn = objt_conn(s->req.prod->end)) && conn_ctrl_ready(cli_conn))
                                setsockopt(cli_conn->t.sock.fd, SOL_SOCKET, SO_MARK, &rule->arg.mark, sizeof(rule->arg.mark));
 #endif
                        break;
@@ -3686,13 +3686,13 @@ resume_execution:
                        break;
 
                case HTTP_RES_ACT_SET_TOS:
-                       if ((cli_conn = objt_conn(s->req->prod->end)) && conn_ctrl_ready(cli_conn))
+                       if ((cli_conn = objt_conn(s->req.prod->end)) && conn_ctrl_ready(cli_conn))
                                inet_set_tos(cli_conn->t.sock.fd, cli_conn->addr.from, rule->arg.tos);
                        break;
 
                case HTTP_RES_ACT_SET_MARK:
 #ifdef SO_MARK
-                       if ((cli_conn = objt_conn(s->req->prod->end)) && conn_ctrl_ready(cli_conn))
+                       if ((cli_conn = objt_conn(s->req.prod->end)) && conn_ctrl_ready(cli_conn))
                                setsockopt(cli_conn->t.sock.fd, SOL_SOCKET, SO_MARK, &rule->arg.mark, sizeof(rule->arg.mark));
 #endif
                        break;
@@ -4072,7 +4072,7 @@ static int http_apply_redirect_rule(struct redirect_rule *rule, struct session *
                msg->next -= msg->sov;
                msg->sov = 0;
                txn->req.chn->analysers = AN_REQ_HTTP_XFER_BODY;
-               s->rep->analysers = AN_RES_HTTP_XFER_BODY;
+               s->res.analysers = AN_RES_HTTP_XFER_BODY;
                txn->req.msg_state = HTTP_MSG_CLOSED;
                txn->rsp.msg_state = HTTP_MSG_DONE;
        } else {
@@ -4162,9 +4162,9 @@ int http_process_req_common(struct session *s, struct channel *req, int an_bit,
         * by a possible reqrep, while they are processed *after* so that a
         * reqdeny can still block them. This clearly needs to change in 1.6!
         */
-       if (stats_check_uri(s->rep->prod, txn, px)) {
+       if (stats_check_uri(s->res.prod, txn, px)) {
                s->target = &http_stats_applet.obj_type;
-               if (unlikely(!stream_int_register_handler(s->rep->prod, objt_applet(s->target)))) {
+               if (unlikely(!stream_int_register_handler(s->res.prod, objt_applet(s->target)))) {
                        txn->status = 500;
                        s->logs.tv_request = now;
                        stream_int_retnclose(req->prod, http_error_message(s, HTTP_ERR_500));
@@ -4274,7 +4274,7 @@ int http_process_req_common(struct session *s, struct channel *req, int an_bit,
         * If unset, then set it to zero because we really want it to
         * eventually expire. We build the tarpit as an analyser.
         */
-       channel_erase(s->req);
+       channel_erase(&s->req);
 
        /* wipe the request out so that we can drop the connection early
         * if the client closes first.
@@ -4341,7 +4341,7 @@ int http_process_req_common(struct session *s, struct channel *req, int an_bit,
 /* This function performs all the processing enabled for the current request.
  * It returns 1 if the processing can continue on next analysers, or zero if it
  * needs more data, encounters an error, or wants to immediately abort the
- * request. It relies on buffers flags, and updates s->req->analysers.
+ * request. It relies on buffers flags, and updates s->req.analysers.
  */
 int http_process_request(struct session *s, struct channel *req, int an_bit)
 {
@@ -4761,7 +4761,7 @@ int http_wait_for_request_body(struct session *s, struct channel *req, int an_bi
                                /* Expect is allowed in 1.1, look for it */
                                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);
+                                       bo_inject(&s->res, http_100_chunk.str, http_100_chunk.len);
                                }
                        }
                        msg->msg_state = HTTP_MSG_100_SENT;
@@ -4945,10 +4945,10 @@ void http_end_txn_clean_session(struct session *s)
         * to the server.
         */
        if (((s->txn.flags & TX_CON_WANT_MSK) != TX_CON_WANT_KAL) ||
-           !si_conn_ready(s->req->cons)) {
-               s->req->cons->flags |= SI_FL_NOLINGER | SI_FL_NOHALF;
-               si_shutr(s->req->cons);
-               si_shutw(s->req->cons);
+           !si_conn_ready(s->req.cons)) {
+               s->req.cons->flags |= SI_FL_NOLINGER | SI_FL_NOHALF;
+               si_shutr(s->req.cons);
+               si_shutw(s->req.cons);
        }
 
        if (s->flags & SN_BE_ASSIGNED) {
@@ -4982,13 +4982,13 @@ 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->res.buf->i;
 
        /* let's do a final log if we need it */
        if (!LIST_ISEMPTY(&s->fe->logformat) && s->logs.logwait &&
            !(s->flags & SN_MONITOR) &&
-           (!(s->fe->options & PR_O_NULLNOLOG) || s->req->total)) {
+           (!(s->fe->options & PR_O_NULLNOLOG) || s->req.total)) {
                s->do_log(s);
        }
 
@@ -5006,8 +5006,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->res.total = s->res.buf->i;
 
        if (s->pend_pos)
                pendconn_free(s->pend_pos);
@@ -5027,17 +5027,17 @@ void http_end_txn_clean_session(struct session *s)
         * connection.
         */
        if (((s->txn.flags & TX_CON_WANT_MSK) != TX_CON_WANT_KAL) ||
-           !si_conn_ready(s->req->cons)) {
-               si_release_endpoint(s->req->cons);
+           !si_conn_ready(s->req.cons)) {
+               si_release_endpoint(s->req.cons);
        }
 
-       s->req->cons->state     = s->req->cons->prev_state = SI_ST_INI;
-       s->req->cons->err_type  = SI_ET_NONE;
-       s->req->cons->conn_retries = 0;  /* used for logging too */
-       s->req->cons->exp       = TICK_ETERNITY;
-       s->req->cons->flags    &= SI_FL_DONT_WAKE; /* we're in the context of process_session */
-       s->req->flags &= ~(CF_SHUTW|CF_SHUTW_NOW|CF_AUTO_CONNECT|CF_WRITE_ERROR|CF_STREAMER|CF_STREAMER_FAST|CF_NEVER_WAIT|CF_WAKE_CONNECT|CF_WROTE_DATA);
-       s->rep->flags &= ~(CF_SHUTR|CF_SHUTR_NOW|CF_READ_ATTACHED|CF_READ_ERROR|CF_READ_NOEXP|CF_STREAMER|CF_STREAMER_FAST|CF_WRITE_PARTIAL|CF_NEVER_WAIT|CF_WROTE_DATA);
+       s->req.cons->state     = s->req.cons->prev_state = SI_ST_INI;
+       s->req.cons->err_type  = SI_ET_NONE;
+       s->req.cons->conn_retries = 0;  /* used for logging too */
+       s->req.cons->exp       = TICK_ETERNITY;
+       s->req.cons->flags    &= SI_FL_DONT_WAKE; /* we're in the context of process_session */
+       s->req.flags &= ~(CF_SHUTW|CF_SHUTW_NOW|CF_AUTO_CONNECT|CF_WRITE_ERROR|CF_STREAMER|CF_STREAMER_FAST|CF_NEVER_WAIT|CF_WAKE_CONNECT|CF_WROTE_DATA);
+       s->res.flags &= ~(CF_SHUTR|CF_SHUTR_NOW|CF_READ_ATTACHED|CF_READ_ERROR|CF_READ_NOEXP|CF_STREAMER|CF_STREAMER_FAST|CF_WRITE_PARTIAL|CF_NEVER_WAIT|CF_WROTE_DATA);
        s->flags &= ~(SN_DIRECT|SN_ASSIGNED|SN_ADDR_SET|SN_BE_ASSIGNED|SN_FORCE_PRST|SN_IGNORE_PRST);
        s->flags &= ~(SN_CURR_SESS|SN_REDIRECTABLE|SN_SRV_REUSED);
        s->flags &= ~(SN_ERR_MASK|SN_FINST_MASK|SN_REDISP);
@@ -5058,11 +5058,11 @@ void http_end_txn_clean_session(struct session *s)
        }
 
        if (s->fe->options2 & PR_O2_INDEPSTR)
-               s->req->cons->flags |= SI_FL_INDEP_STR;
+               s->req.cons->flags |= SI_FL_INDEP_STR;
 
        if (s->fe->options2 & PR_O2_NODELAY) {
-               s->req->flags |= CF_NEVER_WAIT;
-               s->rep->flags |= CF_NEVER_WAIT;
+               s->req.flags |= CF_NEVER_WAIT;
+               s->res.flags |= CF_NEVER_WAIT;
        }
 
        /* if the request buffer is not empty, it means we're
@@ -5072,24 +5072,24 @@ 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)
-                       s->rep->flags |= CF_EXPECT_MORE;
+       if (s->req.buf->i) {
+               if (s->res.buf->o &&
+                   !buffer_full(s->res.buf, global.tune.maxrewrite) &&
+                   bi_end(s->res.buf) <= s->res.buf->data + s->res.buf->size - global.tune.maxrewrite)
+                       s->res.flags |= CF_EXPECT_MORE;
        }
 
        /* we're removing the analysers, we MUST re-enable events detection */
-       channel_auto_read(s->req);
-       channel_auto_close(s->req);
-       channel_auto_read(s->rep);
-       channel_auto_close(s->rep);
+       channel_auto_read(&s->req);
+       channel_auto_close(&s->req);
+       channel_auto_read(&s->res);
+       channel_auto_close(&s->res);
 
        /* we're in keep-alive with an idle connection, monitor it */
-       si_idle_conn(s->req->cons);
+       si_idle_conn(s->req.cons);
 
-       s->req->analysers = s->listener->analysers;
-       s->rep->analysers = 0;
+       s->req.analysers = s->listener->analysers;
+       s->res.analysers = 0;
 }
 
 
@@ -5102,7 +5102,7 @@ void http_end_txn_clean_session(struct session *s)
  */
 int http_sync_req_state(struct session *s)
 {
-       struct channel *chn = s->req;
+       struct channel *chn = &s->req;
        struct http_txn *txn = &s->txn;
        unsigned int old_flags = chn->flags;
        unsigned int old_state = txn->req.msg_state;
@@ -5240,7 +5240,7 @@ int http_sync_req_state(struct session *s)
  */
 int http_sync_res_state(struct session *s)
 {
-       struct channel *chn = s->rep;
+       struct channel *chn = &s->res;
        struct http_txn *txn = &s->txn;
        unsigned int old_flags = chn->flags;
        unsigned int old_state = txn->rsp.msg_state;
@@ -5397,25 +5397,25 @@ int http_resync_states(struct session *s)
            txn->rsp.msg_state == HTTP_MSG_TUNNEL ||
            (txn->req.msg_state == HTTP_MSG_CLOSED &&
             txn->rsp.msg_state == HTTP_MSG_CLOSED)) {
-               s->req->analysers = 0;
-               channel_auto_close(s->req);
-               channel_auto_read(s->req);
-               s->rep->analysers = 0;
-               channel_auto_close(s->rep);
-               channel_auto_read(s->rep);
+               s->req.analysers = 0;
+               channel_auto_close(&s->req);
+               channel_auto_read(&s->req);
+               s->res.analysers = 0;
+               channel_auto_close(&s->res);
+               channel_auto_read(&s->res);
        }
        else if ((txn->req.msg_state >= HTTP_MSG_DONE &&
-                 (txn->rsp.msg_state == HTTP_MSG_CLOSED || (s->rep->flags & CF_SHUTW))) ||
+                 (txn->rsp.msg_state == HTTP_MSG_CLOSED || (s->res.flags & CF_SHUTW))) ||
                 txn->rsp.msg_state == HTTP_MSG_ERROR ||
                 txn->req.msg_state == HTTP_MSG_ERROR) {
-               s->rep->analysers = 0;
-               channel_auto_close(s->rep);
-               channel_auto_read(s->rep);
-               s->req->analysers = 0;
-               channel_abort(s->req);
-               channel_auto_close(s->req);
-               channel_auto_read(s->req);
-               channel_truncate(s->req);
+               s->res.analysers = 0;
+               channel_auto_close(&s->res);
+               channel_auto_read(&s->res);
+               s->req.analysers = 0;
+               channel_abort(&s->req);
+               channel_auto_close(&s->req);
+               channel_auto_read(&s->req);
+               channel_truncate(&s->req);
        }
        else if ((txn->req.msg_state == HTTP_MSG_DONE ||
                  txn->req.msg_state == HTTP_MSG_CLOSED) &&
@@ -5494,7 +5494,7 @@ int http_request_forward_body(struct session *s, struct channel *req, int an_bit
         * whichs need to parse/process the request after we've enabled forwarding.
         */
        if (unlikely(msg->flags & HTTP_MSGF_WAIT_CONN)) {
-               if (!(s->rep->flags & CF_READ_ATTACHED)) {
+               if (!(s->res.flags & CF_READ_ATTACHED)) {
                        channel_auto_connect(req);
                        req->flags |= CF_WAKE_CONNECT;
                        goto missing_data;
@@ -5581,7 +5581,7 @@ int http_request_forward_body(struct session *s, struct channel *req, int an_bit
                         * such as last chunk of data or trailers.
                         */
                        b_adv(req->buf, msg->next);
-                       if (unlikely(!(s->req->flags & CF_WROTE_DATA)))
+                       if (unlikely(!(s->req.flags & CF_WROTE_DATA)))
                                msg->sov -= msg->next;
                        msg->next = 0;
 
@@ -5633,7 +5633,7 @@ int http_request_forward_body(struct session *s, struct channel *req, int an_bit
  missing_data:
        /* we may have some pending data starting at req->buf->p */
        b_adv(req->buf, msg->next);
-       if (unlikely(!(s->req->flags & CF_WROTE_DATA)))
+       if (unlikely(!(s->req.flags & CF_WROTE_DATA)))
                msg->sov -= msg->next + MIN(msg->chunk_len, req->buf->i);
 
        msg->next = 0;
@@ -5700,7 +5700,7 @@ int http_request_forward_body(struct session *s, struct channel *req, int an_bit
                stream_int_retnclose(req->prod, http_error_message(s, HTTP_ERR_400));
        }
        req->analysers = 0;
-       s->rep->analysers = 0; /* we're in data phase, we want to abort both directions */
+       s->res.analysers = 0; /* we're in data phase, we want to abort both directions */
 
        if (!(s->flags & SN_ERR_MASK))
                s->flags |= SN_ERR_PRXCOND;
@@ -5722,7 +5722,7 @@ int http_request_forward_body(struct session *s, struct channel *req, int an_bit
                stream_int_retnclose(req->prod, http_error_message(s, HTTP_ERR_502));
        }
        req->analysers = 0;
-       s->rep->analysers = 0; /* we're in data phase, we want to abort both directions */
+       s->res.analysers = 0; /* we're in data phase, we want to abort both directions */
 
        s->fe->fe_counters.srv_aborts++;
        s->be->be_counters.srv_aborts++;
@@ -5743,7 +5743,7 @@ int http_request_forward_body(struct session *s, struct channel *req, int an_bit
 /* This stream analyser waits for a complete HTTP response. It returns 1 if the
  * processing can continue on next analysers, or zero if it either needs more
  * data or wants to immediately abort the response (eg: timeout, error, ...). It
- * is tied to AN_RES_WAIT_HTTP and may may remove itself from s->rep->analysers
+ * is tied to AN_RES_WAIT_HTTP and may may remove itself from s->res.analysers
  * when it has nothing left to do, and may remove any analyser when it wants to
  * abort.
  */
@@ -5933,7 +5933,7 @@ int http_wait_for_response(struct session *s, struct channel *rep, int an_bit)
                }
 
                /* client abort with an abortonclose */
-               else if ((rep->flags & CF_SHUTR) && ((s->req->flags & (CF_SHUTR|CF_SHUTW)) == (CF_SHUTR|CF_SHUTW))) {
+               else if ((rep->flags & CF_SHUTR) && ((s->req.flags & (CF_SHUTR|CF_SHUTW)) == (CF_SHUTR|CF_SHUTW))) {
                        s->fe->fe_counters.cli_aborts++;
                        s->be->be_counters.cli_aborts++;
                        if (objt_server(s->target))
@@ -6299,11 +6299,11 @@ skip_content_length:
         */
        txn->status = 0;
        rep->analysers = 0;
-       s->req->analysers = 0;
+       s->req.analysers = 0;
        channel_auto_close(rep);
        s->logs.logwait = 0;
        s->logs.level = 0;
-       s->rep->flags &= ~CF_EXPECT_MORE; /* speed up sending a previous response */
+       s->res.flags &= ~CF_EXPECT_MORE; /* speed up sending a previous response */
        channel_truncate(rep);
        stream_int_retnclose(rep->cons, NULL);
        return 0;
@@ -6311,7 +6311,7 @@ skip_content_length:
 
 /* This function performs all the processing enabled for the current response.
  * It normally returns 1 unless it wants to break. It relies on buffers flags,
- * and updates s->rep->analysers. It might make sense to explode it into several
+ * and updates s->res.analysers. It might make sense to explode it into several
  * other functions. It works like process_request (see indications above).
  */
 int http_process_res_common(struct session *s, struct channel *rep, int an_bit, struct proxy *px)
@@ -6666,7 +6666,7 @@ int http_response_forward_body(struct session *s, struct channel *res, int an_bi
 
        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)) ||
-           !s->req->analysers) {
+           !s->req.analysers) {
                /* Output closed while we were sending data. We must abort and
                 * wake the other side up.
                 */
@@ -6870,7 +6870,7 @@ int http_response_forward_body(struct session *s, struct channel *res, int an_bi
         * server abort.
         */
        if (res->flags & CF_SHUTR) {
-               if ((s->req->flags & (CF_SHUTR|CF_SHUTW)) == (CF_SHUTR|CF_SHUTW))
+               if ((s->req.flags & (CF_SHUTR|CF_SHUTW)) == (CF_SHUTR|CF_SHUTW))
                        goto aborted_xfer;
                if (!(s->flags & SN_ERR_MASK))
                        s->flags |= SN_ERR_SRVCL;
@@ -6881,7 +6881,7 @@ int http_response_forward_body(struct session *s, struct channel *res, int an_bi
        }
 
        /* we need to obey the req analyser, so if it leaves, we must too */
-       if (!s->req->analysers)
+       if (!s->req.analysers)
                goto return_bad_res;
 
        /* When TE: chunked is used, we need to get there again to parse remaining
@@ -6929,7 +6929,7 @@ int http_response_forward_body(struct session *s, struct channel *res, int an_bi
        /* don't send any error message as we're in the body */
        stream_int_retnclose(res->cons, NULL);
        res->analysers = 0;
-       s->req->analysers = 0; /* we're in data phase, we want to abort both directions */
+       s->req.analysers = 0; /* we're in data phase, we want to abort both directions */
        if (objt_server(s->target))
                health_adjust(objt_server(s->target), HANA_STATUS_HTTP_HDRRSP);
 
@@ -6949,7 +6949,7 @@ int http_response_forward_body(struct session *s, struct channel *res, int an_bi
        /* don't send any error message as we're in the body */
        stream_int_retnclose(res->cons, NULL);
        res->analysers = 0;
-       s->req->analysers = 0; /* we're in data phase, we want to abort both directions */
+       s->req.analysers = 0; /* we're in data phase, we want to abort both directions */
 
        s->fe->fe_counters.cli_aborts++;
        s->be->be_counters.cli_aborts++;
@@ -8638,8 +8638,8 @@ void http_capture_bad_message(struct error_snapshot *es, struct session *s,
        es->sid  = s->uniq_id;
        es->srv  = objt_server(s->target);
        es->oe   = other_end;
-       if (objt_conn(s->req->prod->end))
-               es->src  = __objt_conn(s->req->prod->end)->addr.from;
+       if (objt_conn(s->req.prod->end))
+               es->src  = __objt_conn(s->req.prod->end)->addr.from;
        else
                memset(&es->src, 0, sizeof(es->src));
 
@@ -8796,8 +8796,8 @@ void debug_hdr(const char *dir, struct session *s, const char *start, const char
        int max;
        chunk_printf(&trash, "%08x:%s.%s[%04x:%04x]: ", s->uniq_id, s->be->id,
                      dir,
-                    objt_conn(s->req->prod->end) ? (unsigned short)objt_conn(s->req->prod->end)->t.sock.fd : -1,
-                    objt_conn(s->req->cons->end) ? (unsigned short)objt_conn(s->req->cons->end)->t.sock.fd : -1);
+                    objt_conn(s->req.prod->end) ? (unsigned short)objt_conn(s->req.prod->end)->t.sock.fd : -1,
+                    objt_conn(s->req.cons->end) ? (unsigned short)objt_conn(s->req.cons->end)->t.sock.fd : -1);
 
        for (max = 0; start + max < end; max++)
                if (start[max] == '\r' || start[max] == '\n')
@@ -8837,8 +8837,8 @@ void http_init_txn(struct session *s)
        txn->rsp.body_len = 0LL;
        txn->req.msg_state = HTTP_MSG_RQBEFORE; /* at the very beginning of the request */
        txn->rsp.msg_state = HTTP_MSG_RPBEFORE; /* at the very beginning of the response */
-       txn->req.chn = s->req;
-       txn->rsp.chn = s->rep;
+       txn->req.chn = &s->req;
+       txn->rsp.chn = &s->res;
 
        txn->auth.method = HTTP_AUTH_UNKNOWN;
 
@@ -8918,7 +8918,7 @@ void http_reset_txn(struct session *s)
 
        s->pend_pos = NULL;
 
-       s->req->flags |= CF_READ_DONTWAIT; /* one read is usually enough */
+       s->req.flags |= CF_READ_DONTWAIT; /* one read is usually enough */
 
        /* We must trim any excess data from the response buffer, because we
         * may have blocked an invalid response from a server that we don't
@@ -8928,21 +8928,21 @@ 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->res.buf->i))
+               s->res.buf->i = 0;
 
-       s->req->rto = s->fe->timeout.client;
-       s->req->wto = TICK_ETERNITY;
+       s->req.rto = s->fe->timeout.client;
+       s->req.wto = TICK_ETERNITY;
 
-       s->rep->rto = TICK_ETERNITY;
-       s->rep->wto = s->fe->timeout.client;
+       s->res.rto = TICK_ETERNITY;
+       s->res.wto = s->fe->timeout.client;
 
-       s->req->rex = TICK_ETERNITY;
-       s->req->wex = TICK_ETERNITY;
-       s->req->analyse_exp = TICK_ETERNITY;
-       s->rep->rex = TICK_ETERNITY;
-       s->rep->wex = TICK_ETERNITY;
-       s->rep->analyse_exp = TICK_ETERNITY;
+       s->req.rex = TICK_ETERNITY;
+       s->req.wex = TICK_ETERNITY;
+       s->req.analyse_exp = TICK_ETERNITY;
+       s->res.rex = TICK_ETERNITY;
+       s->res.wex = TICK_ETERNITY;
+       s->res.analyse_exp = TICK_ETERNITY;
 }
 
 void free_http_res_rules(struct list *r)
@@ -9912,28 +9912,25 @@ smp_prefetch_http(struct proxy *px, struct session *s, void *l7, unsigned int op
        smp->type = SMP_T_BOOL;
 
        if ((opt & SMP_OPT_DIR) == SMP_OPT_DIR_REQ) {
-               if (unlikely(!s->req))
-                       return 0;
-
                /* If the buffer does not leave enough free space at the end,
                 * we must first realign it.
                 */
-               if (s->req->buf->p > s->req->buf->data &&
-                   s->req->buf->i + s->req->buf->p > s->req->buf->data + s->req->buf->size - global.tune.maxrewrite)
-                       buffer_slow_realign(s->req->buf);
+               if (s->req.buf->p > s->req.buf->data &&
+                   s->req.buf->i + s->req.buf->p > s->req.buf->data + s->req.buf->size - global.tune.maxrewrite)
+                       buffer_slow_realign(s->req.buf);
 
                if (unlikely(txn->req.msg_state < HTTP_MSG_BODY)) {
                        if (msg->msg_state == HTTP_MSG_ERROR)
                                return 0;
 
                        /* 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)) {
                                        return 0;
                                }
                                /* wait for final state */
@@ -9951,8 +9948,8 @@ smp_prefetch_http(struct proxy *px, struct session *s, void *l7, unsigned int op
                         * cannot happen, but if the parsers are to change in the future,
                         * we want this check to be maintained.
                         */
-                       if (unlikely(s->req->buf->i + s->req->buf->p >
-                                    s->req->buf->data + s->req->buf->size - global.tune.maxrewrite)) {
+                       if (unlikely(s->req.buf->i + s->req.buf->p >
+                                    s->req.buf->data + s->req.buf->size - global.tune.maxrewrite)) {
                                msg->msg_state = HTTP_MSG_ERROR;
                                smp->data.uint = 1;
                                return 1;
@@ -11666,7 +11663,7 @@ int http_action_set_req_line(struct http_req_rule *rule, struct proxy *px, struc
 
        switch (*(int *)&rule->arg.act.p[2]) {
        case 0: // method
-               cur_ptr = s->req->buf->p;
+               cur_ptr = s->req.buf->p;
                cur_end = cur_ptr + txn->req.sl.rq.m_l;
 
                /* adjust req line offsets and lengths */
@@ -11679,10 +11676,10 @@ int http_action_set_req_line(struct http_req_rule *rule, struct proxy *px, struc
        case 1: // path
                cur_ptr = http_get_path(txn);
                if (!cur_ptr)
-                       cur_ptr = s->req->buf->p + txn->req.sl.rq.u;
+                       cur_ptr = s->req.buf->p + txn->req.sl.rq.u;
 
                cur_end = cur_ptr;
-               while (cur_end < s->req->buf->p + txn->req.sl.rq.u + txn->req.sl.rq.u_l && *cur_end != '?')
+               while (cur_end < s->req.buf->p + txn->req.sl.rq.u + txn->req.sl.rq.u_l && *cur_end != '?')
                        cur_end++;
 
                /* adjust req line offsets and lengths */
@@ -11692,7 +11689,7 @@ int http_action_set_req_line(struct http_req_rule *rule, struct proxy *px, struc
                break;
 
        case 2: // query
-               cur_ptr = s->req->buf->p + txn->req.sl.rq.u;
+               cur_ptr = s->req.buf->p + txn->req.sl.rq.u;
                cur_end = cur_ptr + txn->req.sl.rq.u_l;
                while (cur_ptr < cur_end && *cur_ptr != '?')
                        cur_ptr++;
@@ -11712,7 +11709,7 @@ int http_action_set_req_line(struct http_req_rule *rule, struct proxy *px, struc
                break;
 
        case 3: // uri
-               cur_ptr = s->req->buf->p + txn->req.sl.rq.u;
+               cur_ptr = s->req.buf->p + txn->req.sl.rq.u;
                cur_end = cur_ptr + txn->req.sl.rq.u_l;
 
                /* adjust req line offsets and lengths */
@@ -11726,7 +11723,7 @@ int http_action_set_req_line(struct http_req_rule *rule, struct proxy *px, struc
        }
 
        /* commit changes and adjust end of message */
-       delta = buffer_replace2(s->req->buf, cur_ptr, cur_end, trash.str + offset, trash.len - offset);
+       delta = buffer_replace2(s->req.buf, cur_ptr, cur_end, trash.str + offset, trash.len - offset);
        http_msg_move_end(&txn->req, delta);
        return 0;
 }
index f2272a402ee780ec52ca9bcc6b305b5489d2a04b..086c6cef25ff3a82593aabf19c84ca55e140c391 100644 (file)
@@ -1149,7 +1149,7 @@ resume_execution:
                        /* we have a matching rule. */
                        if (rule->action == TCP_ACT_REJECT) {
                                channel_abort(req);
-                               channel_abort(s->rep);
+                               channel_abort(&s->res);
                                req->analysers = 0;
 
                                s->be->be_counters.denied_req++;
@@ -1310,7 +1310,7 @@ resume_execution:
                        /* we have a matching rule. */
                        if (rule->action == TCP_ACT_REJECT) {
                                channel_abort(rep);
-                               channel_abort(s->req);
+                               channel_abort(&s->req);
                                rep->analysers = 0;
 
                                s->be->be_counters.denied_resp++;
index 405c4c4ada41f110c2450d03f4e2240c9ad51e4b..a8cb443b55f6e6a22f554c91bd2f975a2e7abd1c 100644 (file)
@@ -973,8 +973,8 @@ int session_set_backend(struct session *s, struct proxy *be)
                s->txn.req.flags |= HTTP_MSGF_WAIT_CONN;
 
        if (be->options2 & PR_O2_NODELAY) {
-               s->req->flags |= CF_NEVER_WAIT;
-               s->rep->flags |= CF_NEVER_WAIT;
+               s->req.flags |= CF_NEVER_WAIT;
+               s->res.flags |= CF_NEVER_WAIT;
        }
 
        /* We want to enable the backend-specific analysers except those which
@@ -982,7 +982,7 @@ int session_set_backend(struct session *s, struct proxy *be)
         * be more reliable to store the list of analysers that have been run,
         * but what we do here is OK for now.
         */
-       s->req->analysers |= be->be_req_ana & ~(s->listener->analysers);
+       s->req.analysers |= be->be_req_ana & ~(s->listener->analysers);
 
        return 1;
 }
index fd1a60621e86cf40c95be4c845d725cf2220772e..4e09c3468fb01c5cefe2c85440b032f00dbfe813 100644 (file)
@@ -432,8 +432,8 @@ int session_complete(struct session *s)
         * when the default backend is assigned.
         */
        s->be  = s->fe;
-       s->req = s->rep = NULL; /* will be allocated later */
        s->comp_algo = NULL;
+       s->req.buf = s->res.buf = NULL;
 
        /* Let's count a session now */
        proxy_inc_fe_sess_ctr(l, p);
@@ -484,43 +484,37 @@ int session_complete(struct session *s)
        /* init store persistence */
        s->store_count = 0;
 
-       if (unlikely((s->req = pool_alloc2(pool2_channel)) == NULL))
-               goto out_free_task; /* no memory */
-
-       channel_init(s->req);
-       s->req->prod = &s->si[0];
-       s->req->cons = &s->si[1];
-       s->si[0].ib = s->si[1].ob = s->req;
-       s->req->flags |= CF_READ_ATTACHED; /* the producer is already connected */
+       channel_init(&s->req);
+       s->req.prod = &s->si[0];
+       s->req.cons = &s->si[1];
+       s->si[0].ib = s->si[1].ob = &s->req;
+       s->req.flags |= CF_READ_ATTACHED; /* the producer is already connected */
 
        /* activate default analysers enabled for this listener */
-       s->req->analysers = l->analysers;
-
-       s->req->wto = TICK_ETERNITY;
-       s->req->rto = TICK_ETERNITY;
-       s->req->rex = TICK_ETERNITY;
-       s->req->wex = TICK_ETERNITY;
-       s->req->analyse_exp = TICK_ETERNITY;
+       s->req.analysers = l->analysers;
 
-       if (unlikely((s->rep = pool_alloc2(pool2_channel)) == NULL))
-               goto out_free_req; /* no memory */
+       s->req.wto = TICK_ETERNITY;
+       s->req.rto = TICK_ETERNITY;
+       s->req.rex = TICK_ETERNITY;
+       s->req.wex = TICK_ETERNITY;
+       s->req.analyse_exp = TICK_ETERNITY;
 
-       channel_init(s->rep);
-       s->rep->prod = &s->si[1];
-       s->rep->cons = &s->si[0];
-       s->si[0].ob = s->si[1].ib = s->rep;
-       s->rep->analysers = 0;
+       channel_init(&s->res);
+       s->res.prod = &s->si[1];
+       s->res.cons = &s->si[0];
+       s->si[0].ob = s->si[1].ib = &s->res;
+       s->res.analysers = 0;
 
        if (s->fe->options2 & PR_O2_NODELAY) {
-               s->req->flags |= CF_NEVER_WAIT;
-               s->rep->flags |= CF_NEVER_WAIT;
+               s->req.flags |= CF_NEVER_WAIT;
+               s->res.flags |= CF_NEVER_WAIT;
        }
 
-       s->rep->rto = TICK_ETERNITY;
-       s->rep->wto = TICK_ETERNITY;
-       s->rep->rex = TICK_ETERNITY;
-       s->rep->wex = TICK_ETERNITY;
-       s->rep->analyse_exp = TICK_ETERNITY;
+       s->res.rto = TICK_ETERNITY;
+       s->res.wto = TICK_ETERNITY;
+       s->res.rex = TICK_ETERNITY;
+       s->res.wex = TICK_ETERNITY;
+       s->res.analyse_exp = TICK_ETERNITY;
 
        txn = &s->txn;
        /* Those variables will be checked and freed if non-NULL in
@@ -539,8 +533,8 @@ int session_complete(struct session *s)
        txn->req.flags = 0;
        txn->rsp.flags = 0;
        /* the HTTP messages need to know what buffer they're associated with */
-       txn->req.chn = s->req;
-       txn->rsp.chn = s->rep;
+       txn->req.chn = &s->req;
+       txn->rsp.chn = &s->res;
 
        HLUA_INIT(&s->hlua);
 
@@ -552,7 +546,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_strm;
        }
 
        /* if logs require transport layer information, note it on the connection */
@@ -570,11 +564,7 @@ int session_complete(struct session *s)
        return 1;
 
        /* Error unrolling */
- out_free_rep:
-       pool_free2(pool2_channel, s->rep);
- out_free_req:
-       pool_free2(pool2_channel, s->req);
- out_free_task:
+ out_free_strm:
        /* and restore the connection pointer in case we destroyed it,
         * because kill_mini_session() will need it.
         */
@@ -614,11 +604,11 @@ static void session_free(struct session *s)
                sess_change_server(s, NULL);
        }
 
-       if (s->req->pipe)
-               put_pipe(s->req->pipe);
+       if (s->req.pipe)
+               put_pipe(s->req.pipe);
 
-       if (s->rep->pipe)
-               put_pipe(s->rep->pipe);
+       if (s->res.pipe)
+               put_pipe(s->res.pipe);
 
        /* We may still be present in the buffer wait queue */
        if (!LIST_ISEMPTY(&s->buffer_wait)) {
@@ -626,16 +616,12 @@ static void session_free(struct session *s)
                LIST_INIT(&s->buffer_wait);
        }
 
-       b_drop(&s->req->buf);
-       b_drop(&s->rep->buf);
+       b_drop(&s->req.buf);
+       b_drop(&s->res.buf);
        if (!LIST_ISEMPTY(&buffer_wq))
                session_offer_buffers();
 
        hlua_ctx_destroy(&s->hlua);
-
-       pool_free2(pool2_channel, s->req);
-       pool_free2(pool2_channel, s->rep);
-
        http_end_txn(s);
 
        /* ensure the client-side transport layer is destroyed */
@@ -701,7 +687,7 @@ int session_alloc_recv_buffer(struct session *s, struct buffer **buf)
        struct buffer *b;
        int margin = 0;
 
-       if (buf == &s->req->buf)
+       if (buf == &s->req.buf)
                margin = global.tune.reserved_bufs;
 
        b = b_alloc_margin(buf, margin);
@@ -730,11 +716,11 @@ int session_alloc_work_buffer(struct session *s)
        struct buffer **buf;
 
        if (objt_appctx(s->si[0].end)) {
-               buf = &s->req->buf;
+               buf = &s->req.buf;
                margin = global.tune.reserved_bufs;
        }
        else {
-               buf = &s->rep->buf;
+               buf = &s->res.buf;
                margin = 0;
        }
 
@@ -758,11 +744,11 @@ int session_alloc_work_buffer(struct session *s)
  */
 void session_release_buffers(struct session *s)
 {
-       if (s->req->buf->size && buffer_empty(s->req->buf))
-               b_free(&s->req->buf);
+       if (s->req.buf->size && buffer_empty(s->req.buf))
+               b_free(&s->req.buf);
 
-       if (s->rep->buf->size && buffer_empty(s->rep->buf))
-               b_free(&s->rep->buf);
+       if (s->res.buf->size && buffer_empty(s->res.buf))
+               b_free(&s->res.buf);
 
        /* if we're certain to have at least 1 buffer available, and there is
         * someone waiting, we can wake up a waiter and offer them.
@@ -806,71 +792,67 @@ void session_process_counters(struct session *s)
        void *ptr;
        int i;
 
-       if (s->req) {
-               bytes = s->req->total - s->logs.bytes_in;
-               s->logs.bytes_in = s->req->total;
-               if (bytes) {
-                       s->fe->fe_counters.bytes_in += bytes;
-
-                       s->be->be_counters.bytes_in += bytes;
+       bytes = s->req.total - s->logs.bytes_in;
+       s->logs.bytes_in = s->req.total;
+       if (bytes) {
+               s->fe->fe_counters.bytes_in += bytes;
 
-                       if (objt_server(s->target))
-                               objt_server(s->target)->counters.bytes_in += bytes;
+               s->be->be_counters.bytes_in += bytes;
 
-                       if (s->listener && s->listener->counters)
-                               s->listener->counters->bytes_in += bytes;
+               if (objt_server(s->target))
+                       objt_server(s->target)->counters.bytes_in += bytes;
 
-                       for (i = 0; i < MAX_SESS_STKCTR; i++) {
-                               if (!stkctr_entry(&s->stkctr[i]))
-                                       continue;
+               if (s->listener && s->listener->counters)
+                       s->listener->counters->bytes_in += bytes;
 
-                               ptr = stktable_data_ptr(s->stkctr[i].table,
-                                                       stkctr_entry(&s->stkctr[i]),
-                                                       STKTABLE_DT_BYTES_IN_CNT);
-                               if (ptr)
-                                       stktable_data_cast(ptr, bytes_in_cnt) += bytes;
+               for (i = 0; i < MAX_SESS_STKCTR; i++) {
+                       if (!stkctr_entry(&s->stkctr[i]))
+                               continue;
 
-                               ptr = stktable_data_ptr(s->stkctr[i].table,
-                                                       stkctr_entry(&s->stkctr[i]),
-                                                       STKTABLE_DT_BYTES_IN_RATE);
-                               if (ptr)
-                                       update_freq_ctr_period(&stktable_data_cast(ptr, bytes_in_rate),
-                                                              s->stkctr[i].table->data_arg[STKTABLE_DT_BYTES_IN_RATE].u, bytes);
-                       }
+                       ptr = stktable_data_ptr(s->stkctr[i].table,
+                                               stkctr_entry(&s->stkctr[i]),
+                                               STKTABLE_DT_BYTES_IN_CNT);
+                       if (ptr)
+                               stktable_data_cast(ptr, bytes_in_cnt) += bytes;
+
+                       ptr = stktable_data_ptr(s->stkctr[i].table,
+                                               stkctr_entry(&s->stkctr[i]),
+                                               STKTABLE_DT_BYTES_IN_RATE);
+                       if (ptr)
+                               update_freq_ctr_period(&stktable_data_cast(ptr, bytes_in_rate),
+                                                      s->stkctr[i].table->data_arg[STKTABLE_DT_BYTES_IN_RATE].u, bytes);
                }
        }
 
-       if (s->rep) {
-               bytes = s->rep->total - s->logs.bytes_out;
-               s->logs.bytes_out = s->rep->total;
-               if (bytes) {
-                       s->fe->fe_counters.bytes_out += bytes;
-
-                       s->be->be_counters.bytes_out += bytes;
+       bytes = s->res.total - s->logs.bytes_out;
+       s->logs.bytes_out = s->res.total;
+       if (bytes) {
+               s->fe->fe_counters.bytes_out += bytes;
 
-                       if (objt_server(s->target))
-                               objt_server(s->target)->counters.bytes_out += bytes;
+               s->be->be_counters.bytes_out += bytes;
 
-                       if (s->listener && s->listener->counters)
-                               s->listener->counters->bytes_out += bytes;
+               if (objt_server(s->target))
+                       objt_server(s->target)->counters.bytes_out += bytes;
 
-                       for (i = 0; i < MAX_SESS_STKCTR; i++) {
-                               if (!stkctr_entry(&s->stkctr[i]))
-                                       continue;
+               if (s->listener && s->listener->counters)
+                       s->listener->counters->bytes_out += bytes;
 
-                               ptr = stktable_data_ptr(s->stkctr[i].table,
-                                                       stkctr_entry(&s->stkctr[i]),
-                                                       STKTABLE_DT_BYTES_OUT_CNT);
-                               if (ptr)
-                                       stktable_data_cast(ptr, bytes_out_cnt) += bytes;
+               for (i = 0; i < MAX_SESS_STKCTR; i++) {
+                       if (!stkctr_entry(&s->stkctr[i]))
+                               continue;
 
-                               ptr = stktable_data_ptr(s->stkctr[i].table,
-                                                       stkctr_entry(&s->stkctr[i]),
-                                                       STKTABLE_DT_BYTES_OUT_RATE);
-                               if (ptr)
-                                       update_freq_ctr_period(&stktable_data_cast(ptr, bytes_out_rate),
-                                                              s->stkctr[i].table->data_arg[STKTABLE_DT_BYTES_OUT_RATE].u, bytes);
-                       }
+                       ptr = stktable_data_ptr(s->stkctr[i].table,
+                                               stkctr_entry(&s->stkctr[i]),
+                                               STKTABLE_DT_BYTES_OUT_CNT);
+                       if (ptr)
+                               stktable_data_cast(ptr, bytes_out_cnt) += bytes;
+
+                       ptr = stktable_data_ptr(s->stkctr[i].table,
+                                               stkctr_entry(&s->stkctr[i]),
+                                               STKTABLE_DT_BYTES_OUT_RATE);
+                       if (ptr)
+                               update_freq_ctr_period(&stktable_data_cast(ptr, bytes_out_rate),
+                                                      s->stkctr[i].table->data_arg[STKTABLE_DT_BYTES_OUT_RATE].u, bytes);
                }
        }
 }
@@ -1103,9 +1085,9 @@ static void sess_update_stream_int(struct session *s, struct stream_interface *s
                now_ms, __FUNCTION__,
                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.rex, s->res.wex,
+               s->req.flags, s->res.flags,
+               s->req.buf->i, s->req.buf->o, s->res.buf->i, s->res.buf->o, s->res.cons->state, s->req.cons->state);
 
        if (si->state == SI_ST_ASS) {
                /* Server assigned to connection request, we have to try to connect now */
@@ -1295,9 +1277,9 @@ static void sess_prepare_conn_req(struct session *s, struct stream_interface *si
                now_ms, __FUNCTION__,
                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.rex, s->res.wex,
+               s->req.flags, s->res.flags,
+               s->req.buf->i, s->req.buf->o, s->res.buf->i, s->res.buf->o, s->res.cons->state, s->req.cons->state);
 
        if (si->state != SI_ST_REQ)
                return;
@@ -1432,8 +1414,8 @@ static int process_switching_rules(struct session *s, struct channel *req, int a
 
        /* we don't want to run the TCP or HTTP filters again if the backend has not changed */
        if (s->fe == s->be) {
-               s->req->analysers &= ~AN_REQ_INSPECT_BE;
-               s->req->analysers &= ~AN_REQ_HTTP_PROCESS_BE;
+               s->req.analysers &= ~AN_REQ_INSPECT_BE;
+               s->req.analysers &= ~AN_REQ_HTTP_PROCESS_BE;
        }
 
        /* as soon as we know the backend, we must check if we have a matching forced or ignored
@@ -1464,8 +1446,8 @@ static int process_switching_rules(struct session *s, struct channel *req, int a
 
  sw_failed:
        /* immediately abort this request in case of allocation failure */
-       channel_abort(s->req);
-       channel_abort(s->rep);
+       channel_abort(&s->req);
+       channel_abort(&s->res);
 
        if (!(s->flags & SN_ERR_MASK))
                s->flags |= SN_ERR_RESOURCE;
@@ -1473,8 +1455,8 @@ static int process_switching_rules(struct session *s, struct channel *req, int a
                s->flags |= SN_FINST_R;
 
        s->txn.status = 500;
-       s->req->analysers = 0;
-       s->req->analyse_exp = TICK_ETERNITY;
+       s->req.analysers = 0;
+       s->req.analyse_exp = TICK_ETERNITY;
        return 0;
 }
 
@@ -1754,24 +1736,24 @@ struct task *process_session(struct task *t)
        unsigned int req_ana_back;
 
        //DPRINTF(stderr, "%s:%d: cs=%d ss=%d(%d) rqf=0x%08x rpf=0x%08x\n", __FUNCTION__, __LINE__,
-       //        s->si[0].state, s->si[1].state, s->si[1].err_type, s->req->flags, s->rep->flags);
+       //        s->si[0].state, s->si[1].state, s->si[1].err_type, s->req.flags, s->res.flags);
 
        /* this data may be no longer valid, clear it */
        memset(&s->txn.auth, 0, sizeof(s->txn.auth));
 
        /* This flag must explicitly be set every time */
-       s->req->flags &= ~(CF_READ_NOEXP|CF_WAKE_WRITE);
-       s->rep->flags &= ~(CF_READ_NOEXP|CF_WAKE_WRITE);
+       s->req.flags &= ~(CF_READ_NOEXP|CF_WAKE_WRITE);
+       s->res.flags &= ~(CF_READ_NOEXP|CF_WAKE_WRITE);
 
        /* Keep a copy of req/rep flags so that we can detect shutdowns */
-       rqf_last = s->req->flags & ~CF_MASK_ANALYSER;
-       rpf_last = s->rep->flags & ~CF_MASK_ANALYSER;
+       rqf_last = s->req.flags & ~CF_MASK_ANALYSER;
+       rpf_last = s->res.flags & ~CF_MASK_ANALYSER;
 
        /* we don't want the stream interface functions to recursively wake us up */
-       if (s->req->prod->owner == t)
-               s->req->prod->flags |= SI_FL_DONT_WAKE;
-       if (s->req->cons->owner == t)
-               s->req->cons->flags |= SI_FL_DONT_WAKE;
+       if (s->req.prod->owner == t)
+               s->req.prod->flags |= SI_FL_DONT_WAKE;
+       if (s->req.cons->owner == t)
+               s->req.cons->flags |= SI_FL_DONT_WAKE;
 
        /* 1a: Check for low level timeouts if needed. We just set a flag on
         * stream interfaces when their timeouts have expired.
@@ -1786,30 +1768,30 @@ struct task *process_session(struct task *t)
                 * detect state changes when calling them.
                 */
 
-               channel_check_timeouts(s->req);
+               channel_check_timeouts(&s->req);
 
-               if (unlikely((s->req->flags & (CF_SHUTW|CF_WRITE_TIMEOUT)) == CF_WRITE_TIMEOUT)) {
-                       s->req->cons->flags |= SI_FL_NOLINGER;
-                       si_shutw(s->req->cons);
+               if (unlikely((s->req.flags & (CF_SHUTW|CF_WRITE_TIMEOUT)) == CF_WRITE_TIMEOUT)) {
+                       s->req.cons->flags |= SI_FL_NOLINGER;
+                       si_shutw(s->req.cons);
                }
 
-               if (unlikely((s->req->flags & (CF_SHUTR|CF_READ_TIMEOUT)) == CF_READ_TIMEOUT)) {
-                       if (s->req->prod->flags & SI_FL_NOHALF)
-                               s->req->prod->flags |= SI_FL_NOLINGER;
-                       si_shutr(s->req->prod);
+               if (unlikely((s->req.flags & (CF_SHUTR|CF_READ_TIMEOUT)) == CF_READ_TIMEOUT)) {
+                       if (s->req.prod->flags & SI_FL_NOHALF)
+                               s->req.prod->flags |= SI_FL_NOLINGER;
+                       si_shutr(s->req.prod);
                }
 
-               channel_check_timeouts(s->rep);
+               channel_check_timeouts(&s->res);
 
-               if (unlikely((s->rep->flags & (CF_SHUTW|CF_WRITE_TIMEOUT)) == CF_WRITE_TIMEOUT)) {
-                       s->rep->cons->flags |= SI_FL_NOLINGER;
-                       si_shutw(s->rep->cons);
+               if (unlikely((s->res.flags & (CF_SHUTW|CF_WRITE_TIMEOUT)) == CF_WRITE_TIMEOUT)) {
+                       s->res.cons->flags |= SI_FL_NOLINGER;
+                       si_shutw(s->res.cons);
                }
 
-               if (unlikely((s->rep->flags & (CF_SHUTR|CF_READ_TIMEOUT)) == CF_READ_TIMEOUT)) {
-                       if (s->rep->prod->flags & SI_FL_NOHALF)
-                               s->rep->prod->flags |= SI_FL_NOLINGER;
-                       si_shutr(s->rep->prod);
+               if (unlikely((s->res.flags & (CF_SHUTR|CF_READ_TIMEOUT)) == CF_READ_TIMEOUT)) {
+                       if (s->res.prod->flags & SI_FL_NOHALF)
+                               s->res.prod->flags |= SI_FL_NOLINGER;
+                       si_shutr(s->res.prod);
                }
 
                /* Once in a while we're woken up because the task expires. But
@@ -1817,7 +1799,7 @@ struct task *process_session(struct task *t)
                 * So let's not run a whole session processing if only an expiration
                 * timeout needs to be refreshed.
                 */
-               if (!((s->req->flags | s->rep->flags) &
+               if (!((s->req.flags | s->res.flags) &
                      (CF_SHUTR|CF_READ_ACTIVITY|CF_READ_TIMEOUT|CF_SHUTW|
                       CF_WRITE_ACTIVITY|CF_WRITE_TIMEOUT|CF_ANA_TIMEOUT)) &&
                    !((s->si[0].flags | s->si[1].flags) & (SI_FL_EXP|SI_FL_ERR)) &&
@@ -1848,7 +1830,7 @@ struct task *process_session(struct task *t)
                        si_shutr(&s->si[0]);
                        si_shutw(&s->si[0]);
                        stream_int_report_error(&s->si[0]);
-                       if (!(s->req->analysers) && !(s->rep->analysers)) {
+                       if (!(s->req.analysers) && !(s->res.analysers)) {
                                s->be->be_counters.cli_aborts++;
                                s->fe->fe_counters.cli_aborts++;
                                if (srv)
@@ -1869,7 +1851,7 @@ struct task *process_session(struct task *t)
                        s->be->be_counters.failed_resp++;
                        if (srv)
                                srv->counters.failed_resp++;
-                       if (!(s->req->analysers) && !(s->rep->analysers)) {
+                       if (!(s->req.analysers) && !(s->res.analysers)) {
                                s->be->be_counters.srv_aborts++;
                                s->fe->fe_counters.srv_aborts++;
                                if (srv)
@@ -1912,21 +1894,21 @@ struct task *process_session(struct task *t)
                t,
                s, s->flags,
                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->rep->cons->err_type, s->req->cons->err_type,
-               s->req->cons->conn_retries);
+               s->req.rex, s->res.wex,
+               s->req.flags, s->res.flags,
+               s->req.buf->i, s->req.buf->o, s->res.buf->i, s->res.buf->o, s->res.cons->state, s->req.cons->state,
+               s->res.cons->err_type, s->req.cons->err_type,
+               s->req.cons->conn_retries);
 
        /* nothing special to be done on client side */
-       if (unlikely(s->req->prod->state == SI_ST_DIS))
-               s->req->prod->state = SI_ST_CLO;
+       if (unlikely(s->req.prod->state == SI_ST_DIS))
+               s->req.prod->state = SI_ST_CLO;
 
        /* When a server-side connection is released, we have to count it and
         * check for pending connections on this server.
         */
-       if (unlikely(s->req->cons->state == SI_ST_DIS)) {
-               s->req->cons->state = SI_ST_CLO;
+       if (unlikely(s->req.cons->state == SI_ST_DIS)) {
+               s->req.cons->state = SI_ST_CLO;
                srv = objt_server(s->target);
                if (srv) {
                        if (s->flags & SN_CURR_SESS) {
@@ -1946,14 +1928,14 @@ struct task *process_session(struct task *t)
 
  resync_request:
        /* Analyse request */
-       if (((s->req->flags & ~rqf_last) & CF_MASK_ANALYSER) ||
-           ((s->req->flags ^ rqf_last) & CF_MASK_STATIC) ||
+       if (((s->req.flags & ~rqf_last) & CF_MASK_ANALYSER) ||
+           ((s->req.flags ^ rqf_last) & CF_MASK_STATIC) ||
            s->si[0].state != rq_prod_last ||
            s->si[1].state != rq_cons_last ||
            s->task->state & TASK_WOKEN_MSG) {
-               unsigned int flags = s->req->flags;
+               unsigned int flags = s->req.flags;
 
-               if (s->req->prod->state >= SI_ST_EST) {
+               if (s->req.prod->state >= SI_ST_EST) {
                        int max_loops = global.tune.maxpollevents;
                        unsigned int ana_list;
                        unsigned int ana_back;
@@ -1964,12 +1946,12 @@ struct task *process_session(struct task *t)
                         * enabling them again when it disables itself, so
                         * that other analysers are called in similar conditions.
                         */
-                       channel_auto_read(s->req);
-                       channel_auto_connect(s->req);
-                       channel_auto_close(s->req);
+                       channel_auto_read(&s->req);
+                       channel_auto_connect(&s->req);
+                       channel_auto_close(&s->req);
 
                        /* We will call all analysers for which a bit is set in
-                        * s->req->analysers, following the bit order from LSB
+                        * s->req.analysers, following the bit order from LSB
                         * to MSB. The analysers must remove themselves from
                         * the list when not needed. Any analyser may return 0
                         * to break out of the loop, either because of missing
@@ -2002,86 +1984,86 @@ struct task *process_session(struct task *t)
                         * analyser and must immediately loop again.
                         */
 
-                       ana_list = ana_back = s->req->analysers;
+                       ana_list = ana_back = s->req.analysers;
                        while (ana_list && max_loops--) {
                                /* Warning! ensure that analysers are always placed in ascending order! */
 
                                if (ana_list & AN_REQ_INSPECT_FE) {
-                                       if (!tcp_inspect_request(s, s->req, AN_REQ_INSPECT_FE))
+                                       if (!tcp_inspect_request(s, &s->req, AN_REQ_INSPECT_FE))
                                                break;
-                                       UPDATE_ANALYSERS(s->req->analysers, ana_list, ana_back, AN_REQ_INSPECT_FE);
+                                       UPDATE_ANALYSERS(s->req.analysers, ana_list, ana_back, AN_REQ_INSPECT_FE);
                                }
 
                                if (ana_list & AN_REQ_WAIT_HTTP) {
-                                       if (!http_wait_for_request(s, s->req, AN_REQ_WAIT_HTTP))
+                                       if (!http_wait_for_request(s, &s->req, AN_REQ_WAIT_HTTP))
                                                break;
-                                       UPDATE_ANALYSERS(s->req->analysers, ana_list, ana_back, AN_REQ_WAIT_HTTP);
+                                       UPDATE_ANALYSERS(s->req.analysers, ana_list, ana_back, AN_REQ_WAIT_HTTP);
                                }
 
                                if (ana_list & AN_REQ_HTTP_PROCESS_FE) {
-                                       if (!http_process_req_common(s, s->req, AN_REQ_HTTP_PROCESS_FE, s->fe))
+                                       if (!http_process_req_common(s, &s->req, AN_REQ_HTTP_PROCESS_FE, s->fe))
                                                break;
-                                       UPDATE_ANALYSERS(s->req->analysers, ana_list, ana_back, AN_REQ_HTTP_PROCESS_FE);
+                                       UPDATE_ANALYSERS(s->req.analysers, ana_list, ana_back, AN_REQ_HTTP_PROCESS_FE);
                                }
 
                                if (ana_list & AN_REQ_SWITCHING_RULES) {
-                                       if (!process_switching_rules(s, s->req, AN_REQ_SWITCHING_RULES))
+                                       if (!process_switching_rules(s, &s->req, AN_REQ_SWITCHING_RULES))
                                                break;
-                                       UPDATE_ANALYSERS(s->req->analysers, ana_list, ana_back, AN_REQ_SWITCHING_RULES);
+                                       UPDATE_ANALYSERS(s->req.analysers, ana_list, ana_back, AN_REQ_SWITCHING_RULES);
                                }
 
                                if (ana_list & AN_REQ_INSPECT_BE) {
-                                       if (!tcp_inspect_request(s, s->req, AN_REQ_INSPECT_BE))
+                                       if (!tcp_inspect_request(s, &s->req, AN_REQ_INSPECT_BE))
                                                break;
-                                       UPDATE_ANALYSERS(s->req->analysers, ana_list, ana_back, AN_REQ_INSPECT_BE);
+                                       UPDATE_ANALYSERS(s->req.analysers, ana_list, ana_back, AN_REQ_INSPECT_BE);
                                }
 
                                if (ana_list & AN_REQ_HTTP_PROCESS_BE) {
-                                       if (!http_process_req_common(s, s->req, AN_REQ_HTTP_PROCESS_BE, s->be))
+                                       if (!http_process_req_common(s, &s->req, AN_REQ_HTTP_PROCESS_BE, s->be))
                                                break;
-                                       UPDATE_ANALYSERS(s->req->analysers, ana_list, ana_back, AN_REQ_HTTP_PROCESS_BE);
+                                       UPDATE_ANALYSERS(s->req.analysers, ana_list, ana_back, AN_REQ_HTTP_PROCESS_BE);
                                }
 
                                if (ana_list & AN_REQ_HTTP_TARPIT) {
-                                       if (!http_process_tarpit(s, s->req, AN_REQ_HTTP_TARPIT))
+                                       if (!http_process_tarpit(s, &s->req, AN_REQ_HTTP_TARPIT))
                                                break;
-                                       UPDATE_ANALYSERS(s->req->analysers, ana_list, ana_back, AN_REQ_HTTP_TARPIT);
+                                       UPDATE_ANALYSERS(s->req.analysers, ana_list, ana_back, AN_REQ_HTTP_TARPIT);
                                }
 
                                if (ana_list & AN_REQ_SRV_RULES) {
-                                       if (!process_server_rules(s, s->req, AN_REQ_SRV_RULES))
+                                       if (!process_server_rules(s, &s->req, AN_REQ_SRV_RULES))
                                                break;
-                                       UPDATE_ANALYSERS(s->req->analysers, ana_list, ana_back, AN_REQ_SRV_RULES);
+                                       UPDATE_ANALYSERS(s->req.analysers, ana_list, ana_back, AN_REQ_SRV_RULES);
                                }
 
                                if (ana_list & AN_REQ_HTTP_INNER) {
-                                       if (!http_process_request(s, s->req, AN_REQ_HTTP_INNER))
+                                       if (!http_process_request(s, &s->req, AN_REQ_HTTP_INNER))
                                                break;
-                                       UPDATE_ANALYSERS(s->req->analysers, ana_list, ana_back, AN_REQ_HTTP_INNER);
+                                       UPDATE_ANALYSERS(s->req.analysers, ana_list, ana_back, AN_REQ_HTTP_INNER);
                                }
 
                                if (ana_list & AN_REQ_HTTP_BODY) {
-                                       if (!http_wait_for_request_body(s, s->req, AN_REQ_HTTP_BODY))
+                                       if (!http_wait_for_request_body(s, &s->req, AN_REQ_HTTP_BODY))
                                                break;
-                                       UPDATE_ANALYSERS(s->req->analysers, ana_list, ana_back, AN_REQ_HTTP_BODY);
+                                       UPDATE_ANALYSERS(s->req.analysers, ana_list, ana_back, AN_REQ_HTTP_BODY);
                                }
 
                                if (ana_list & AN_REQ_PRST_RDP_COOKIE) {
-                                       if (!tcp_persist_rdp_cookie(s, s->req, AN_REQ_PRST_RDP_COOKIE))
+                                       if (!tcp_persist_rdp_cookie(s, &s->req, AN_REQ_PRST_RDP_COOKIE))
                                                break;
-                                       UPDATE_ANALYSERS(s->req->analysers, ana_list, ana_back, AN_REQ_PRST_RDP_COOKIE);
+                                       UPDATE_ANALYSERS(s->req.analysers, ana_list, ana_back, AN_REQ_PRST_RDP_COOKIE);
                                }
 
                                if (ana_list & AN_REQ_STICKING_RULES) {
-                                       if (!process_sticking_rules(s, s->req, AN_REQ_STICKING_RULES))
+                                       if (!process_sticking_rules(s, &s->req, AN_REQ_STICKING_RULES))
                                                break;
-                                       UPDATE_ANALYSERS(s->req->analysers, ana_list, ana_back, AN_REQ_STICKING_RULES);
+                                       UPDATE_ANALYSERS(s->req.analysers, ana_list, ana_back, AN_REQ_STICKING_RULES);
                                }
 
                                if (ana_list & AN_REQ_HTTP_XFER_BODY) {
-                                       if (!http_request_forward_body(s, s->req, AN_REQ_HTTP_XFER_BODY))
+                                       if (!http_request_forward_body(s, &s->req, AN_REQ_HTTP_XFER_BODY))
                                                break;
-                                       UPDATE_ANALYSERS(s->req->analysers, ana_list, ana_back, AN_REQ_HTTP_XFER_BODY);
+                                       UPDATE_ANALYSERS(s->req.analysers, ana_list, ana_back, AN_REQ_HTTP_XFER_BODY);
                                }
                                break;
                        }
@@ -2089,10 +2071,10 @@ struct task *process_session(struct task *t)
 
                rq_prod_last = s->si[0].state;
                rq_cons_last = s->si[1].state;
-               s->req->flags &= ~CF_WAKE_ONCE;
-               rqf_last = s->req->flags;
+               s->req.flags &= ~CF_WAKE_ONCE;
+               rqf_last = s->req.flags;
 
-               if ((s->req->flags ^ flags) & CF_MASK_STATIC)
+               if ((s->req.flags ^ flags) & CF_MASK_STATIC)
                        goto resync_request;
        }
 
@@ -2100,31 +2082,31 @@ struct task *process_session(struct task *t)
         * because some response analysers may indirectly enable new request
         * analysers (eg: HTTP keep-alive).
         */
-       req_ana_back = s->req->analysers;
+       req_ana_back = s->req.analysers;
 
  resync_response:
        /* Analyse response */
 
-       if (((s->rep->flags & ~rpf_last) & CF_MASK_ANALYSER) ||
-                (s->rep->flags ^ rpf_last) & CF_MASK_STATIC ||
+       if (((s->res.flags & ~rpf_last) & CF_MASK_ANALYSER) ||
+                (s->res.flags ^ rpf_last) & CF_MASK_STATIC ||
                 s->si[0].state != rp_cons_last ||
                 s->si[1].state != rp_prod_last ||
                 s->task->state & TASK_WOKEN_MSG) {
-               unsigned int flags = s->rep->flags;
+               unsigned int flags = s->res.flags;
 
-               if ((s->rep->flags & CF_MASK_ANALYSER) &&
-                   (s->rep->analysers & AN_REQ_ALL)) {
+               if ((s->res.flags & CF_MASK_ANALYSER) &&
+                   (s->res.analysers & AN_REQ_ALL)) {
                        /* Due to HTTP pipelining, the HTTP request analyser might be waiting
                         * for some free space in the response buffer, so we might need to call
                         * it when something changes in the response buffer, but still we pass
                         * it the request buffer. Note that the SI state might very well still
                         * be zero due to us returning a flow of redirects!
                         */
-                       s->rep->analysers &= ~AN_REQ_ALL;
-                       s->req->flags |= CF_WAKE_ONCE;
+                       s->res.analysers &= ~AN_REQ_ALL;
+                       s->req.flags |= CF_WAKE_ONCE;
                }
 
-               if (s->rep->prod->state >= SI_ST_EST) {
+               if (s->res.prod->state >= SI_ST_EST) {
                        int max_loops = global.tune.maxpollevents;
                        unsigned int ana_list;
                        unsigned int ana_back;
@@ -2135,11 +2117,11 @@ struct task *process_session(struct task *t)
                         * it disables itself, so that other analysers are called
                         * in similar conditions.
                         */
-                       channel_auto_read(s->rep);
-                       channel_auto_close(s->rep);
+                       channel_auto_read(&s->res);
+                       channel_auto_close(&s->res);
 
                        /* We will call all analysers for which a bit is set in
-                        * s->rep->analysers, following the bit order from LSB
+                        * s->res.analysers, following the bit order from LSB
                         * to MSB. The analysers must remove themselves from
                         * the list when not needed. Any analyser may return 0
                         * to break out of the loop, either because of missing
@@ -2149,38 +2131,38 @@ struct task *process_session(struct task *t)
                         * are added in the middle.
                         */
 
-                       ana_list = ana_back = s->rep->analysers;
+                       ana_list = ana_back = s->res.analysers;
                        while (ana_list && max_loops--) {
                                /* Warning! ensure that analysers are always placed in ascending order! */
 
                                if (ana_list & AN_RES_INSPECT) {
-                                       if (!tcp_inspect_response(s, s->rep, AN_RES_INSPECT))
+                                       if (!tcp_inspect_response(s, &s->res, AN_RES_INSPECT))
                                                break;
-                                       UPDATE_ANALYSERS(s->rep->analysers, ana_list, ana_back, AN_RES_INSPECT);
+                                       UPDATE_ANALYSERS(s->res.analysers, ana_list, ana_back, AN_RES_INSPECT);
                                }
 
                                if (ana_list & AN_RES_WAIT_HTTP) {
-                                       if (!http_wait_for_response(s, s->rep, AN_RES_WAIT_HTTP))
+                                       if (!http_wait_for_response(s, &s->res, AN_RES_WAIT_HTTP))
                                                break;
-                                       UPDATE_ANALYSERS(s->rep->analysers, ana_list, ana_back, AN_RES_WAIT_HTTP);
+                                       UPDATE_ANALYSERS(s->res.analysers, ana_list, ana_back, AN_RES_WAIT_HTTP);
                                }
 
                                if (ana_list & AN_RES_STORE_RULES) {
-                                       if (!process_store_rules(s, s->rep, AN_RES_STORE_RULES))
+                                       if (!process_store_rules(s, &s->res, AN_RES_STORE_RULES))
                                                break;
-                                       UPDATE_ANALYSERS(s->rep->analysers, ana_list, ana_back, AN_RES_STORE_RULES);
+                                       UPDATE_ANALYSERS(s->res.analysers, ana_list, ana_back, AN_RES_STORE_RULES);
                                }
 
                                if (ana_list & AN_RES_HTTP_PROCESS_BE) {
-                                       if (!http_process_res_common(s, s->rep, AN_RES_HTTP_PROCESS_BE, s->be))
+                                       if (!http_process_res_common(s, &s->res, AN_RES_HTTP_PROCESS_BE, s->be))
                                                break;
-                                       UPDATE_ANALYSERS(s->rep->analysers, ana_list, ana_back, AN_RES_HTTP_PROCESS_BE);
+                                       UPDATE_ANALYSERS(s->res.analysers, ana_list, ana_back, AN_RES_HTTP_PROCESS_BE);
                                }
 
                                if (ana_list & AN_RES_HTTP_XFER_BODY) {
-                                       if (!http_response_forward_body(s, s->rep, AN_RES_HTTP_XFER_BODY))
+                                       if (!http_response_forward_body(s, &s->res, AN_RES_HTTP_XFER_BODY))
                                                break;
-                                       UPDATE_ANALYSERS(s->rep->analysers, ana_list, ana_back, AN_RES_HTTP_XFER_BODY);
+                                       UPDATE_ANALYSERS(s->res.analysers, ana_list, ana_back, AN_RES_HTTP_XFER_BODY);
                                }
                                break;
                        }
@@ -2188,17 +2170,17 @@ struct task *process_session(struct task *t)
 
                rp_cons_last = s->si[0].state;
                rp_prod_last = s->si[1].state;
-               rpf_last = s->rep->flags;
+               rpf_last = s->res.flags;
 
-               if ((s->rep->flags ^ flags) & CF_MASK_STATIC)
+               if ((s->res.flags ^ flags) & CF_MASK_STATIC)
                        goto resync_response;
        }
 
        /* maybe someone has added some request analysers, so we must check and loop */
-       if (s->req->analysers & ~req_ana_back)
+       if (s->req.analysers & ~req_ana_back)
                goto resync_request;
 
-       if ((s->req->flags & ~rqf_last) & CF_MASK_ANALYSER)
+       if ((s->req.flags & ~rqf_last) & CF_MASK_ANALYSER)
                goto resync_request;
 
        /* FIXME: here we should call protocol handlers which rely on
@@ -2213,24 +2195,24 @@ struct task *process_session(struct task *t)
         */
        srv = objt_server(s->target);
        if (unlikely(!(s->flags & SN_ERR_MASK))) {
-               if (s->req->flags & (CF_READ_ERROR|CF_READ_TIMEOUT|CF_WRITE_ERROR|CF_WRITE_TIMEOUT)) {
+               if (s->req.flags & (CF_READ_ERROR|CF_READ_TIMEOUT|CF_WRITE_ERROR|CF_WRITE_TIMEOUT)) {
                        /* Report it if the client got an error or a read timeout expired */
-                       s->req->analysers = 0;
-                       if (s->req->flags & CF_READ_ERROR) {
+                       s->req.analysers = 0;
+                       if (s->req.flags & CF_READ_ERROR) {
                                s->be->be_counters.cli_aborts++;
                                s->fe->fe_counters.cli_aborts++;
                                if (srv)
                                        srv->counters.cli_aborts++;
                                s->flags |= SN_ERR_CLICL;
                        }
-                       else if (s->req->flags & CF_READ_TIMEOUT) {
+                       else if (s->req.flags & CF_READ_TIMEOUT) {
                                s->be->be_counters.cli_aborts++;
                                s->fe->fe_counters.cli_aborts++;
                                if (srv)
                                        srv->counters.cli_aborts++;
                                s->flags |= SN_ERR_CLITO;
                        }
-                       else if (s->req->flags & CF_WRITE_ERROR) {
+                       else if (s->req.flags & CF_WRITE_ERROR) {
                                s->be->be_counters.srv_aborts++;
                                s->fe->fe_counters.srv_aborts++;
                                if (srv)
@@ -2246,24 +2228,24 @@ struct task *process_session(struct task *t)
                        }
                        sess_set_term_flags(s);
                }
-               else if (s->rep->flags & (CF_READ_ERROR|CF_READ_TIMEOUT|CF_WRITE_ERROR|CF_WRITE_TIMEOUT)) {
+               else if (s->res.flags & (CF_READ_ERROR|CF_READ_TIMEOUT|CF_WRITE_ERROR|CF_WRITE_TIMEOUT)) {
                        /* Report it if the server got an error or a read timeout expired */
-                       s->rep->analysers = 0;
-                       if (s->rep->flags & CF_READ_ERROR) {
+                       s->res.analysers = 0;
+                       if (s->res.flags & CF_READ_ERROR) {
                                s->be->be_counters.srv_aborts++;
                                s->fe->fe_counters.srv_aborts++;
                                if (srv)
                                        srv->counters.srv_aborts++;
                                s->flags |= SN_ERR_SRVCL;
                        }
-                       else if (s->rep->flags & CF_READ_TIMEOUT) {
+                       else if (s->res.flags & CF_READ_TIMEOUT) {
                                s->be->be_counters.srv_aborts++;
                                s->fe->fe_counters.srv_aborts++;
                                if (srv)
                                        srv->counters.srv_aborts++;
                                s->flags |= SN_ERR_SRVTO;
                        }
-                       else if (s->rep->flags & CF_WRITE_ERROR) {
+                       else if (s->res.flags & CF_WRITE_ERROR) {
                                s->be->be_counters.cli_aborts++;
                                s->fe->fe_counters.cli_aborts++;
                                if (srv)
@@ -2292,41 +2274,41 @@ struct task *process_session(struct task *t)
         * Note that we're checking CF_SHUTR_NOW as an indication of a possible
         * recent call to channel_abort().
         */
-       if (unlikely(!s->req->analysers &&
-           !(s->req->flags & (CF_SHUTW|CF_SHUTR_NOW)) &&
-           (s->req->prod->state >= SI_ST_EST) &&
-           (s->req->to_forward != CHN_INFINITE_FORWARD))) {
+       if (unlikely(!s->req.analysers &&
+           !(s->req.flags & (CF_SHUTW|CF_SHUTR_NOW)) &&
+           (s->req.prod->state >= SI_ST_EST) &&
+           (s->req.to_forward != CHN_INFINITE_FORWARD))) {
                /* This buffer is freewheeling, there's no analyser
                 * attached to it. If any data are left in, we'll permit them to
                 * move.
                 */
-               channel_auto_read(s->req);
-               channel_auto_connect(s->req);
-               channel_auto_close(s->req);
-               buffer_flush(s->req->buf);
+               channel_auto_read(&s->req);
+               channel_auto_connect(&s->req);
+               channel_auto_close(&s->req);
+               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).
                 */
-               if (!(s->req->flags & (CF_SHUTR|CF_SHUTW_NOW)))
-                       channel_forward(s->req, CHN_INFINITE_FORWARD);
+               if (!(s->req.flags & (CF_SHUTR|CF_SHUTW_NOW)))
+                       channel_forward(&s->req, CHN_INFINITE_FORWARD);
        }
 
        /* check if it is wise to enable kernel splicing to forward request data */
-       if (!(s->req->flags & (CF_KERN_SPLICING|CF_SHUTR)) &&
-           s->req->to_forward &&
+       if (!(s->req.flags & (CF_KERN_SPLICING|CF_SHUTR)) &&
+           s->req.to_forward &&
            (global.tune.options & GTUNE_USE_SPLICE) &&
            (objt_conn(s->si[0].end) && __objt_conn(s->si[0].end)->xprt && __objt_conn(s->si[0].end)->xprt->rcv_pipe) &&
            (objt_conn(s->si[1].end) && __objt_conn(s->si[1].end)->xprt && __objt_conn(s->si[1].end)->xprt->snd_pipe) &&
            (pipes_used < global.maxpipes) &&
            (((s->fe->options2|s->be->options2) & PR_O2_SPLIC_REQ) ||
             (((s->fe->options2|s->be->options2) & PR_O2_SPLIC_AUT) &&
-             (s->req->flags & CF_STREAMER_FAST)))) {
-               s->req->flags |= CF_KERN_SPLICING;
+             (s->req.flags & CF_STREAMER_FAST)))) {
+               s->req.flags |= CF_KERN_SPLICING;
        }
 
        /* reflect what the L7 analysers have seen last */
-       rqf_last = s->req->flags;
+       rqf_last = s->req.flags;
 
        /*
         * Now forward all shutdown requests between both sides of the buffer
@@ -2337,40 +2319,40 @@ struct task *process_session(struct task *t)
         * once the server has begun to respond. If a half-closed timeout is set, we adjust
         * the other side's timeout as well.
         */
-       if (unlikely((s->req->flags & (CF_SHUTW|CF_SHUTW_NOW|CF_AUTO_CLOSE|CF_SHUTR)) ==
+       if (unlikely((s->req.flags & (CF_SHUTW|CF_SHUTW_NOW|CF_AUTO_CLOSE|CF_SHUTR)) ==
                     (CF_AUTO_CLOSE|CF_SHUTR))) {
-               channel_shutw_now(s->req);
+               channel_shutw_now(&s->req);
                if (tick_isset(s->fe->timeout.clientfin)) {
-                       s->rep->wto = s->fe->timeout.clientfin;
-                       s->rep->wex = tick_add(now_ms, s->rep->wto);
+                       s->res.wto = s->fe->timeout.clientfin;
+                       s->res.wex = tick_add(now_ms, s->res.wto);
                }
        }
 
        /* shutdown(write) pending */
-       if (unlikely((s->req->flags & (CF_SHUTW|CF_SHUTW_NOW)) == CF_SHUTW_NOW &&
-                    channel_is_empty(s->req))) {
-               if (s->req->flags & CF_READ_ERROR)
-                       s->req->cons->flags |= SI_FL_NOLINGER;
-               si_shutw(s->req->cons);
+       if (unlikely((s->req.flags & (CF_SHUTW|CF_SHUTW_NOW)) == CF_SHUTW_NOW &&
+                    channel_is_empty(&s->req))) {
+               if (s->req.flags & CF_READ_ERROR)
+                       s->req.cons->flags |= SI_FL_NOLINGER;
+               si_shutw(s->req.cons);
                if (tick_isset(s->be->timeout.serverfin)) {
-                       s->rep->rto = s->be->timeout.serverfin;
-                       s->rep->rex = tick_add(now_ms, s->rep->rto);
+                       s->res.rto = s->be->timeout.serverfin;
+                       s->res.rex = tick_add(now_ms, s->res.rto);
                }
        }
 
        /* shutdown(write) done on server side, we must stop the client too */
-       if (unlikely((s->req->flags & (CF_SHUTW|CF_SHUTR|CF_SHUTR_NOW)) == CF_SHUTW &&
-                    !s->req->analysers))
-               channel_shutr_now(s->req);
+       if (unlikely((s->req.flags & (CF_SHUTW|CF_SHUTR|CF_SHUTR_NOW)) == CF_SHUTW &&
+                    !s->req.analysers))
+               channel_shutr_now(&s->req);
 
        /* shutdown(read) pending */
-       if (unlikely((s->req->flags & (CF_SHUTR|CF_SHUTR_NOW)) == CF_SHUTR_NOW)) {
-               if (s->req->prod->flags & SI_FL_NOHALF)
-                       s->req->prod->flags |= SI_FL_NOLINGER;
-               si_shutr(s->req->prod);
+       if (unlikely((s->req.flags & (CF_SHUTR|CF_SHUTR_NOW)) == CF_SHUTR_NOW)) {
+               if (s->req.prod->flags & SI_FL_NOHALF)
+                       s->req.prod->flags |= SI_FL_NOLINGER;
+               si_shutr(s->req.prod);
                if (tick_isset(s->fe->timeout.clientfin)) {
-                       s->rep->wto = s->fe->timeout.clientfin;
-                       s->rep->wex = tick_add(now_ms, s->rep->wto);
+                       s->res.wto = s->fe->timeout.clientfin;
+                       s->res.wex = tick_add(now_ms, s->res.wto);
                }
        }
 
@@ -2379,21 +2361,21 @@ struct task *process_session(struct task *t)
         *  - there are data scheduled for emission in the buffer
         *  - the CF_AUTO_CONNECT flag is set (active connection)
         */
-       if (s->req->cons->state == SI_ST_INI) {
-               if (!(s->req->flags & CF_SHUTW)) {
-                       if ((s->req->flags & CF_AUTO_CONNECT) || !channel_is_empty(s->req)) {
+       if (s->req.cons->state == SI_ST_INI) {
+               if (!(s->req.flags & CF_SHUTW)) {
+                       if ((s->req.flags & CF_AUTO_CONNECT) || !channel_is_empty(&s->req)) {
                                /* If we have an appctx, there is no connect method, so we
                                 * immediately switch to the connected state, otherwise we
                                 * perform a connection request.
                                 */
-                               s->req->cons->state = SI_ST_REQ; /* new connection requested */
-                               s->req->cons->conn_retries = s->be->conn_retries;
+                               s->req.cons->state = SI_ST_REQ; /* new connection requested */
+                               s->req.cons->conn_retries = s->be->conn_retries;
                        }
                }
                else {
-                       s->req->cons->state = SI_ST_CLO; /* shutw+ini = abort */
-                       channel_shutw_now(s->req);        /* fix buffer flags upon abort */
-                       channel_shutr_now(s->rep);
+                       s->req.cons->state = SI_ST_CLO; /* shutw+ini = abort */
+                       channel_shutw_now(&s->req);        /* fix buffer flags upon abort */
+                       channel_shutr_now(&s->res);
                }
        }
 
@@ -2434,11 +2416,11 @@ struct task *process_session(struct task *t)
        }
 
        /* Benchmarks have shown that it's optimal to do a full resync now */
-       if (s->req->prod->state == SI_ST_DIS || s->req->cons->state == SI_ST_DIS)
+       if (s->req.prod->state == SI_ST_DIS || s->req.cons->state == SI_ST_DIS)
                goto resync_stream_interface;
 
        /* otherwise we want to check if we need to resync the req buffer or not */
-       if ((s->req->flags ^ rqf_last) & CF_MASK_STATIC)
+       if ((s->req.flags ^ rqf_last) & CF_MASK_STATIC)
                goto resync_request;
 
        /* perform output updates to the response buffer */
@@ -2448,63 +2430,63 @@ struct task *process_session(struct task *t)
         * Note that we're checking CF_SHUTR_NOW as an indication of a possible
         * recent call to channel_abort().
         */
-       if (unlikely(!s->rep->analysers &&
-           !(s->rep->flags & (CF_SHUTW|CF_SHUTR_NOW)) &&
-           (s->rep->prod->state >= SI_ST_EST) &&
-           (s->rep->to_forward != CHN_INFINITE_FORWARD))) {
+       if (unlikely(!s->res.analysers &&
+           !(s->res.flags & (CF_SHUTW|CF_SHUTR_NOW)) &&
+           (s->res.prod->state >= SI_ST_EST) &&
+           (s->res.to_forward != CHN_INFINITE_FORWARD))) {
                /* This buffer is freewheeling, there's no analyser
                 * attached to it. If any data are left in, we'll permit them to
                 * move.
                 */
-               channel_auto_read(s->rep);
-               channel_auto_close(s->rep);
-               buffer_flush(s->rep->buf);
+               channel_auto_read(&s->res);
+               channel_auto_close(&s->res);
+               buffer_flush(s->res.buf);
 
                /* We'll let data flow between the producer (if still connected)
                 * to the consumer.
                 */
-               if (!(s->rep->flags & (CF_SHUTR|CF_SHUTW_NOW)))
-                       channel_forward(s->rep, CHN_INFINITE_FORWARD);
+               if (!(s->res.flags & (CF_SHUTR|CF_SHUTW_NOW)))
+                       channel_forward(&s->res, CHN_INFINITE_FORWARD);
 
                /* if we have no analyser anymore in any direction and have a
                 * tunnel timeout set, use it now. Note that we must respect
                 * the half-closed timeouts as well.
                 */
-               if (!s->req->analysers && s->be->timeout.tunnel) {
-                       s->req->rto = s->req->wto = s->rep->rto = s->rep->wto =
+               if (!s->req.analysers && s->be->timeout.tunnel) {
+                       s->req.rto = s->req.wto = s->res.rto = s->res.wto =
                                s->be->timeout.tunnel;
 
-                       if ((s->req->flags & CF_SHUTR) && tick_isset(s->fe->timeout.clientfin))
-                               s->rep->wto = s->fe->timeout.clientfin;
-                       if ((s->req->flags & CF_SHUTW) && tick_isset(s->be->timeout.serverfin))
-                               s->rep->rto = s->be->timeout.serverfin;
-                       if ((s->rep->flags & CF_SHUTR) && tick_isset(s->be->timeout.serverfin))
-                               s->req->wto = s->be->timeout.serverfin;
-                       if ((s->rep->flags & CF_SHUTW) && tick_isset(s->fe->timeout.clientfin))
-                               s->req->rto = s->fe->timeout.clientfin;
-
-                       s->req->rex = tick_add(now_ms, s->req->rto);
-                       s->req->wex = tick_add(now_ms, s->req->wto);
-                       s->rep->rex = tick_add(now_ms, s->rep->rto);
-                       s->rep->wex = tick_add(now_ms, s->rep->wto);
+                       if ((s->req.flags & CF_SHUTR) && tick_isset(s->fe->timeout.clientfin))
+                               s->res.wto = s->fe->timeout.clientfin;
+                       if ((s->req.flags & CF_SHUTW) && tick_isset(s->be->timeout.serverfin))
+                               s->res.rto = s->be->timeout.serverfin;
+                       if ((s->res.flags & CF_SHUTR) && tick_isset(s->be->timeout.serverfin))
+                               s->req.wto = s->be->timeout.serverfin;
+                       if ((s->res.flags & CF_SHUTW) && tick_isset(s->fe->timeout.clientfin))
+                               s->req.rto = s->fe->timeout.clientfin;
+
+                       s->req.rex = tick_add(now_ms, s->req.rto);
+                       s->req.wex = tick_add(now_ms, s->req.wto);
+                       s->res.rex = tick_add(now_ms, s->res.rto);
+                       s->res.wex = tick_add(now_ms, s->res.wto);
                }
        }
 
        /* check if it is wise to enable kernel splicing to forward response data */
-       if (!(s->rep->flags & (CF_KERN_SPLICING|CF_SHUTR)) &&
-           s->rep->to_forward &&
+       if (!(s->res.flags & (CF_KERN_SPLICING|CF_SHUTR)) &&
+           s->res.to_forward &&
            (global.tune.options & GTUNE_USE_SPLICE) &&
            (objt_conn(s->si[0].end) && __objt_conn(s->si[0].end)->xprt && __objt_conn(s->si[0].end)->xprt->snd_pipe) &&
            (objt_conn(s->si[1].end) && __objt_conn(s->si[1].end)->xprt && __objt_conn(s->si[1].end)->xprt->rcv_pipe) &&
            (pipes_used < global.maxpipes) &&
            (((s->fe->options2|s->be->options2) & PR_O2_SPLIC_RTR) ||
             (((s->fe->options2|s->be->options2) & PR_O2_SPLIC_AUT) &&
-             (s->rep->flags & CF_STREAMER_FAST)))) {
-               s->rep->flags |= CF_KERN_SPLICING;
+             (s->res.flags & CF_STREAMER_FAST)))) {
+               s->res.flags |= CF_KERN_SPLICING;
        }
 
        /* reflect what the L7 analysers have seen last */
-       rpf_last = s->rep->flags;
+       rpf_last = s->res.flags;
 
        /*
         * Now forward all shutdown requests between both sides of the buffer
@@ -2515,53 +2497,53 @@ struct task *process_session(struct task *t)
         */
 
        /* first, let's check if the response buffer needs to shutdown(write) */
-       if (unlikely((s->rep->flags & (CF_SHUTW|CF_SHUTW_NOW|CF_AUTO_CLOSE|CF_SHUTR)) ==
+       if (unlikely((s->res.flags & (CF_SHUTW|CF_SHUTW_NOW|CF_AUTO_CLOSE|CF_SHUTR)) ==
                     (CF_AUTO_CLOSE|CF_SHUTR))) {
-               channel_shutw_now(s->rep);
+               channel_shutw_now(&s->res);
                if (tick_isset(s->be->timeout.serverfin)) {
-                       s->req->wto = s->be->timeout.serverfin;
-                       s->req->wex = tick_add(now_ms, s->req->wto);
+                       s->req.wto = s->be->timeout.serverfin;
+                       s->req.wex = tick_add(now_ms, s->req.wto);
                }
        }
 
        /* shutdown(write) pending */
-       if (unlikely((s->rep->flags & (CF_SHUTW|CF_SHUTW_NOW)) == CF_SHUTW_NOW &&
-                    channel_is_empty(s->rep))) {
-               si_shutw(s->rep->cons);
+       if (unlikely((s->res.flags & (CF_SHUTW|CF_SHUTW_NOW)) == CF_SHUTW_NOW &&
+                    channel_is_empty(&s->res))) {
+               si_shutw(s->res.cons);
                if (tick_isset(s->fe->timeout.clientfin)) {
-                       s->req->rto = s->fe->timeout.clientfin;
-                       s->req->rex = tick_add(now_ms, s->req->rto);
+                       s->req.rto = s->fe->timeout.clientfin;
+                       s->req.rex = tick_add(now_ms, s->req.rto);
                }
        }
 
        /* shutdown(write) done on the client side, we must stop the server too */
-       if (unlikely((s->rep->flags & (CF_SHUTW|CF_SHUTR|CF_SHUTR_NOW)) == CF_SHUTW) &&
-           !s->rep->analysers)
-               channel_shutr_now(s->rep);
+       if (unlikely((s->res.flags & (CF_SHUTW|CF_SHUTR|CF_SHUTR_NOW)) == CF_SHUTW) &&
+           !s->res.analysers)
+               channel_shutr_now(&s->res);
 
        /* shutdown(read) pending */
-       if (unlikely((s->rep->flags & (CF_SHUTR|CF_SHUTR_NOW)) == CF_SHUTR_NOW)) {
-               if (s->rep->prod->flags & SI_FL_NOHALF)
-                       s->rep->prod->flags |= SI_FL_NOLINGER;
-               si_shutr(s->rep->prod);
+       if (unlikely((s->res.flags & (CF_SHUTR|CF_SHUTR_NOW)) == CF_SHUTR_NOW)) {
+               if (s->res.prod->flags & SI_FL_NOHALF)
+                       s->res.prod->flags |= SI_FL_NOLINGER;
+               si_shutr(s->res.prod);
                if (tick_isset(s->be->timeout.serverfin)) {
-                       s->req->wto = s->be->timeout.serverfin;
-                       s->req->wex = tick_add(now_ms, s->req->wto);
+                       s->req.wto = s->be->timeout.serverfin;
+                       s->req.wex = tick_add(now_ms, s->req.wto);
                }
        }
 
-       if (s->req->prod->state == SI_ST_DIS || s->req->cons->state == SI_ST_DIS)
+       if (s->req.prod->state == SI_ST_DIS || s->req.cons->state == SI_ST_DIS)
                goto resync_stream_interface;
 
-       if (s->req->flags != rqf_last)
+       if (s->req.flags != rqf_last)
                goto resync_request;
 
-       if ((s->rep->flags ^ rpf_last) & CF_MASK_STATIC)
+       if ((s->res.flags ^ rpf_last) & CF_MASK_STATIC)
                goto resync_response;
 
        /* we're interested in getting wakeups again */
-       s->req->prod->flags &= ~SI_FL_DONT_WAKE;
-       s->req->cons->flags &= ~SI_FL_DONT_WAKE;
+       s->req.prod->flags &= ~SI_FL_DONT_WAKE;
+       s->req.cons->flags &= ~SI_FL_DONT_WAKE;
 
        /* This is needed only when debugging is enabled, to indicate
         * client-side or server-side close. Please note that in the unlikely
@@ -2590,20 +2572,20 @@ struct task *process_session(struct task *t)
                }
        }
 
-       if (likely((s->rep->cons->state != SI_ST_CLO) ||
-                  (s->req->cons->state > SI_ST_INI && s->req->cons->state < SI_ST_CLO))) {
+       if (likely((s->res.cons->state != SI_ST_CLO) ||
+                  (s->req.cons->state > SI_ST_INI && s->req.cons->state < SI_ST_CLO))) {
 
                if ((s->fe->options & PR_O_CONTSTATS) && (s->flags & SN_BE_ASSIGNED))
                        session_process_counters(s);
 
-               if (s->rep->cons->state == SI_ST_EST && obj_type(s->rep->cons->end) != OBJ_TYPE_APPCTX)
-                       si_update(s->rep->cons);
+               if (s->res.cons->state == SI_ST_EST && obj_type(s->res.cons->end) != OBJ_TYPE_APPCTX)
+                       si_update(s->res.cons);
 
-               if (s->req->cons->state == SI_ST_EST && obj_type(s->req->cons->end) != OBJ_TYPE_APPCTX)
-                       si_update(s->req->cons);
+               if (s->req.cons->state == SI_ST_EST && obj_type(s->req.cons->end) != OBJ_TYPE_APPCTX)
+                       si_update(s->req.cons);
 
-               s->req->flags &= ~(CF_READ_NULL|CF_READ_PARTIAL|CF_WRITE_NULL|CF_WRITE_PARTIAL|CF_READ_ATTACHED);
-               s->rep->flags &= ~(CF_READ_NULL|CF_READ_PARTIAL|CF_WRITE_NULL|CF_WRITE_PARTIAL|CF_READ_ATTACHED);
+               s->req.flags &= ~(CF_READ_NULL|CF_READ_PARTIAL|CF_WRITE_NULL|CF_WRITE_PARTIAL|CF_READ_ATTACHED);
+               s->res.flags &= ~(CF_READ_NULL|CF_READ_PARTIAL|CF_WRITE_NULL|CF_WRITE_PARTIAL|CF_READ_ATTACHED);
                s->si[0].prev_state = s->si[0].state;
                s->si[1].prev_state = s->si[1].state;
                s->si[0].flags &= ~(SI_FL_ERR|SI_FL_EXP);
@@ -2617,10 +2599,10 @@ struct task *process_session(struct task *t)
                 * request timeout is set and the server has not yet sent a response.
                 */
 
-               if ((s->rep->flags & (CF_AUTO_CLOSE|CF_SHUTR)) == 0 &&
-                   (tick_isset(s->req->wex) || tick_isset(s->rep->rex))) {
-                       s->req->flags |= CF_READ_NOEXP;
-                       s->req->rex = TICK_ETERNITY;
+               if ((s->res.flags & (CF_AUTO_CLOSE|CF_SHUTR)) == 0 &&
+                   (tick_isset(s->req.wex) || tick_isset(s->res.rex))) {
+                       s->req.flags |= CF_READ_NOEXP;
+                       s->req.rex = TICK_ETERNITY;
                }
 
                /* When any of the stream interfaces is attached to an applet,
@@ -2632,7 +2614,7 @@ struct task *process_session(struct task *t)
                 * both functions are always called and that we wake up if at
                 * least one did something.
                 */
-               if ((si_applet_call(s->req->cons) | si_applet_call(s->rep->cons)) != 0) {
+               if ((si_applet_call(s->req.cons) | si_applet_call(s->res.cons)) != 0) {
                        if (task_in_rq(t)) {
                                t->expire = TICK_ETERNITY;
                                session_release_buffers(s);
@@ -2641,10 +2623,10 @@ struct task *process_session(struct task *t)
                }
 
        update_exp_and_leave:
-               t->expire = tick_first(tick_first(s->req->rex, s->req->wex),
-                                      tick_first(s->rep->rex, s->rep->wex));
-               if (s->req->analysers)
-                       t->expire = tick_first(t->expire, s->req->analyse_exp);
+               t->expire = tick_first(tick_first(s->req.rex, s->req.wex),
+                                      tick_first(s->res.rex, s->res.wex));
+               if (s->req.analysers)
+                       t->expire = tick_first(t->expire, s->req.analyse_exp);
 
                if (s->si[0].exp)
                        t->expire = tick_first(t->expire, s->si[0].exp);
@@ -2656,8 +2638,8 @@ struct task *process_session(struct task *t)
                fprintf(stderr,
                        "[%u] queuing with exp=%u req->rex=%u req->wex=%u req->ana_exp=%u"
                        " rep->rex=%u rep->wex=%u, si[0].exp=%u, si[1].exp=%u, cs=%d, ss=%d\n",
-                       now_ms, t->expire, s->req->rex, s->req->wex, s->req->analyse_exp,
-                       s->rep->rex, s->rep->wex, s->si[0].exp, s->si[1].exp, s->si[0].state, s->si[1].state);
+                       now_ms, t->expire, s->req.rex, s->req.wex, s->req.analyse_exp,
+                       s->res.rex, s->res.wex, s->si[0].exp, s->si[1].exp, s->si[0].state, s->si[1].state);
 #endif
 
 #ifdef DEBUG_DEV
@@ -2725,7 +2707,7 @@ struct task *process_session(struct task *t)
        /* let's do a final log if we need it */
        if (!LIST_ISEMPTY(&s->fe->logformat) && s->logs.logwait &&
            !(s->flags & SN_MONITOR) &&
-           (!(s->fe->options & PR_O_NULLNOLOG) || s->req->total)) {
+           (!(s->fe->options & PR_O_NULLNOLOG) || s->req.total)) {
                s->do_log(s);
        }
 
@@ -2860,11 +2842,11 @@ void default_srv_error(struct session *s, struct stream_interface *si)
 /* kill a session and set the termination flags to <why> (one of SN_ERR_*) */
 void session_shutdown(struct session *session, int why)
 {
-       if (session->req->flags & (CF_SHUTW|CF_SHUTW_NOW))
+       if (session->req.flags & (CF_SHUTW|CF_SHUTW_NOW))
                return;
 
-       channel_shutw_now(session->req);
-       channel_shutr_now(session->rep);
+       channel_shutw_now(&session->req);
+       channel_shutr_now(&session->res);
        session->task->nice = 1024;
        if (!(session->flags & SN_ERR_MASK))
                session->flags |= why;