MINOR: http: Switch requests/responses in TUNNEL mode only by checking txn flags

Today, the only way to have a request or a response in HTTP_MSG_TUNNEL state is
to have the flag TX_CON_WANT_TUN set on the transaction. So this is a symmetric
state. Both the request and the response are switch in same time in this
state. This can be done only by checking transaction flags instead of relying on
the other side state. This is the purpose of this patch.

This way, if for any reason we need to switch only one side in TUNNEL mode, it
will be possible. And to prepare asymmetric cases, we check channel flags in
DONE _AND_ TUNNEL states.

WARNING: This patch will be used to fix a bug. The fix will be commited in a
very next commit. So if the fix is backported, this one must be backported too.
diff --git a/src/proto_http.c b/src/proto_http.c
index d257d66..6f8c5f4 100644
--- a/src/proto_http.c
+++ b/src/proto_http.c
@@ -5313,7 +5313,7 @@
 	unsigned int old_flags = chn->flags;
 	unsigned int old_state = txn->req.msg_state;
 
-	if (unlikely(txn->req.msg_state < HTTP_MSG_BODY))
+	if (unlikely(txn->req.msg_state < HTTP_MSG_DONE))
 		return 0;
 
 	if (txn->req.msg_state == HTTP_MSG_DONE) {
@@ -5357,13 +5357,6 @@
 			goto wait_other_side;
 		}
 
-		if (txn->rsp.msg_state == HTTP_MSG_TUNNEL) {
-			/* if any side switches to tunnel mode, the other one does too */
-			channel_auto_read(chn);
-			txn->req.msg_state = HTTP_MSG_TUNNEL;
-			goto wait_other_side;
-		}
-
 		/* When we get here, it means that both the request and the
 		 * response have finished receiving. Depending on the connection
 		 * mode, we'll have to wait for the last bytes to leave in either
@@ -5396,20 +5389,7 @@
 			}
 		}
 
-		if (chn->flags & (CF_SHUTW|CF_SHUTW_NOW)) {
-			/* if we've just closed an output, let's switch */
-			s->si[1].flags |= SI_FL_NOLINGER;  /* we want to close ASAP */
-
-			if (!channel_is_empty(chn)) {
-				txn->req.msg_state = HTTP_MSG_CLOSING;
-				goto http_msg_closing;
-			}
-			else {
-				txn->req.msg_state = HTTP_MSG_CLOSED;
-				goto http_msg_closed;
-			}
-		}
-		goto wait_other_side;
+		goto check_channel_flags;
 	}
 
 	if (txn->req.msg_state == HTTP_MSG_CLOSING) {
@@ -5438,6 +5418,16 @@
 		goto wait_other_side;
 	}
 
+ check_channel_flags:
+	/* Here, we are in HTTP_MSG_DONE or HTTP_MSG_TUNNEL */
+	if (chn->flags & (CF_SHUTW|CF_SHUTW_NOW)) {
+		/* if we've just closed an output, let's switch */
+		s->si[1].flags |= SI_FL_NOLINGER;  /* we want to close ASAP */
+		txn->req.msg_state = HTTP_MSG_CLOSING;
+		goto http_msg_closing;
+	}
+
+
  wait_other_side:
 	return txn->req.msg_state != old_state || chn->flags != old_flags;
 }
@@ -5457,7 +5447,7 @@
 	unsigned int old_flags = chn->flags;
 	unsigned int old_state = txn->rsp.msg_state;
 
-	if (unlikely(txn->rsp.msg_state < HTTP_MSG_BODY))
+	if (unlikely(txn->rsp.msg_state < HTTP_MSG_DONE))
 		return 0;
 
 	if (txn->rsp.msg_state == HTTP_MSG_DONE) {
@@ -5480,14 +5470,6 @@
 			goto wait_other_side;
 		}
 
-		if (txn->req.msg_state == HTTP_MSG_TUNNEL) {
-			/* if any side switches to tunnel mode, the other one does too */
-			channel_auto_read(chn);
-			txn->rsp.msg_state = HTTP_MSG_TUNNEL;
-			chn->flags |= CF_NEVER_WAIT;
-			goto wait_other_side;
-		}
-
 		/* When we get here, it means that both the request and the
 		 * response have finished receiving. Depending on the connection
 		 * mode, we'll have to wait for the last bytes to leave in either
@@ -5525,18 +5507,7 @@
 				txn->rsp.msg_state = HTTP_MSG_TUNNEL;
 		}
 
-		if (chn->flags & (CF_SHUTW|CF_SHUTW_NOW)) {
-			/* if we've just closed an output, let's switch */
-			if (!channel_is_empty(chn)) {
-				txn->rsp.msg_state = HTTP_MSG_CLOSING;
-				goto http_msg_closing;
-			}
-			else {
-				txn->rsp.msg_state = HTTP_MSG_CLOSED;
-				goto http_msg_closed;
-			}
-		}
-		goto wait_other_side;
+		goto check_channel_flags;
 	}
 
 	if (txn->rsp.msg_state == HTTP_MSG_CLOSING) {
@@ -5567,6 +5538,14 @@
 		goto wait_other_side;
 	}
 
+ check_channel_flags:
+	/* Here, we are in HTTP_MSG_DONE or HTTP_MSG_TUNNEL */
+	if (chn->flags & (CF_SHUTW|CF_SHUTW_NOW)) {
+		/* if we've just closed an output, let's switch */
+		txn->rsp.msg_state = HTTP_MSG_CLOSING;
+		goto http_msg_closing;
+	}
+
  wait_other_side:
 	/* We force the response to leave immediately if we're waiting for the
 	 * other side, since there is no pending shutdown to push it out.