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.
diff --git a/src/proto_http.c b/src/proto_http.c
index 1d00071..5fea6c4 100644
--- a/src/proto_http.c
+++ b/src/proto_http.c
@@ -5120,6 +5120,7 @@
{
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 @@
}
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 @@
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 @@
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 @@
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