[MEDIUM] move the HTTP request body analyser out of process_request().

A new function http_process_request_body() has been created to process
the request body. Next step is now to clean up process_request().
diff --git a/include/proto/proto_http.h b/include/proto/proto_http.h
index 535611d..343bbe6 100644
--- a/include/proto/proto_http.h
+++ b/include/proto/proto_http.h
@@ -64,6 +64,7 @@
 int process_srv_conn(struct session *t);
 int process_request(struct session *t);
 int http_process_tarpit(struct session *s, struct buffer *req);
+int http_process_request_body(struct session *s, struct buffer *req);
 int process_response(struct session *t);
 
 int produce_content(struct session *s);
diff --git a/src/proto_http.c b/src/proto_http.c
index ab8c255..4fdb21b 100644
--- a/src/proto_http.c
+++ b/src/proto_http.c
@@ -2359,82 +2359,6 @@
 		; // to keep gcc happy
 	}
 
-	if (req->analysers & AN_REQ_HTTP_BODY) {
-		/* 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
-		 * into this. We were brought here after HTTP header analysis, so all
-		 * related structures are ready.
-		 */
-		struct http_msg *msg = &t->txn.req;
-		unsigned long body = msg->sol[msg->eoh] == '\r' ? msg->eoh + 2 : msg->eoh + 1;
-		long long limit = t->be->url_param_post_limit;
-		struct hdr_ctx ctx;
-
-		ctx.idx = 0;
-
-		/* now if we have a length, we'll take the hint */
-		http_find_header2("Transfer-Encoding", 17, msg->sol, &t->txn.hdr_idx, &ctx);
-		if (ctx.idx && ctx.vlen >= 7 && strncasecmp(ctx.line+ctx.val, "chunked", 7) == 0) {
-			unsigned int chunk = 0;
-			while (body < req->l && !HTTP_IS_CRLF(msg->sol[body])) {
-				char c = msg->sol[body];
-				if (ishex(c)) {
-					unsigned int hex = toupper(c) - '0';
-					if (hex > 9)
-						hex -= 'A' - '9' - 1;
-					chunk = (chunk << 4) | hex;
-				} else
-					break;
-				body++;
-			}
-			if (body + 2 >= req->l) /* we want CRLF too */
-				goto http_body_end; /* end of buffer? data missing! */
-
-			if (memcmp(msg->sol+body, "\r\n", 2) != 0)
-				goto http_body_end; /* chunked encoding len ends with CRLF, and we don't have it yet */
-
-			body += 2; // skip CRLF
-
-			/* if we support more then one chunk here, we have to do it again when assigning server
-			 * 1. how much entity data do we have? new var
-			 * 2. should save entity_start, entity_cursor, elen & rlen in req; so we don't repeat scanning here
-			 * 3. test if elen > limit, or set new limit to elen if 0 (end of entity found)
-			 */
-
-			if (chunk < limit)
-				limit = chunk;                  /* only reading one chunk */
-		} else {
-			if (msg->hdr_content_len < limit)
-				limit = msg->hdr_content_len;
-		}
-
-	http_body_end:
-		/* we leave once we know we have nothing left to do. This means that we have
-		 * enough bytes, or that we know we'll not get any more (buffer full, read
-		 * buffer closed).
-		 */
-		if (req->l - body >= limit ||             /* enough bytes! */
-		    req->flags & (BF_FULL | BF_READ_ERROR | BF_SHUTR | BF_READ_TIMEOUT) ||
-		    tick_is_expired(req->analyse_exp, now_ms)) {
-			/* The situation will not evolve, so let's give up on the analysis. */
-			t->logs.tv_request = now;  /* update the request timer to reflect full request */
-			req->analysers &= ~AN_REQ_HTTP_BODY;
-			req->analyse_exp = TICK_ETERNITY;
-		}
-		else {
-			/* Not enough data. We'll re-use the http-request
-			 * timeout here. Ideally, we should set the timeout
-			 * relative to the accept() date. We just set the
-			 * request timeout once at the beginning of the
-			 * request.
-			 */
-			buffer_write_dis(req);
-			if (!tick_isset(req->analyse_exp))
-				req->analyse_exp = tick_add_ifset(now_ms, t->fe->timeout.httpreq);
-			return 0;
-		}
-	}
-
 	/* Note: eventhough nobody should set an unknown flag, clearing them right now will
 	 * probably reduce one day's debugging session.
 	 */
@@ -2489,6 +2413,91 @@
 	return 0;
 }
 
