]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: action: add a new flag ACT_FLAG_FIRST
authorWilly Tarreau <w@1wt.eu>
Sun, 27 Sep 2015 21:34:39 +0000 (23:34 +0200)
committerWilly Tarreau <w@1wt.eu>
Sun, 27 Sep 2015 21:34:39 +0000 (23:34 +0200)
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.

include/types/action.h
src/proto_http.c
src/proto_tcp.c

index b1e19e7fafccf98397b4e916dce0d83fb465d54d..ca0163fa6e76136f5b4ae373a46a6889851bedb8 100644 (file)
@@ -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 {
index e646f790019019f0e9e17750885055af2479129d..41858bf765385ce4968d1c3d2982052ccd436e2f 100644 (file)
@@ -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;
index 825f32085d938f3869e834ee6d1adb779e65873a..ea7586661ca4a7af34d479637019a31487f62e81 100644 (file)
@@ -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.