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.
|
||||
|
||||
pbr>=2.0 # Apache-2.0
|
||||
python-pcre
|
||||
|
4
tox.ini
4
tox.ini
@ -25,6 +25,10 @@ commands = flake8 {posargs}
|
||||
basepython = python3
|
||||
commands = {posargs}
|
||||
|
||||
[testenv:bindep]
|
||||
deps = bindep
|
||||
commands = bindep test
|
||||
|
||||
[testenv:cover]
|
||||
commands = python setup.py test --coverage --testr-args='{posargs}'
|
||||
|
||||
|
@ -16,6 +16,7 @@
|
||||
# under the License.
|
||||
|
||||
import logging
|
||||
import pcre
|
||||
import re
|
||||
|
||||
|
||||
@ -74,14 +75,15 @@ class RedirectMatch(Rule):
|
||||
|
||||
def __init__(self, linenum, *params):
|
||||
super(RedirectMatch, self).__init__(linenum, *params)
|
||||
self.regex = re.compile(self.pattern)
|
||||
self.regex = pcre.compile(self.pattern)
|
||||
if self.target:
|
||||
self.target_repl = self._get_target_repl()
|
||||
else:
|
||||
self.target_repl = None
|
||||
|
||||
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):
|
||||
m = self.regex.search(path)
|
||||
|
@ -96,6 +96,15 @@ class TestRedirectMatch(base.TestCase):
|
||||
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):
|
||||
rule = rules.RedirectMatch(
|
||||
1,
|
||||
@ -106,6 +115,16 @@ class TestRedirectMatch(base.TestCase):
|
||||
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):
|
||||
rule = rules.RedirectMatch(
|
||||
1,
|
||||
|
Loading…
Reference in New Issue
Block a user