]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
[MEDIUM] http: make the request filter loop check for optional conditions
authorWilly Tarreau <w@1wt.eu>
Thu, 28 Jan 2010 19:22:06 +0000 (20:22 +0100)
committerWilly Tarreau <w@1wt.eu>
Thu, 28 Jan 2010 19:22:06 +0000 (20:22 +0100)
From now on, if request filters have ACLs defined, these ACLs will be
evaluated to condition the filter. This will be used to conditionally
remove/rewrite headers based on ACLs.

include/proto/proto_http.h
src/proto_http.c

index cfaf9859a3a55a968a8e8401606a43491c931938..6a424c0f06beb2673c6bdfa3fb301327da8473a7 100644 (file)
@@ -75,7 +75,7 @@ void debug_hdr(const char *dir, struct session *t, const char *start, const char
 void get_srv_from_appsession(struct session *t, const char *begin, int len);
 int apply_filter_to_req_headers(struct session *t, struct buffer *req, struct hdr_exp *exp);
 int apply_filter_to_req_line(struct session *t, struct buffer *req, struct hdr_exp *exp);
-int apply_filters_to_request(struct session *t, struct buffer *req, struct hdr_exp *exp);
+int apply_filters_to_request(struct session *s, struct buffer *req, struct proxy *px);
 int apply_filters_to_response(struct session *t, struct buffer *rtr, struct hdr_exp *exp);
 void manage_client_side_appsession(struct session *t, const char *buf, int len);
 void manage_client_side_cookies(struct session *t, struct buffer *req);
index 94022c8766bd051a214e67bde9e39328cb25f971..975963504b0d9579a0d5e2c8082cf310a618b613 100644 (file)
@@ -2764,7 +2764,7 @@ int http_process_req_common(struct session *s, struct buffer *req, int an_bit, s
 
        /* try headers filters */
        if (px->req_exp != NULL) {
-               if (apply_filters_to_request(s, req, px->req_exp) < 0)
+               if (apply_filters_to_request(s, req, px) < 0)
                        goto return_bad_req;
 
                /* has the request been denied ? */
@@ -5176,16 +5176,17 @@ int apply_filter_to_req_line(struct session *t, struct buffer *req, struct hdr_e
 
 
 /*
- * Apply all the req filters <exp> to all headers in buffer <req> of session <t>.
+ * Apply all the req filters of proxy <px> to all headers in buffer <req> of session <s>.
  * Returns 0 if everything is alright, or -1 in case a replacement lead to an
  * unparsable request. Since it can manage the switch to another backend, it
  * updates the per-proxy DENY stats.
  */
-int apply_filters_to_request(struct session *t, struct buffer *req, struct hdr_exp *exp)
+int apply_filters_to_request(struct session *s, struct buffer *req, struct proxy *px)
 {
-       struct http_txn *txn = &t->txn;
-       /* iterate through the filters in the outer loop */
-       while (exp && !(txn->flags & (TX_CLDENY|TX_CLTARPIT))) {
+       struct http_txn *txn = &s->txn;
+       struct hdr_exp *exp;
+
+       for (exp = px->req_exp; exp; exp = exp->next) {
                int ret;
 
                /*
@@ -5194,15 +5195,29 @@ int apply_filters_to_request(struct session *t, struct buffer *req, struct hdr_e
                 * the evaluation.
                 */
 
+               if (txn->flags & (TX_CLDENY|TX_CLTARPIT))
+                       break;
+
                if ((txn->flags & TX_CLALLOW) &&
                    (exp->action == ACT_ALLOW || exp->action == ACT_DENY ||
-                    exp->action == ACT_TARPIT || exp->action == ACT_PASS)) {
-                       exp = exp->next;
+                    exp->action == ACT_TARPIT || exp->action == ACT_PASS))
                        continue;
+
+               /* if this filter had a condition, evaluate it now and skip to
+                * next filter if the condition does not match.
+                */
+               if (exp->cond) {
+                       ret = acl_exec_cond(exp->cond, px, s, txn, ACL_DIR_REQ);
+                       ret = acl_pass(ret);
+                       if (((struct acl_cond *)exp->cond)->pol == ACL_COND_UNLESS)
+                               ret = !ret;
+
+                       if (!ret)
+                               continue;
                }
 
                /* Apply the filter to the request line. */
-               ret = apply_filter_to_req_line(t, req, exp);
+               ret = apply_filter_to_req_line(s, req, exp);
                if (unlikely(ret < 0))
                        return -1;
 
@@ -5210,9 +5225,8 @@ int apply_filters_to_request(struct session *t, struct buffer *req, struct hdr_e
                        /* The filter did not match the request, it can be
                         * iterated through all headers.
                         */
-                       apply_filter_to_req_headers(t, req, exp);
+                       apply_filter_to_req_headers(s, req, exp);
                }
-               exp = exp->next;
        }
        return 0;
 }