MINOR: http-rules: Handle internal errors during HTTP rules evaluation

The HTTP_RULE_RES_ERROR code is now used by HTTP analyzers to handle internal
errors during HTTP rules evaluation. It is used instead of HTTP_RULE_RES_BADREQ,
used for invalid requests/responses. In addition, the SF_ERR_RESOURCE flag is
set on the stream when an allocation failure happens.

Note that the return value of http-response rules evaluation is now tested in
the same way than the result of http-request rules evaluation.
diff --git a/src/http_ana.c b/src/http_ana.c
index e63323b..983c5eb 100644
--- a/src/http_ana.c
+++ b/src/http_ana.c
@@ -515,6 +515,9 @@
 
 		case HTTP_RULE_RES_BADREQ: /* failed with a bad request */
 			goto return_bad_req;
+
+		case HTTP_RULE_RES_ERROR: /* failed with a bad request */
+			goto return_int_err;
 		}
 	}
 
@@ -554,6 +557,12 @@
 
 		if (verdict == HTTP_RULE_RES_ABRT) /* stats auth / stats http-request auth */
 			goto return_prx_cond;
+
+		if (verdict == HTTP_RULE_RES_BADREQ) /* failed with a bad request */
+			goto return_bad_req;
+
+		if (verdict == HTTP_RULE_RES_ERROR) /* failed with a bad request */
+			goto return_int_err;
 	}
 
 	/* Proceed with the applets now. */
@@ -1931,19 +1940,31 @@
 		if (ret == HTTP_RULE_RES_CONT) {
 			ret = http_res_get_intercept_rule(cur_proxy, &cur_proxy->http_res_rules, s);
 
-				goto return_bad_res;
+			switch (ret) {
+			case HTTP_RULE_RES_YIELD: /* some data miss, call the function later. */
+				goto return_prx_yield;
+
+			case HTTP_RULE_RES_CONT:
+			case HTTP_RULE_RES_STOP: /* nothing to do */
+				break;
+
+			case HTTP_RULE_RES_DENY: /* deny or tarpit */
+				goto deny;
 
-			if (ret == HTTP_RULE_RES_DONE)
+			case HTTP_RULE_RES_ABRT: /* abort request, response already sent */
+				goto return_prx_cond;
+
+			case HTTP_RULE_RES_DONE: /* OK, but terminate request processing (eg: redirect) */
 				goto done;
-		}
 
-		/* we need to be called again. */
-		if (ret == HTTP_RULE_RES_YIELD)
-			goto return_prx_yield;
+			case HTTP_RULE_RES_BADREQ: /* failed with a bad request */
+				goto return_bad_res;
 
-		/* has the response been denied ? */
-		if (txn->flags & TX_SVDENY)
-			goto deny;
+			case HTTP_RULE_RES_ERROR: /* failed with a bad request */
+				goto return_int_err;
+			}
+
+		}
 
 		/* check whether we're already working on the frontend */
 		if (cur_proxy == sess->fe)
@@ -2929,14 +2950,14 @@
 				 */
 				rule_ret = HTTP_RULE_RES_ABRT;
 				if (http_reply_40x_unauthorized(s, auth_realm) == -1)
-					rule_ret = HTTP_RULE_RES_BADREQ;
+					rule_ret = HTTP_RULE_RES_ERROR;
 				stream_inc_http_err_ctr(s);
 				goto end;
 
 			case ACT_HTTP_REDIR:
 				rule_ret = HTTP_RULE_RES_DONE;
 				if (!http_apply_redirect_rule(rule->arg.redir, s, txn))
-					rule_ret = HTTP_RULE_RES_BADREQ;
+					rule_ret = HTTP_RULE_RES_ERROR;
 				goto end;
 
 			case ACT_HTTP_SET_NICE:
@@ -2961,7 +2982,7 @@
 							  ist2(rule->arg.hdr_add.name, rule->arg.hdr_add.name_len),
 							  &rule->arg.hdr_add.fmt,
 							  rule->arg.hdr_add.re, rule->action)) {
-					rule_ret = HTTP_RULE_RES_BADREQ;
+					rule_ret = HTTP_RULE_RES_ERROR;
 					goto end;
 				}
 				break;
@@ -2986,7 +3007,9 @@
 
 				replace = alloc_trash_chunk();
 				if (!replace) {
-					rule_ret = HTTP_RULE_RES_BADREQ;
+					if (!(s->flags & SF_ERR_MASK))
+						s->flags |= SF_ERR_RESOURCE;
+					rule_ret = HTTP_RULE_RES_ERROR;
 					goto end;
 				}
 
@@ -3031,7 +3054,9 @@
 				/* allocate key */
 				key = alloc_trash_chunk();
 				if (!key) {
-					rule_ret = HTTP_RULE_RES_BADREQ;
+					if (!(s->flags & SF_ERR_MASK))
+						s->flags |= SF_ERR_RESOURCE;
+					rule_ret = HTTP_RULE_RES_ERROR;
 					goto end;
 				}
 
@@ -3061,7 +3086,9 @@
 				/* allocate key */
 				key = alloc_trash_chunk();
 				if (!key) {
-					rule_ret = HTTP_RULE_RES_BADREQ;
+					if (!(s->flags & SF_ERR_MASK))
+						s->flags |= SF_ERR_RESOURCE;
+					rule_ret = HTTP_RULE_RES_ERROR;
 					goto end;
 				}
 
