MEDIUM: channel/htx: Add functions for forward HTX data

To ease the fast forwarding and the infinte forwarding on HTX proxies, 2
functions have been added to let the channel be almost aware of the way data are
stored in its buffer. By calling these functions instead of legacy ones, we are
sure to forward the right amount of data.
diff --git a/src/proto_htx.c b/src/proto_htx.c
index 3232d0a..c613e72 100644
--- a/src/proto_htx.c
+++ b/src/proto_htx.c
@@ -1245,10 +1245,8 @@
 		 * right length is then restored. We must do that, because when an HTX
 		 * message is stored into a buffer, it appears as full.
 		 */
-		b_set_data(&req->buf, co_data(req));
-		if (msg->flags & HTTP_MSGF_XFER_LEN)
-			htx->extra -= channel_forward(req, htx->extra);
-		b_set_data(&req->buf, b_size(&req->buf));
+		if ((msg->flags & HTTP_MSGF_XFER_LEN) && htx->extra)
+			htx->extra -= channel_htx_forward(req, htx, htx->extra);
 	}
 
 	/* Check if the end-of-message is reached and if so, switch the message
@@ -2185,10 +2183,8 @@
 		 * right length is then restored. We must do that, because when an HTX
 		 * message is stored into a buffer, it appears as full.
 		 */
-		b_set_data(&res->buf, co_data(res));
-		if (msg->flags & HTTP_MSGF_XFER_LEN)
-			htx->extra -= channel_forward(res, htx->extra);
-		b_set_data(&res->buf, b_size(&res->buf));
+		if ((msg->flags & HTTP_MSGF_XFER_LEN) && htx->extra)
+			htx->extra -= channel_htx_forward(res, htx, htx->extra);
 	}
 
 	if (!(msg->flags & HTTP_MSGF_XFER_LEN)) {
diff --git a/src/stream.c b/src/stream.c
index ed913d1..be58e77 100644
--- a/src/stream.c
+++ b/src/stream.c
@@ -46,6 +46,7 @@
 #include <proto/hdr_idx.h>
 #include <proto/hlua.h>
 #include <proto/http_rules.h>
+#include <proto/htx.h>
 #include <proto/listener.h>
 #include <proto/log.h>
 #include <proto/raw_sock.h>
@@ -2184,19 +2185,27 @@
 		channel_auto_close(req);
 		c_adv(req, ci_data(req));
 
-		/* We'll let data flow between the producer (if still connected)
-		 * to the consumer (which might possibly not be connected yet).
-		 */
-		if (!(req->flags & (CF_SHUTR|CF_SHUTW_NOW)))
-			channel_forward_forever(req);
+		if (IS_HTX_STRM(s) && s->txn) {
+			/* We'll let data flow between the producer (if still connected)
+			 * to the consumer (which might possibly not be connected yet).
+			 */
+			if (!(req->flags & (CF_SHUTR|CF_SHUTW_NOW)))
+				channel_htx_forward_forever(req, htxbuf(&req->buf));
+		}
+		else {
+			/* We'll let data flow between the producer (if still connected)
+			 * to the consumer (which might possibly not be connected yet).
+			 */
+			if (!(req->flags & (CF_SHUTR|CF_SHUTW_NOW)))
+				channel_forward_forever(req);
 
-		/* Just in order to support fetching HTTP contents after start
-		 * of forwarding when the HTTP forwarding analyser is not used,
-		 * we simply reset msg->sov so that HTTP rewinding points to the
-		 * headers.
-		 */
-		if (IS_HTX_STRM(s) && s->txn)
+			/* Just in order to support fetching HTTP contents after start
+			 * of forwarding when the HTTP forwarding analyser is not used,
+			 * we simply reset msg->sov so that HTTP rewinding points to the
+			 * headers.
+			 */
 			s->txn->req.sov = s->txn->req.eoh + s->txn->req.eol - co_data(req);
+		}
 	}
 
 	/* check if it is wise to enable kernel splicing to forward request data */
@@ -2345,19 +2354,28 @@
 		channel_auto_close(res);
 		c_adv(res, ci_data(res));
 
-		/* We'll let data flow between the producer (if still connected)
-		 * to the consumer.
-		 */
-		if (!(res->flags & (CF_SHUTR|CF_SHUTW_NOW)))
-			channel_forward_forever(res);
 
-		/* Just in order to support fetching HTTP contents after start
-		 * of forwarding when the HTTP forwarding analyser is not used,
-		 * we simply reset msg->sov so that HTTP rewinding points to the
-		 * headers.
-		 */
-		if (IS_HTX_STRM(s) && s->txn)
+		if (IS_HTX_STRM(s) && s->txn) {
+			/* We'll let data flow between the producer (if still connected)
+			 * to the consumer.
+			 */
+			if (!(res->flags & (CF_SHUTR|CF_SHUTW_NOW)))
+				channel_htx_forward_forever(res, htxbuf(&res->buf));
+		}
+		else {
+			/* We'll let data flow between the producer (if still connected)
+			 * to the consumer.
+			 */
+			if (!(res->flags & (CF_SHUTR|CF_SHUTW_NOW)))
+				channel_forward_forever(res);
+
+			/* Just in order to support fetching HTTP contents after start
+			 * of forwarding when the HTTP forwarding analyser is not used,
+			 * we simply reset msg->sov so that HTTP rewinding points to the
+			 * headers.
+			 */
 			s->txn->rsp.sov = s->txn->rsp.eoh + s->txn->rsp.eol - co_data(res);
+		}
 
 		/* if we have no analyser anymore in any direction and have a
 		 * tunnel timeout set, use it now. Note that we must respect