[MINOR] ACL regex matching on the URI ; uri_reg
The URI can be matched on regexen now. The upcase/lowcase flag
can not be set yet and will soon have to.
diff --git a/include/proto/acl.h b/include/proto/acl.h
index 86cbe74..ace72dd 100644
--- a/include/proto/acl.h
+++ b/include/proto/acl.h
@@ -118,6 +118,9 @@
/* Parse a string. It is allocated and duplicated. */
int acl_parse_str(const char *text, struct acl_pattern *pattern);
+/* Parse a regex. It is allocated. */
+int acl_parse_reg(const char *text, struct acl_pattern *pattern);
+
/* Parse an IP address and an optional mask in the form addr[/mask].
* The addr may either be an IPv4 address or a hostname. The mask
* may either be a dotted mask or a number of bits. Returns 1 if OK,
@@ -149,6 +152,13 @@
/* Check that the IPv4 address in <test> matches the IP/mask in pattern */
int acl_match_ip(struct acl_test *test, struct acl_pattern *pattern);
+/* Executes a regex. It needs to change the data. If it is marked READ_ONLY
+ * then it will be allocated and duplicated in place so that others may use
+ * it later on. Note that this is embarrassing because we always try to avoid
+ * allocating memory at run time.
+ */
+int acl_match_reg(struct acl_test *test, struct acl_pattern *pattern);
+
#endif /* _PROTO_ACL_H */
/*
diff --git a/src/acl.c b/src/acl.c
index e5d7594..1dce3ea 100644
--- a/src/acl.c
+++ b/src/acl.c
@@ -47,6 +47,44 @@
return 0;
}
+/* Executes a regex. It needs to change the data. If it is marked READ_ONLY
+ * then it will be allocated and duplicated in place so that others may use
+ * it later on. Note that this is embarrassing because we always try to avoid
+ * allocating memory at run time.
+ */
+int acl_match_reg(struct acl_test *test, struct acl_pattern *pattern)
+{
+ char old_char;
+ int ret;
+
+ if (unlikely(test->flags & ACL_TEST_F_READ_ONLY)) {
+ char *new_str;
+
+ new_str = calloc(1, test->len + 1);
+ if (!new_str)
+ return 0;
+
+ memcpy(new_str, test->ptr, test->len);
+ new_str[test->len] = 0;
+ if (test->flags & ACL_TEST_F_MUST_FREE)
+ free(test->ptr);
+ test->ptr = new_str;
+ test->flags |= ACL_TEST_F_MUST_FREE;
+ test->flags &= ~ACL_TEST_F_READ_ONLY;
+ }
+
+ old_char = test->ptr[test->len];
+ test->ptr[test->len] = 0;
+
+ if (regexec(pattern->ptr.reg, test->ptr, 0, NULL, 0) == 0)
+ ret = 1;
+ else
+ ret = 0;
+
+ test->ptr[test->len] = old_char;
+ return ret;
+}
+
/* Checks that the pattern matches the beginning of the tested string. */
int acl_match_beg(struct acl_test *test, struct acl_pattern *pattern)
{
@@ -199,6 +237,25 @@
return 1;
}
+/* Parse a regex. It is allocated. */
+int acl_parse_reg(const char *text, struct acl_pattern *pattern)
+{
+ regex_t *preg;
+
+ preg = calloc(1, sizeof(regex_t));
+
+ if (!preg)
+ return 0;
+
+ if (regcomp(preg, text, REG_EXTENDED | REG_NOSUB) != 0) {
+ free(preg);
+ return 0;
+ }
+
+ pattern->ptr.reg = preg;
+ return 1;
+}
+
/* Parse an integer. It is put both in min and max. */
int acl_parse_int(const char *text, struct acl_pattern *pattern)
{
diff --git a/src/proto_http.c b/src/proto_http.c
index 6d4c152..9506b16 100644
--- a/src/proto_http.c
+++ b/src/proto_http.c
@@ -5276,7 +5276,8 @@
test->len = txn->req.sl.rq.u_l;
test->ptr = txn->req.sol + txn->req.sl.rq.u;
- test->flags = ACL_TEST_F_READ_ONLY | ACL_TEST_F_VOL_1ST;
+ /* we do not need to set READ_ONLY because the data is in a buffer */
+ test->flags = ACL_TEST_F_VOL_1ST;
return 1;
}
@@ -5299,10 +5300,11 @@
{ "url_sub", acl_parse_str, acl_fetch_url, acl_match_sub },
{ "url_dir", acl_parse_str, acl_fetch_url, acl_match_dir },
{ "url_dom", acl_parse_str, acl_fetch_url, acl_match_dom },
- { NULL, NULL, NULL, NULL },
-#if 0
{ "url_reg", acl_parse_reg, acl_fetch_url, acl_match_reg },
+ { NULL, NULL, NULL, NULL },
+
+#if 0
{ "line", acl_parse_str, acl_fetch_line, acl_match_str },
{ "line_reg", acl_parse_reg, acl_fetch_line, acl_match_reg },
{ "line_beg", acl_parse_str, acl_fetch_line, acl_match_beg },