]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: http: fix http-reuse when frontend and backend differ
authorWilly Tarreau <w@1wt.eu>
Mon, 7 Dec 2015 16:04:59 +0000 (17:04 +0100)
committerWilly Tarreau <w@1wt.eu>
Mon, 7 Dec 2015 16:04:59 +0000 (17:04 +0100)
Krishna Kumar reported that the following configuration doesn't permit
HTTP reuse between two clients :

    frontend private-frontend
        mode http
        bind :8001
        default_backend private-backend

    backend private-backend
        mode http
        http-reuse always
        server bck 127.0.0.1:8888

The reason for this is that in http_end_txn_clean_session() we check the
stream's backend backend's http-reuse option before deciding whether the
backend connection should be moved back to the server's pool or not. But
since we're doing this after the call to http_reset_txn(), the backend is
reset to match the frontend, which doesn't have the option. However it
will work fine in a setup involving a "listen" section.

We just need to keep a pointer to the current backend before calling
http_reset_txn(). The code does that and replaces the few remaining
references to s->be inside the same function so that if any part of
code were to be moved later, this trap doesn't happen again.

This fix must be backported to 1.6.

src/proto_http.c

index 1d000717279fb8b9f8f83567bedf3fca34640f71..5fea6c4fc3e4dd098f8146f475154a46f9691896 100644 (file)
@@ -5120,6 +5120,7 @@ void http_end_txn_clean_session(struct stream *s)
 {
        int prev_status = s->txn->status;
        struct proxy *fe = strm_fe(s);
+       struct proxy *be = s->be;
        struct connection *srv_conn;
        struct server *srv;
        unsigned int prev_flags = s->txn->flags;
@@ -5142,7 +5143,7 @@ void http_end_txn_clean_session(struct stream *s)
        }
 
        if (s->flags & SF_BE_ASSIGNED) {
-               s->be->beconn--;
+               be->beconn--;
                if (unlikely(s->srv_conn))
                        sess_change_server(s, NULL);
        }
@@ -5163,11 +5164,11 @@ void http_end_txn_clean_session(struct stream *s)
                                fe->fe_counters.p.http.comp_rsp++;
                }
                if ((s->flags & SF_BE_ASSIGNED) &&
-                   (s->be->mode == PR_MODE_HTTP)) {
-                       s->be->be_counters.p.http.rsp[n]++;
-                       s->be->be_counters.p.http.cum_req++;
+                   (be->mode == PR_MODE_HTTP)) {
+                       be->be_counters.p.http.rsp[n]++;
+                       be->be_counters.p.http.cum_req++;
                        if (s->comp_algo && (s->flags & SF_COMP_READY))
-                               s->be->be_counters.p.http.comp_rsp++;
+                               be->be_counters.p.http.comp_rsp++;
                }
        }
 
@@ -5207,7 +5208,7 @@ void http_end_txn_clean_session(struct stream *s)
                        s->flags &= ~SF_CURR_SESS;
                        objt_server(s->target)->cur_sess--;
                }
-               if (may_dequeue_tasks(objt_server(s->target), s->be))
+               if (may_dequeue_tasks(objt_server(s->target), be))
                        process_srv_queue(objt_server(s->target));
        }
 
@@ -5286,7 +5287,7 @@ void http_end_txn_clean_session(struct stream *s)
                if (!srv)
                        si_idle_conn(&s->si[1], NULL);
                else if ((srv_conn->flags & CO_FL_PRIVATE) ||
-                        ((s->be->options & PR_O_REUSE_MASK) == PR_O_REUSE_NEVR))
+                        ((be->options & PR_O_REUSE_MASK) == PR_O_REUSE_NEVR))
                        si_idle_conn(&s->si[1], &srv->priv_conns);
                else if (prev_flags & TX_NOT_FIRST)
                        /* note: we check the request, not the connection, but