+/* This function is an analyser which processes the HTTP request body. It looks
+ * for parameters to be used for the load balancing algorithm (url_param). It
+ * must only be called after the standard HTTP request processing has occurred,
+ * because it expects the request to be parsed. It returns zero if it needs to
+ * read more data, or 1 once it has completed its analysis.
+ */
+int http_process_request_body(struct session *s, struct buffer *req)
+{
+	struct http_msg *msg = &s->txn.req;
+	unsigned long body = msg->sol[msg->eoh] == '\r' ? msg->eoh + 2 : msg->eoh + 1;
+	long long limit = s->be->url_param_post_limit;
+	struct hdr_ctx ctx;
+
+	/* 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
+	 * into this. We were brought here after HTTP header analysis, so all
+	 * related structures are ready.
+	 */
+
+	ctx.idx = 0;
+
+	/* now if we have a length, we'll take the hint */
+	http_find_header2("Transfer-Encoding", 17, msg->sol, &s->txn.hdr_idx, &ctx);
+	if (ctx.idx && ctx.vlen >= 7 && strncasecmp(ctx.line+ctx.val, "chunked", 7) == 0) {
+		unsigned int chunk = 0;
+		while (body < req->l && !HTTP_IS_CRLF(msg->sol[body])) {
+			char c = msg->sol[body];
+			if (ishex(c)) {
+				unsigned int hex = toupper(c) - '0';
+				if (hex > 9)
+					hex -= 'A' - '9' - 1;
+				chunk = (chunk << 4) | hex;
+			} else
+				break;
+			body++;
+		}
+		if (body + 2 >= req->l) /* we want CRLF too */
+			goto http_body_end; /* end of buffer? data missing! */
+
+		if (memcmp(msg->sol+body, "\r\n", 2) != 0)
+			goto http_body_end; /* chunked encoding len ends with CRLF, and we don't have it yet */
+
+		body += 2; // skip CRLF
+
+		/* if we support more then one chunk here, we have to do it again when assigning server
+		 * 1. how much entity data do we have? new var
+		 * 2. should save entity_start, entity_cursor, elen & rlen in req; so we don't repeat scanning here
+		 * 3. test if elen > limit, or set new limit to elen if 0 (end of entity found)
+		 */
+
+		if (chunk < limit)
+			limit = chunk;                  /* only reading one chunk */
+	} else {
+		if (msg->hdr_content_len < limit)
+			limit = msg->hdr_content_len;
+	}
+
+ http_body_end:
+	/* we leave once we know we have nothing left to do. This means that we have
+	 * enough bytes, or that we know we'll not get any more (buffer full, read
+	 * buffer closed).
+	 */
+	if (req->l - body >= limit ||             /* enough bytes! */
+	    req->flags & (BF_FULL | BF_READ_ERROR | BF_SHUTR | BF_READ_TIMEOUT) ||
+	    tick_is_expired(req->analyse_exp, now_ms)) {
+		/* The situation will not evolve, so let's give up on the analysis. */
+		s->logs.tv_request = now;  /* update the request timer to reflect full request */
+		req->analysers &= ~AN_REQ_HTTP_BODY;
+		req->analyse_exp = TICK_ETERNITY;
+		return 1;
+	}
+	else {
+		/* Not enough data. We'll re-use the http-request
+		 * timeout here. Ideally, we should set the timeout
+		 * relative to the accept() date. We just set the
+		 * request timeout once at the beginning of the
+		 * request.
+		 */
+		buffer_write_dis(req);
+		if (!tick_isset(req->analyse_exp))
+			req->analyse_exp = tick_add_ifset(now_ms, s->fe->timeout.httpreq);
+		return 0;
+	}
+}
+
 /* This function performs all the processing enabled for the current response.
  * It normally returns zero, but may return 1 if it absolutely needs to be
  * called again after other functions. It relies on buffers flags, and updates
diff --git a/src/session.c b/src/session.c
index 34d3d0a..9a9e469 100644
--- a/src/session.c
+++ b/src/session.c
@@ -713,6 +713,10 @@
 					if (!http_process_tarpit(s, s->req))
 						break;
 
+				if (s->req->analysers & AN_REQ_HTTP_BODY)
+					if (!http_process_request_body(s, s->req))
+						break;
+
 				/* Just make sure that nobody set a wrong flag causing an endless loop */
 				s->req->analysers &= AN_REQ_INSPECT | AN_REQ_HTTP_HDR | AN_REQ_HTTP_TARPIT | AN_REQ_HTTP_BODY;