From: Willy Tarreau Date: Sun, 27 Sep 2015 21:34:39 +0000 (+0200) Subject: MEDIUM: action: add a new flag ACT_FLAG_FIRST X-Git-Tag: v1.6-dev6~35 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=acc980036fd6fe4106390eb9cd213f676110c4a4;p=thirdparty%2Fhaproxy.git MEDIUM: action: add a new flag ACT_FLAG_FIRST This flag is used by custom actions to know that they're called for the first time. The only case where it's not set is when they're resuming from a yield. It will be needed to let them know when they have to allocate some resources. --- diff --git a/include/types/action.h b/include/types/action.h index b1e19e7faf..ca0163fa6e 100644 --- a/include/types/action.h +++ b/include/types/action.h @@ -50,6 +50,7 @@ enum act_parse_ret { enum act_flag { ACT_FLAG_NONE = 0x00000000, /* no flag */ ACT_FLAG_FINAL = 0x00000001, /* last call, cannot yield */ + ACT_FLAG_FIRST = 0x00000002, /* first call for this action */ }; enum act_name { diff --git a/src/proto_http.c b/src/proto_http.c index e646f79001..41858bf765 100644 --- a/src/proto_http.c +++ b/src/proto_http.c @@ -3497,7 +3497,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; - int final; + int act_flags = 0; /* If "the current_rule_list" match the executed rule list, we are in * resume condition. If a resume is needed it is always in the action @@ -3528,6 +3528,7 @@ http_req_get_intercept_rule(struct proxy *px, struct list *rules, struct stream continue; } + act_flags |= ACT_FLAG_FIRST; resume_execution: switch (rule->action) { case ACT_ACTION_ALLOW: @@ -3710,11 +3711,10 @@ resume_execution: } case ACT_CUSTOM: - final = 0; - if (px->options & PR_O_ABRT_CLOSE) - final = (s->req.flags & (CF_SHUTR|CF_READ_NULL|CF_READ_ERROR)); + if ((px->options & PR_O_ABRT_CLOSE) && (s->req.flags & (CF_SHUTR|CF_READ_NULL|CF_READ_ERROR))) + act_flags |= ACT_FLAG_FINAL; - switch (rule->action_ptr(rule, px, s->sess, s, final)) { + switch (rule->action_ptr(rule, px, s->sess, s, act_flags)) { case ACT_RET_ERR: case ACT_RET_CONT: break; @@ -3809,7 +3809,7 @@ http_res_get_intercept_rule(struct proxy *px, struct list *rules, struct stream struct connection *cli_conn; struct act_rule *rule; struct hdr_ctx ctx; - int final; + int act_flags = 0; /* If "the current_rule_list" match the executed rule list, we are in * resume condition. If a resume is needed it is always in the action @@ -3840,6 +3840,7 @@ http_res_get_intercept_rule(struct proxy *px, struct list *rules, struct stream continue; } + act_flags |= ACT_FLAG_FIRST; resume_execution: switch (rule->action) { case ACT_ACTION_ALLOW: @@ -3997,11 +3998,10 @@ resume_execution: return HTTP_RULE_RES_DONE; case ACT_CUSTOM: - final = 0; - if (px->options & PR_O_ABRT_CLOSE) - final = (s->req.flags & (CF_SHUTR|CF_READ_NULL|CF_READ_ERROR)); + if ((px->options & PR_O_ABRT_CLOSE) && (s->req.flags & (CF_SHUTR|CF_READ_NULL|CF_READ_ERROR))) + act_flags |= ACT_FLAG_FINAL; - switch (rule->action_ptr(rule, px, s->sess, s, final)) { + switch (rule->action_ptr(rule, px, s->sess, s, act_flags)) { case ACT_RET_ERR: case ACT_RET_CONT: break; diff --git a/src/proto_tcp.c b/src/proto_tcp.c index 825f32085d..ea7586661c 100644 --- a/src/proto_tcp.c +++ b/src/proto_tcp.c @@ -1038,6 +1038,7 @@ int tcp_inspect_request(struct stream *s, struct channel *req, int an_bit) struct stksess *ts; struct stktable *t; int partial; + int act_flags = 0; DPRINTF(stderr,"[%u] %s: stream=%p b=%p, exp(r,w)=%u,%u bf=%08x bh=%d analysers=%02x\n", now_ms, __FUNCTION__, @@ -1091,6 +1092,7 @@ int tcp_inspect_request(struct stream *s, struct channel *req, int an_bit) } if (ret) { + act_flags |= ACT_FLAG_FIRST; resume_execution: /* we have a matching rule. */ if (rule->action == ACT_ACTION_ALLOW) { @@ -1166,7 +1168,10 @@ resume_execution: if (!rule->action_ptr) continue; - switch (rule->action_ptr(rule, s->be, s->sess, s, (partial & SMP_OPT_FINAL) ? ACT_FLAG_FINAL : 0)) { + if (partial & SMP_OPT_FINAL) + act_flags |= ACT_FLAG_FINAL; + + switch (rule->action_ptr(rule, s->be, s->sess, s, act_flags)) { case ACT_RET_ERR: case ACT_RET_CONT: continue; @@ -1208,6 +1213,7 @@ int tcp_inspect_response(struct stream *s, struct channel *rep, int an_bit) struct session *sess = s->sess; struct act_rule *rule; int partial; + int act_flags = 0; DPRINTF(stderr,"[%u] %s: stream=%p b=%p, exp(r,w)=%u,%u bf=%08x bh=%d analysers=%02x\n", now_ms, __FUNCTION__, @@ -1264,6 +1270,7 @@ int tcp_inspect_response(struct stream *s, struct channel *rep, int an_bit) } if (ret) { + act_flags |= ACT_FLAG_FIRST; resume_execution: /* we have a matching rule. */ if (rule->action == ACT_ACTION_ALLOW) { @@ -1295,7 +1302,11 @@ resume_execution: /* Custom keywords. */ if (!rule->action_ptr) continue; - switch (rule->action_ptr(rule, s->be, s->sess, s, (partial & SMP_OPT_FINAL) ? ACT_FLAG_FINAL : 0)) { + + if (partial & SMP_OPT_FINAL) + act_flags |= ACT_FLAG_FINAL; + + switch (rule->action_ptr(rule, s->be, s->sess, s, act_flags)) { case ACT_RET_ERR: case ACT_RET_CONT: continue; @@ -1383,7 +1394,7 @@ int tcp_exec_req_rules(struct session *sess) /* Custom keywords. */ if (rule->action_ptr) break; - switch (rule->action_ptr(rule, sess->fe, sess, NULL, ACT_FLAG_FINAL)) { + switch (rule->action_ptr(rule, sess->fe, sess, NULL, ACT_FLAG_FINAL | ACT_FLAG_FIRST)) { case ACT_RET_YIELD: /* yield is not allowed at this point. If this return code is * used it is a bug, so I prefer to abort the process.