]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: acl: use temp_pattern to store fetched information in the "method" match
authorWilly Tarreau <w@1wt.eu>
Fri, 16 Dec 2011 14:38:49 +0000 (15:38 +0100)
committerWilly Tarreau <w@1wt.eu>
Fri, 30 Dec 2011 16:33:25 +0000 (17:33 +0100)
This match was using both the int and ptr part of the acl_test struct. Let's
change this to be able to store it into a chunk with a special encoding.

src/proto_http.c

index 14dc24be06fce3d002a48308ea95ac2ea795957d..f45c514a0947c09cc88eadd60225c9b7f49c616f 100644 (file)
@@ -7770,6 +7770,14 @@ static int acl_parse_meth(const char **text, struct acl_pattern *pattern, int *o
        return 1;
 }
 
+/* This function fetches the method of current HTTP request and stores
+ * it in the global pattern struct as a chunk. There are two possibilities :
+ *   - if the method is known (not HTTP_METH_OTHER), its identifier is stored
+ *     in <len> and <ptr> is NULL ;
+ *   - if the method is unknown (HTTP_METH_OTHER), <ptr> points to the text and
+ *     <len> to its length.
+ * This is intended to be used with acl_match_meth() only.
+ */
 static int
 acl_fetch_meth(struct proxy *px, struct session *l4, void *l7, int dir,
                struct acl_expr *expr, struct acl_test *test)
@@ -7784,35 +7792,43 @@ acl_fetch_meth(struct proxy *px, struct session *l4, void *l7, int dir,
                return 0;
 
        meth = txn->meth;
-       test->i = meth;
+       temp_pattern.data.str.len = meth;
+       temp_pattern.data.str.str = NULL;
        if (meth == HTTP_METH_OTHER) {
                if (txn->rsp.msg_state != HTTP_MSG_RPBEFORE)
                        /* ensure the indexes are not affected */
                        return 0;
-               test->len = txn->req.sl.rq.m_l;
-               test->ptr = txn->req.sol;
+               temp_pattern.data.str.len = txn->req.sl.rq.m_l;
+               temp_pattern.data.str.str = txn->req.sol;
        }
        test->flags = ACL_TEST_F_READ_ONLY | ACL_TEST_F_VOL_1ST;
        return 1;
 }
 
+/* See above how the method is stored in the global pattern */
 static int acl_match_meth(struct acl_test *test, struct acl_pattern *pattern)
 {
        int icase;
 
-       if (test->i != pattern->val.i)
+
+       if (temp_pattern.data.str.str == NULL) {
+               /* well-known method */
+               if (temp_pattern.data.str.len == pattern->val.i)
+                       return ACL_PAT_PASS;
                return ACL_PAT_FAIL;
+       }
 
-       if (test->i != HTTP_METH_OTHER)
-               return ACL_PAT_PASS;
+       /* Uncommon method, only HTTP_METH_OTHER is accepted now */
+       if (pattern->val.i != HTTP_METH_OTHER)
+               return ACL_PAT_FAIL;
 
        /* Other method, we must compare the strings */
-       if (pattern->len != test->len)
+       if (pattern->len != temp_pattern.data.str.len)
                return ACL_PAT_FAIL;
 
        icase = pattern->flags & ACL_PAT_F_IGNORE_CASE;
-       if ((icase && strncasecmp(pattern->ptr.str, test->ptr, test->len) != 0) ||
-           (!icase && strncmp(pattern->ptr.str, test->ptr, test->len) != 0))
+       if ((icase && strncasecmp(pattern->ptr.str, temp_pattern.data.str.str, temp_pattern.data.str.len) != 0) ||
+           (!icase && strncmp(pattern->ptr.str, temp_pattern.data.str.str, temp_pattern.data.str.len) != 0))
                return ACL_PAT_FAIL;
        return ACL_PAT_PASS;
 }