On Tue, Dec 08, 2015 at 07:44:45AM +0530, Krishna Kumar (Engineering) wrote: > Great, will be glad to test and report on the finding. Thanks!
Sorry I forgot to post the patch after committing it. Here it comes. Regarding the second point, in the end it's not a bug, it's simply because we don't have connection pools yet, and I forgot that keeping an orphan backend connection was only possible with connection pools :-) Willy
commit 58b318c613b6209d6fe3c9ad38cd11f6814bf7ab Author: Willy Tarreau <[email protected]> Date: Mon Dec 7 17:04:59 2015 +0100 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. (cherry picked from commit 858b103631db41c608660210eb37a9e09ee9f086) 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 @@ 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

