BUG/MEDIUM: http/applet: Finish request processing when a service is registered

In the analyzers AN_REQ_HTTP_PROCESS_FE/BE, when a service is registered, it is
important to not interrupt remaining processing but just the http-request rules
processing. Otherwise, the part that handles the applets installation is
skipped.

Among the several effects, if the service is registered on a frontend (not a
listen), the forwarding of the request is skipped because all analyzers are not
set on the request channel. If the service does not depends on it, the response
is still produced and forwarded to the client. But the stream is infinitly
blocked because the request is not fully consumed. This issue was reported on
Github, see #151.

So this bug is fixed thanks to the new action return ACT_RET_DONE. Once a
service is registered, the action process_use_service() still returns
ACT_RET_STOP. But now, only rules processing is stopped. As a side effet, the
action http_action_reject() must now return ACT_RET_DONE to really stop all
processing.

This patch must be backported to 2.0. It depends on the commit introducing the
return code ACT_RET_DONE.

(cherry picked from commit 8f1aa77b423b85012c062149f16ceb8f3aacefea)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
diff --git a/src/hlua.c b/src/hlua.c
index af24004..a2669be 100644
--- a/src/hlua.c
+++ b/src/hlua.c
@@ -6794,7 +6794,7 @@
 			return ACT_RET_ERR;
 		}
 		if (s->hlua->flags & HLUA_STOP)
-			return ACT_RET_STOP;
+			return ACT_RET_DONE;
 		return ACT_RET_CONT;
 
 	/* yield. */
diff --git a/src/http_act.c b/src/http_act.c
index 65d9595..0653dd5 100644
--- a/src/http_act.c
+++ b/src/http_act.c
@@ -269,7 +269,7 @@
  * alternative to the silent-drop action to defend against DoS attacks, and may
  * also be used with HTTP/2 to close a connection instead of just a stream.
  * The txn status is unchanged, indicating no response was sent. The termination
- * flags will indicate "PR". It always returns ACT_RET_STOP.
+ * flags will indicate "PR". It always returns ACT_RET_DONE.
  */
 static enum act_return http_action_reject(struct act_rule *rule, struct proxy *px,
                                           struct session *sess, struct stream *s, int flags)
@@ -290,7 +290,7 @@
 	if (!(s->flags & SF_FINST_MASK))
 		s->flags |= SF_FINST_R;
 
-	return ACT_RET_STOP;
+	return ACT_RET_DONE;
 }
 
 /* parse the "reject" action:
diff --git a/src/proto_http.c b/src/proto_http.c
index bfdb199..35f86ef 100644
--- a/src/proto_http.c
+++ b/src/proto_http.c
@@ -1788,6 +1788,9 @@
 			case ACT_RET_CONT:
 				break;
 			case ACT_RET_STOP:
+				rule_ret = HTTP_RULE_RES_STOP;
+				goto end;
+			case ACT_RET_DONE:
 				rule_ret = HTTP_RULE_RES_DONE;
 				goto end;
 			case ACT_RET_YIELD:
@@ -2198,6 +2201,9 @@
 			case ACT_RET_STOP:
 				rule_ret = HTTP_RULE_RES_STOP;
 				goto end;
+			case ACT_RET_DONE:
+				rule_ret = HTTP_RULE_RES_DONE;
+				goto end;
 			case ACT_RET_YIELD:
 				s->current_rule = rule;
 				rule_ret = HTTP_RULE_RES_YIELD;
@@ -2588,7 +2594,7 @@
 	 * by a possible reqrep, while they are processed *after* so that a
 	 * reqdeny can still block them. This clearly needs to change in 1.6!
 	 */
-	if (stats_check_uri(&s->si[1], txn, px)) {
+	if (!s->target && stats_check_uri(&s->si[1], txn, px)) {
 		s->target = &http_stats_applet.obj_type;
 		if (unlikely(!si_register_handler(&s->si[1], objt_applet(s->target)))) {
 			txn->status = 500;
diff --git a/src/proto_htx.c b/src/proto_htx.c
index 6cbd33b..d5119c1 100644
--- a/src/proto_htx.c
+++ b/src/proto_htx.c
@@ -540,7 +540,7 @@
 	 * by a possible reqrep, while they are processed *after* so that a
 	 * reqdeny can still block them. This clearly needs to change in 1.6!
 	 */
-	if (htx_stats_check_uri(s, txn, px)) {
+	if (!s->target && htx_stats_check_uri(s, txn, px)) {
 		s->target = &http_stats_applet.obj_type;
 		if (unlikely(!si_register_handler(&s->si[1], objt_applet(s->target)))) {
 			txn->status = 500;
@@ -3086,6 +3086,9 @@
 					case ACT_RET_CONT:
 						break;
 					case ACT_RET_STOP:
+						rule_ret = HTTP_RULE_RES_STOP;
+						goto end;
+					case ACT_RET_DONE:
 						rule_ret = HTTP_RULE_RES_DONE;
 						goto end;
 					case ACT_RET_YIELD:
@@ -3478,6 +3481,9 @@
 					case ACT_RET_STOP:
 						rule_ret = HTTP_RULE_RES_STOP;
 						goto end;
+					case ACT_RET_DONE:
+						rule_ret = HTTP_RULE_RES_DONE;
+						goto end;
 					case ACT_RET_YIELD:
 						s->current_rule = rule;
 						rule_ret = HTTP_RULE_RES_YIELD;