Use PCRE instead of Python's re for RedirectMatch tests
Previously, RedirectMatch rules were evaluated using Python's re regexp module. However, Apache httpd uses the PCRE library for evaluating regular expressions,[1] and there are subtle differences between the Python and PCRE implementations. Using the PCRE library itself (via the pcre-python binding) provides more representative results, and hence more confidence to the user that any rules that pass whereto's tests will work in the same way in a real Apache configuration. [1] https://httpd.apache.org/docs/trunk/glossary.html#regex Change-Id: Ibef3376d9da0688d0c97f5837dacc5b7cc52431c
This commit is contained in:
parent
006ffc075c
commit
797cb67a37
3
bindep.txt
Normal file
3
bindep.txt
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
libpcre3-dev [platform:dpkg]
|
||||||
|
pcre-devel [platform:rpm]
|
||||||
|
dev-libs/libpcre [platform:gentoo]
|
4
releasenotes/notes/pcre-9c6e76b391620545.yaml
Normal file
4
releasenotes/notes/pcre-9c6e76b391620545.yaml
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- whereto now uses the PCRE library - the same regex library used by
|
||||||
|
mod_alias - for compiling regular expressions.
|
@ -3,3 +3,4 @@
|
|||||||
# process, which may cause wedges in the gate later.
|
# process, which may cause wedges in the gate later.
|
||||||
|
|
||||||
pbr>=2.0 # Apache-2.0
|
pbr>=2.0 # Apache-2.0
|
||||||
|
python-pcre
|
||||||
|
4
tox.ini
4
tox.ini
@ -25,6 +25,10 @@ commands = flake8 {posargs}
|
|||||||
basepython = python3
|
basepython = python3
|
||||||
commands = {posargs}
|
commands = {posargs}
|
||||||
|
|
||||||
|
[testenv:bindep]
|
||||||
|
deps = bindep
|
||||||
|
commands = bindep test
|
||||||
|
|
||||||
[testenv:cover]
|
[testenv:cover]
|
||||||
commands = python setup.py test --coverage --testr-args='{posargs}'
|
commands = python setup.py test --coverage --testr-args='{posargs}'
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
import pcre
|
||||||
import re
|
import re
|
||||||
|
|
||||||
|
|
||||||
@ -74,14 +75,15 @@ class RedirectMatch(Rule):
|
|||||||
|
|
||||||
def __init__(self, linenum, *params):
|
def __init__(self, linenum, *params):
|
||||||
super(RedirectMatch, self).__init__(linenum, *params)
|
super(RedirectMatch, self).__init__(linenum, *params)
|
||||||
self.regex = re.compile(self.pattern)
|
self.regex = pcre.compile(self.pattern)
|
||||||
if self.target:
|
if self.target:
|
||||||
self.target_repl = self._get_target_repl()
|
self.target_repl = self._get_target_repl()
|
||||||
else:
|
else:
|
||||||
self.target_repl = None
|
self.target_repl = None
|
||||||
|
|
||||||
def _get_target_repl(self):
|
def _get_target_repl(self):
|
||||||
return self._group_subst.sub(r'\\1', self.target).replace(r'\$', '$')
|
escaped = pcre.escape_template(self.target)
|
||||||
|
return self._group_subst.sub(r'{\1}', escaped).replace(r'\$', '$')
|
||||||
|
|
||||||
def match(self, path):
|
def match(self, path):
|
||||||
m = self.regex.search(path)
|
m = self.regex.search(path)
|
||||||
|
@ -96,6 +96,15 @@ class TestRedirectMatch(base.TestCase):
|
|||||||
rule.match('/user/'),
|
rule.match('/user/'),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_match_pcre_syntax(self):
|
||||||
|
rule = rules.RedirectMatch(
|
||||||
|
1,
|
||||||
|
'redirectmatch', '301', '^/((?i)pike)/user/.*$', '/pike/user/',
|
||||||
|
)
|
||||||
|
self.assertIsNone(
|
||||||
|
rule.match('/Pike/USER/')
|
||||||
|
)
|
||||||
|
|
||||||
def test_match_with_group(self):
|
def test_match_with_group(self):
|
||||||
rule = rules.RedirectMatch(
|
rule = rules.RedirectMatch(
|
||||||
1,
|
1,
|
||||||
@ -106,6 +115,16 @@ class TestRedirectMatch(base.TestCase):
|
|||||||
rule.match('/user/foo'),
|
rule.match('/user/foo'),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_match_with_group_braces(self):
|
||||||
|
rule = rules.RedirectMatch(
|
||||||
|
1,
|
||||||
|
'redirectmatch', '301', '^/user/(.*)$', '/pike/user/{1}/$1',
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
('301', '/pike/user/{1}/foo'),
|
||||||
|
rule.match('/user/foo'),
|
||||||
|
)
|
||||||
|
|
||||||
def test_match_with_no_group_dollar(self):
|
def test_match_with_no_group_dollar(self):
|
||||||
rule = rules.RedirectMatch(
|
rule = rules.RedirectMatch(
|
||||||
1,
|
1,
|
||||||
|
Loading…
Reference in New Issue
Block a user