diff --git a/src/proto_http.c b/src/proto_http.c index c5d35437f..ab63c55ef 100644 --- a/src/proto_http.c +++ b/src/proto_http.c @@ -1779,6 +1779,7 @@ http_req_get_intercept_rule(struct proxy *px, struct list *rules, struct stream struct act_rule *rule; struct hdr_ctx ctx; const char *auth_realm; + enum rule_result rule_ret = HTTP_RULE_RES_CONT; int act_flags = 0; int len; int early_hint = 0; @@ -1816,18 +1817,21 @@ http_req_get_intercept_rule(struct proxy *px, struct list *rules, struct stream resume_execution: switch (rule->action) { case ACT_ACTION_ALLOW: - return HTTP_RULE_RES_STOP; + rule_ret = HTTP_RULE_RES_STOP; + goto end; case ACT_ACTION_DENY: if (deny_status) *deny_status = rule->deny_status; - return HTTP_RULE_RES_DENY; + rule_ret = HTTP_RULE_RES_DENY; + goto end; case ACT_HTTP_REQ_TARPIT: txn->flags |= TX_CLTARPIT; if (deny_status) *deny_status = rule->deny_status; - return HTTP_RULE_RES_DENY; + rule_ret = HTTP_RULE_RES_DENY; + goto end; case ACT_HTTP_REQ_AUTH: /* Auth might be performed on regular http-req rules as well as on stats */ @@ -1846,12 +1850,14 @@ resume_execution: txn->status = (txn->flags & TX_USE_PX_CONN) ? 407 : 401; http_reply_and_close(s, txn->status, &trash); stream_inc_http_err_ctr(s); - return HTTP_RULE_RES_ABRT; + rule_ret = HTTP_RULE_RES_ABRT; + goto end; case ACT_HTTP_REDIR: + rule_ret = HTTP_RULE_RES_DONE; if (!http_apply_redirect_rule(rule->arg.redir, s, txn)) - return HTTP_RULE_RES_BADREQ; - return HTTP_RULE_RES_DONE; + rule_ret = HTTP_RULE_RES_BADREQ; + goto end; case ACT_HTTP_SET_NICE: s->task->nice = rule->arg.nice; @@ -1878,8 +1884,10 @@ resume_execution: if (http_transform_header(s, &txn->req, rule->arg.hdr_add.name, rule->arg.hdr_add.name_len, &rule->arg.hdr_add.fmt, - &rule->arg.hdr_add.re, rule->action)) - return HTTP_RULE_RES_BADREQ; + &rule->arg.hdr_add.re, rule->action)) { + rule_ret = HTTP_RULE_RES_BADREQ; + goto end; + } break; case ACT_HTTP_DEL_HDR: @@ -1902,8 +1910,10 @@ resume_execution: struct buffer *replace; replace = alloc_trash_chunk(); - if (!replace) - return HTTP_RULE_RES_BADREQ; + if (!replace) { + rule_ret = HTTP_RULE_RES_BADREQ; + goto end; + } len = rule->arg.hdr_add.name_len + 2, len += build_logline(s, replace->area + len, @@ -1956,8 +1966,10 @@ resume_execution: /* allocate key */ key = alloc_trash_chunk(); - if (!key) - return HTTP_RULE_RES_BADREQ; + if (!key) { + rule_ret = HTTP_RULE_RES_BADREQ; + goto end; + } /* collect key */ key->data = build_logline(s, key->area, key->size, @@ -1985,8 +1997,10 @@ resume_execution: /* allocate key */ key = alloc_trash_chunk(); - if (!key) - return HTTP_RULE_RES_BADREQ; + if (!key) { + rule_ret = HTTP_RULE_RES_BADREQ; + goto end; + } /* collect key */ key->data = build_logline(s, key->area, key->size, @@ -2015,14 +2029,17 @@ resume_execution: /* allocate key */ key = alloc_trash_chunk(); - if (!key) - return HTTP_RULE_RES_BADREQ; + if (!key) { + rule_ret = HTTP_RULE_RES_BADREQ; + goto end; + } /* allocate value */ value = alloc_trash_chunk(); if (!value) { free_trash_chunk(key); - return HTTP_RULE_RES_BADREQ; + rule_ret = HTTP_RULE_RES_BADREQ; + goto end; } /* collect key */ @@ -2056,8 +2073,10 @@ resume_execution: if (!http_apply_early_hint_rule(s, txn->rsp.chn, early_hint, rule->arg.early_hint.name, rule->arg.early_hint.name_len, - &rule->arg.early_hint.fmt)) - return HTTP_RULE_RES_DONE; + &rule->arg.early_hint.fmt)) { + rule_ret = HTTP_RULE_RES_DONE; + goto end; + } early_hint = 1; break; case ACT_CUSTOM: @@ -2072,10 +2091,12 @@ resume_execution: case ACT_RET_CONT: break; case ACT_RET_STOP: - return HTTP_RULE_RES_DONE; + rule_ret = HTTP_RULE_RES_DONE; + goto end; case ACT_RET_YIELD: s->current_rule = rule; - return HTTP_RULE_RES_YIELD; + rule_ret = HTTP_RULE_RES_YIELD; + goto end; } break; @@ -2128,6 +2149,7 @@ resume_execution: } } + end: if (early_hint) { struct channel *chn = s->txn->rsp.chn; char *cur_ptr = ci_head(chn); @@ -2138,7 +2160,7 @@ resume_execution: } /* we reached the end of the rules, nothing to report */ - return HTTP_RULE_RES_CONT; + return rule_ret; }