mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-05-05 09:18:10 +00:00
[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.
This commit is contained in:
parent
662b2d8d18
commit
f3d259868b
@ -118,6 +118,9 @@ int acl_parse_range(const char *text, struct acl_pattern *pattern);
|
|||||||
/* Parse a string. It is allocated and duplicated. */
|
/* Parse a string. It is allocated and duplicated. */
|
||||||
int acl_parse_str(const char *text, struct acl_pattern *pattern);
|
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].
|
/* 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
|
* 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,
|
* may either be a dotted mask or a number of bits. Returns 1 if OK,
|
||||||
@ -149,6 +152,13 @@ int acl_match_dom(struct acl_test *test, struct acl_pattern *pattern);
|
|||||||
/* Check that the IPv4 address in <test> matches the IP/mask in pattern */
|
/* 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);
|
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 */
|
#endif /* _PROTO_ACL_H */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
57
src/acl.c
57
src/acl.c
@ -47,6 +47,44 @@ int acl_match_str(struct acl_test *test, struct acl_pattern *pattern)
|
|||||||
return 0;
|
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. */
|
/* Checks that the pattern matches the beginning of the tested string. */
|
||||||
int acl_match_beg(struct acl_test *test, struct acl_pattern *pattern)
|
int acl_match_beg(struct acl_test *test, struct acl_pattern *pattern)
|
||||||
{
|
{
|
||||||
@ -199,6 +237,25 @@ int acl_parse_str(const char *text, struct acl_pattern *pattern)
|
|||||||
return 1;
|
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. */
|
/* Parse an integer. It is put both in min and max. */
|
||||||
int acl_parse_int(const char *text, struct acl_pattern *pattern)
|
int acl_parse_int(const char *text, struct acl_pattern *pattern)
|
||||||
{
|
{
|
||||||
|
@ -5276,7 +5276,8 @@ static int acl_fetch_url(struct proxy *px, struct session *l4, void *l7, void *a
|
|||||||
test->len = txn->req.sl.rq.u_l;
|
test->len = txn->req.sl.rq.u_l;
|
||||||
test->ptr = txn->req.sol + txn->req.sl.rq.u;
|
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;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5299,10 +5300,11 @@ static struct acl_kw_list acl_kws = {{ },{
|
|||||||
{ "url_sub", acl_parse_str, acl_fetch_url, acl_match_sub },
|
{ "url_sub", acl_parse_str, acl_fetch_url, acl_match_sub },
|
||||||
{ "url_dir", acl_parse_str, acl_fetch_url, acl_match_dir },
|
{ "url_dir", acl_parse_str, acl_fetch_url, acl_match_dir },
|
||||||
{ "url_dom", acl_parse_str, acl_fetch_url, acl_match_dom },
|
{ "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 },
|
{ "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", acl_parse_str, acl_fetch_line, acl_match_str },
|
||||||
{ "line_reg", acl_parse_reg, acl_fetch_line, acl_match_reg },
|
{ "line_reg", acl_parse_reg, acl_fetch_line, acl_match_reg },
|
||||||
{ "line_beg", acl_parse_str, acl_fetch_line, acl_match_beg },
|
{ "line_beg", acl_parse_str, acl_fetch_line, acl_match_beg },
|
||||||
|
Loading…
Reference in New Issue
Block a user