BUG/MEDIUM: Special-case http_proxy when dealing with outgoing connections.

http_proxy is special, because it creates its connection and conn_stream
earlier. So in assign_server(), check that the connection associated with
the conn_stream has a destination address set, and in connect_server(),
use the connection and the conn_stream already attached to the
stream_interface, instead of looking for a connection in the session, and
creating a new conn_stream.
diff --git a/src/backend.c b/src/backend.c
index 150ea7c..404c5b3 100644
--- a/src/backend.c
+++ b/src/backend.c
@@ -744,10 +744,16 @@
 	else if (s->be->options & (PR_O_DISPATCH | PR_O_TRANSP)) {
 		s->target = &s->be->obj_type;
 	}
-	else if ((s->be->options & PR_O_HTTP_PROXY) &&
-		 conn && is_addr(&conn->addr.to)) {
-		/* in proxy mode, we need a valid destination address */
-		s->target = &s->be->obj_type;
+	else if ((s->be->options & PR_O_HTTP_PROXY)) {
+		conn = cs_conn(objt_cs(s->si[1].end));
+
+		if (conn && is_addr(&conn->addr.to)) {
+			/* in proxy mode, we need a valid destination address */
+			s->target = &s->be->obj_type;
+		} else {
+			err = SRV_STATUS_NOSRV;
+			goto out;
+		}
 	}
 	else {
 		err = SRV_STATUS_NOSRV;
@@ -1109,33 +1115,45 @@
 	struct connection *cli_conn = NULL;
 	struct connection *srv_conn = NULL;
 	struct connection *old_conn = NULL;
-	struct conn_stream *srv_cs;
+	struct conn_stream *srv_cs = NULL;
 	struct server *srv;
 	int reuse = 0;
 	int err;
 	int i;
 
 
-	for (i = 0; i < MAX_SRV_LIST; i++) {
-		if (s->sess->srv_list[i].target == s->target) {
-			list_for_each_entry(srv_conn, &s->sess->srv_list[i].list,
-			    session_list) {
-				if (conn_xprt_ready(srv_conn) &&
-				    srv_conn->mux && (srv_conn->mux->avail_streams(srv_conn) > 0)) {
-					reuse = 1;
-					break;
+	if (!(s->be->options & PR_O_HTTP_PROXY)) {
+		for (i = 0; i < MAX_SRV_LIST; i++) {
+			if (s->sess->srv_list[i].target == s->target) {
+				list_for_each_entry(srv_conn, &s->sess->srv_list[i].list,
+				    session_list) {
+					if (conn_xprt_ready(srv_conn) &&
+					    srv_conn->mux && (srv_conn->mux->avail_streams(srv_conn) > 0)) {
+						reuse = 1;
+						break;
+					}
 				}
 			}
 		}
-	}
-	if (!srv_conn) {
-		for (i = 0; i < MAX_SRV_LIST; i++) {
-			if (!LIST_ISEMPTY(&s->sess->srv_list[i].list)) {
-				srv_conn = LIST_ELEM(&s->sess->srv_list[i].list,
-				    struct connection *, session_list);
-				break;
+		if (!srv_conn) {
+			for (i = 0; i < MAX_SRV_LIST; i++) {
+				if (!LIST_ISEMPTY(&s->sess->srv_list[i].list)) {
+					srv_conn = LIST_ELEM(&s->sess->srv_list[i].list,
+					    struct connection *, session_list);
+					break;
+				}
 			}
 		}
+	} else {
+		/* http_proxy is special, we can't just reuse any connection,
+		 * as the destination may be different. We should have created
+		 * a connection and a conn_stream earlier, so get the
+		 * connection from the conn_stream.
+		 */
+		srv_cs = objt_cs(s->si[1].end);
+		old_conn = srv_conn = cs_conn(srv_cs);
+		if (old_conn)
+			reuse = 1;
 	}
 	old_conn = srv_conn;
 
@@ -1227,14 +1245,19 @@
 		srv_conn = conn_new();
 		srv_cs = NULL;
 	} else {
-		if (srv_conn->mux->avail_streams(srv_conn) == 1) {
-			/* No more streams available, remove it from the list */
-			LIST_DEL(&srv_conn->list);
-			LIST_INIT(&srv_conn->list);
+		/* We already created a cs earlier when using http_proxy, so
+		 * only create a new one if we don't have one already.
+		 */
+		if (!srv_cs) {
+			if (srv_conn->mux->avail_streams(srv_conn) == 1) {
+				/* No more streams available, remove it from the list */
+				LIST_DEL(&srv_conn->list);
+				LIST_INIT(&srv_conn->list);
+			}
+			srv_cs = srv_conn->mux->attach(srv_conn);
+			if (srv_cs)
+				si_attach_cs(&s->si[1], srv_cs);
 		}
-		srv_cs = srv_conn->mux->attach(srv_conn);
-		if (srv_cs)
-			si_attach_cs(&s->si[1], srv_cs);
 	}
 	if (srv_conn && old_conn != srv_conn) {
 		srv_conn->owner = s->sess;