mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-11-07 20:11:17 +01:00
BUG/MEDIUM: http: fix http-reuse when frontend and backend differ
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.
This commit is contained in:
parent
baf9794b4d
commit
858b103631
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user