MEDIUM: proto_htx: Adapt htx_wait_for_request_body to handle HTX messages

This version is simpler than the legacy one because the parsing is no more
handled by the analyzer. So now we just need to wait to have more data to move
on.
diff --git a/src/proto_htx.c b/src/proto_htx.c
index 8bf60fc..4617349 100644
--- a/src/proto_htx.c
+++ b/src/proto_htx.c
@@ -1029,11 +1029,22 @@
 	struct session *sess = s->sess;
 	struct http_txn *txn = s->txn;
 	struct http_msg *msg = &s->txn->req;
+	struct htx *htx;
 
-	// TODO: Disabled for now
-	req->analyse_exp = TICK_ETERNITY;
-	req->analysers &= ~an_bit;
-	return 1;
+
+	DPRINTF(stderr,"[%u] %s: stream=%p b=%p, exp(r,w)=%u,%u bf=%08x bh=%lu analysers=%02x\n",
+		now_ms, __FUNCTION__,
+		s,
+		req,
+		req->rex, req->wex,
+		req->flags,
+		ci_data(req),
+		req->analysers);
+
+	htx = htx_from_buf(&req->buf);
+
+	if (msg->msg_state < HTTP_MSG_BODY)
+		goto missing_data;
 
 	/* We have to parse the HTTP request body to find any required data.
 	 * "balance url_param check_post" should have been the only way to get
@@ -1041,99 +1052,45 @@
 	 * related structures are ready.
 	 */
 
-	if (msg->msg_state < HTTP_MSG_CHUNK_SIZE) {
-		/* This is the first call */
-		if (msg->msg_state < HTTP_MSG_BODY)
-			goto missing_data;
-
-		if (msg->msg_state < HTTP_MSG_100_SENT) {
-			/* If we have HTTP/1.1 and Expect: 100-continue, then we must
-			 * send an HTTP/1.1 100 Continue intermediate response.
-			 */
-			if (msg->flags & HTTP_MSGF_VER_11) {
-				struct hdr_ctx ctx;
-				ctx.idx = 0;
-				/* Expect is allowed in 1.1, look for it */
-				if (http_find_header2("Expect", 6, ci_head(req), &txn->hdr_idx, &ctx) &&
-				    unlikely(ctx.vlen == 12 && strncasecmp(ctx.line+ctx.val, "100-continue", 12) == 0)) {
-					co_inject(&s->res, HTTP_100.ptr, HTTP_100.len);
-					http_remove_header2(&txn->req, &txn->hdr_idx, &ctx);
-				}
-			}
-			msg->msg_state = HTTP_MSG_100_SENT;
-		}
-
-		/* we have msg->sov which points to the first byte of message body.
-		 * ci_head(req) still points to the beginning of the message. We
-		 * must save the body in msg->next because it survives buffer
-		 * re-alignments.
+	if (msg->msg_state < HTTP_MSG_DATA) {
+		/* If we have HTTP/1.1 and Expect: 100-continue, then we must
+		 * send an HTTP/1.1 100 Continue intermediate response.
 		 */
-		msg->next = msg->sov;
+		if (msg->flags & HTTP_MSGF_VER_11) {
+			struct ist hdr = { .ptr = "Expect", .len = 6 };
+			struct http_hdr_ctx ctx;
 
-		if (msg->flags & HTTP_MSGF_TE_CHNK)
-			msg->msg_state = HTTP_MSG_CHUNK_SIZE;
-		else
-			msg->msg_state = HTTP_MSG_DATA;
-	}
+			ctx.blk = NULL;
+			/* Expect is allowed in 1.1, look for it */
+			if (http_find_header(htx, hdr, &ctx, 0) &&
+			    unlikely(isteqi(ctx.value, ist2("100-continue", 12)))) {
+				struct htx *rsp = htx_from_buf(&s->res.buf);
+				struct htx_blk *blk;
 
-	if (!(msg->flags & HTTP_MSGF_TE_CHNK)) {
-		/* We're in content-length mode, we just have to wait for enough data. */
-		if (http_body_bytes(msg) < msg->body_len)
-			goto missing_data;
-
-		/* OK we have everything we need now */
-		goto http_end;
-	}
-
-	/* OK here we're parsing a chunked-encoded message */
-
-	if (msg->msg_state == HTTP_MSG_CHUNK_SIZE) {
-		/* read the chunk size and assign it to ->chunk_len, then
-		 * set ->sov and ->next to point to the body and switch to DATA or
-		 * TRAILERS state.
-		 */
-		unsigned int chunk;
-		int ret = h1_parse_chunk_size(&req->buf, co_data(req) + msg->next, c_data(req), &chunk);
-
-		if (!ret)
-			goto missing_data;
-		else if (ret < 0) {
-			msg->err_pos = ci_data(req) + ret;
-			if (msg->err_pos < 0)
-				msg->err_pos += req->buf.size;
-			stream_inc_http_err_ctr(s);
-			goto return_bad_req;
+				blk = htx_add_oob(rsp, HTTP_100);
+				if (!blk)
+					goto missing_data;
+				b_set_data(&s->res.buf, b_size(&s->res.buf));
+				c_adv(&s->res, HTTP_100.len);
+				s->res.total += HTTP_100.len;
+				http_remove_header(htx, &ctx);
+			}
 		}
-
-		msg->chunk_len = chunk;
-		msg->body_len += chunk;
-
-		msg->sol = ret;
-		msg->next += ret;
-		msg->msg_state = msg->chunk_len ? HTTP_MSG_DATA : HTTP_MSG_TRAILERS;
 	}
 
-	/* Now we're in HTTP_MSG_DATA or HTTP_MSG_TRAILERS state.
-	 * We have the first data byte is in msg->sov + msg->sol. We're waiting
-	 * for at least a whole chunk or the whole content length bytes after
-	 * msg->sov + msg->sol.
-	 */
-	if (msg->msg_state == HTTP_MSG_TRAILERS)
-		goto http_end;
-
-	if (http_body_bytes(msg) >= msg->body_len)   /* we have enough bytes now */
-		goto http_end;
+	msg->msg_state = HTTP_MSG_DATA;
 
- missing_data:
-	/* we get here if we need to wait for more data. If the buffer is full,
-	 * we have the maximum we can expect.
+	/* Now we're in HTTP_MSG_DATA. We just need to know if all data have
+	 * been received or if the buffer is full.
 	 */
-	if (channel_full(req, global.tune.maxrewrite))
+	if (htx_get_tail_type(htx) >= HTX_BLK_EOD ||
+	    htx_used_space(htx) + global.tune.maxrewrite >= htx->size)
 		goto http_end;
 
+ missing_data:
 	if ((req->flags & CF_READ_TIMEOUT) || tick_is_expired(req->analyse_exp, now_ms)) {
 		txn->status = 408;
-		http_reply_and_close(s, txn->status, http_error_message(s));
+		htx_reply_and_close(s, txn->status, http_error_message(s));
 
 		if (!(s->flags & SF_ERR_MASK))
 			s->flags |= SF_ERR_CLITO;
@@ -1167,7 +1124,7 @@
 	txn->req.err_state = txn->req.msg_state;
 	txn->req.msg_state = HTTP_MSG_ERROR;
 	txn->status = 400;
-	http_reply_and_close(s, txn->status, http_error_message(s));
+	htx_reply_and_close(s, txn->status, http_error_message(s));
 
 	if (!(s->flags & SF_ERR_MASK))
 		s->flags |= SF_ERR_PRXCOND;