From 27ba2cfbdcdc3e12f37b7166e82043b9f77a9453 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Fri, 16 Dec 2011 15:38:49 +0100 Subject: MEDIUM: acl: use temp_pattern to store fetched information in the "method" match 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 | 34 +++++++++++++++++++++++++--------- 1 files changed, 25 insertions(+), 9 deletions(-) diff --git a/src/proto_http.c b/src/proto_http.c index 14dc24b..f45c514 100644 --- a/src/proto_http.c +++ b/src/proto_http.c @@ -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 and is NULL ; + * - if the method is unknown (HTTP_METH_OTHER), points to the text and + * 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; } -- 1.7.2.3