@@ -3092,7 +3119,9 @@
 				/* allocate key */
 				key = alloc_trash_chunk();
 				if (!key) {
-					rule_ret = HTTP_RULE_RES_BADREQ;
+					if (!(s->flags & SF_ERR_MASK))
+						s->flags |= SF_ERR_RESOURCE;
+					rule_ret = HTTP_RULE_RES_ERROR;
 					goto end;
 				}
 
@@ -3100,7 +3129,9 @@
 				value = alloc_trash_chunk();
 				if (!value) {
 					free_trash_chunk(key);
-					rule_ret = HTTP_RULE_RES_BADREQ;
+					if (!(s->flags & SF_ERR_MASK))
+						s->flags |= SF_ERR_RESOURCE;
+					rule_ret = HTTP_RULE_RES_ERROR;
 					goto end;
 				}
 
@@ -3133,7 +3164,7 @@
 									 ist2(rule->arg.early_hint.name, rule->arg.early_hint.name_len),
 									 &rule->arg.early_hint.fmt);
 				if (early_hints == -1) {
-					rule_ret = HTTP_RULE_RES_BADREQ;
+					rule_ret = HTTP_RULE_RES_ERROR;
 					goto end;
 				}
 				break;
@@ -3146,7 +3177,7 @@
 
 				switch (rule->action_ptr(rule, px, s->sess, s, act_flags)) {
 					case ACT_RET_ERR:
-						rule_ret = HTTP_RULE_RES_BADREQ;
+						rule_ret = HTTP_RULE_RES_ERROR;
 						goto end;
 					case ACT_RET_CONT:
 						break;
@@ -3216,7 +3247,7 @@
   end:
 	if (early_hints) {
 		if (http_reply_103_early_hints(&s->res) == -1)
-			rule_ret = HTTP_RULE_RES_BADREQ;
+			rule_ret = HTTP_RULE_RES_ERROR;
 	}
 
 	/* we reached the end of the rules, nothing to report */
@@ -3282,8 +3313,7 @@
 				goto end;
 
 			case ACT_ACTION_DENY:
-				txn->flags |= TX_SVDENY;
-				rule_ret = HTTP_RULE_RES_STOP;
+				rule_ret = HTTP_RULE_RES_DENY;
 				goto end;
 
 			case ACT_HTTP_SET_NICE:
@@ -3308,7 +3338,7 @@
 							  ist2(rule->arg.hdr_add.name, rule->arg.hdr_add.name_len),
 							  &rule->arg.hdr_add.fmt,
 							  rule->arg.hdr_add.re, rule->action)) {
-					rule_ret = HTTP_RULE_RES_BADREQ;
+					rule_ret = HTTP_RULE_RES_ERROR;
 					goto end;
 				}
 				break;
@@ -3327,7 +3357,9 @@
 
 				replace = alloc_trash_chunk();
 				if (!replace) {
-					rule_ret = HTTP_RULE_RES_BADREQ;
+					if (!(s->flags & SF_ERR_MASK))
+						s->flags |= SF_ERR_RESOURCE;
+					rule_ret = HTTP_RULE_RES_ERROR;
 					goto end;
 				}
 
@@ -3374,7 +3406,9 @@
 			/* allocate key */
 				key = alloc_trash_chunk();
 				if (!key) {
-					rule_ret = HTTP_RULE_RES_BADREQ;
+					if (!(s->flags & SF_ERR_MASK))
+						s->flags |= SF_ERR_RESOURCE;
+					rule_ret = HTTP_RULE_RES_ERROR;
 					goto end;
 				}
 
@@ -3404,7 +3438,9 @@
 				/* allocate key */
 				key = alloc_trash_chunk();
 				if (!key) {
-					rule_ret = HTTP_RULE_RES_BADREQ;
+					if (!(s->flags & SF_ERR_MASK))
+						s->flags |= SF_ERR_RESOURCE;
+					rule_ret = HTTP_RULE_RES_ERROR;
 					goto end;
 				}
 
@@ -3434,7 +3470,9 @@
 				/* allocate key */
 				key = alloc_trash_chunk();
 				if (!key) {
-					rule_ret = HTTP_RULE_RES_BADREQ;
+					if (!(s->flags & SF_ERR_MASK))
+						s->flags |= SF_ERR_RESOURCE;
+					rule_ret = HTTP_RULE_RES_ERROR;
 					goto end;
 				}
 
@@ -3442,7 +3480,9 @@
 				value = alloc_trash_chunk();
 				if (!value) {
 					free_trash_chunk(key);
-					rule_ret = HTTP_RULE_RES_BADREQ;
+					if (!(s->flags & SF_ERR_MASK))
+						s->flags |= SF_ERR_RESOURCE;
+					rule_ret = HTTP_RULE_RES_ERROR;
 					goto end;
 				}
 
@@ -3471,7 +3511,7 @@
 			case ACT_HTTP_REDIR:
 				rule_ret = HTTP_RULE_RES_DONE;
 				if (!http_apply_redirect_rule(rule->arg.redir, s, txn))
-					rule_ret = HTTP_RULE_RES_BADREQ;
+					rule_ret = HTTP_RULE_RES_ERROR;
 				goto end;
 
 			case ACT_ACTION_TRK_SC0 ... ACT_ACTION_TRK_SCMAX:
@@ -3541,7 +3581,7 @@
 
 				switch (rule->action_ptr(rule, px, s->sess, s, act_flags)) {
 					case ACT_RET_ERR:
-						rule_ret = HTTP_RULE_RES_BADREQ;
+						rule_ret = HTTP_RULE_RES_ERROR;
 						goto end;
 					case ACT_RET_CONT:
 						break;