add support for redirectmatch rules

Signed-off-by: Doug Hellmann <doug@doughellmann.com>
This commit is contained in:
Doug Hellmann 2017-08-23 12:50:51 -04:00
parent 38119d0f05
commit 8b1ece685b
2 changed files with 83 additions and 0 deletions

View File

@ -15,6 +15,8 @@
# License for the specific language governing permissions and limitations
# under the License.
import re
class Rule(object):
"Base class for rules."
@ -53,3 +55,18 @@ class Redirect(Rule):
if path == self.pattern:
return (self.code, self.target)
return None
class RedirectMatch(Rule):
"A RedirectMatch rule with a regular expression."
def __init__(self, linenum, *params):
super(RedirectMatch, self).__init__(linenum, *params)
self.regex = re.compile(self.pattern)
self.target_repl = self.target.replace('$', '\\')
def match(self, path):
m = self.regex.search(path)
if m:
return (self.code, self.regex.sub(self.target_repl, path))
return None

View File

@ -65,4 +65,70 @@ class TestRedirect(base.TestCase):
rules.Redirect,
(1, 'redirect', '301', '/the/path', '/new/path', 'extra-value'),
)
class TestRedirectMatch(base.TestCase):
def test_match(self):
rule = rules.RedirectMatch(
1,
'redirectmatch', '301', '^/user/.*$', '/pike/user/',
)
self.assertEqual(
('301', '/pike/user/'),
rule.match('/user/'),
)
def test_match_with_group(self):
rule = rules.RedirectMatch(
1,
'redirectmatch', '301', '^/user/(.*)$', '/pike/user/$1',
)
self.assertEqual(
('301', '/pike/user/foo'),
rule.match('/user/foo'),
)
def test_no_match(self):
rule = rules.RedirectMatch(
1,
'redirectmatch', '301', '^/user/.*$', '/pike/user/',
)
self.assertIsNone(
rule.match('/different/path'),
)
def test_implied_code(self):
rule = rules.RedirectMatch(
1,
'redirectmatch', '^/user/.*$', '/pike/user/',
)
self.assertEqual(
'301',
rule.code,
)
def test_str(self):
rule = rules.RedirectMatch(
1,
'redirectmatch', '301', '^/user/.*$', '/pike/user/',
)
self.assertEqual(
'[1] redirectmatch 301 ^/user/.*$ /pike/user/',
str(rule),
)
def test_too_few_args(self):
self.assertRaises(
ValueError,
rules.RedirectMatch,
(1, 'redirectmatch', '/the/path'),
)
def test_too_many_args(self):
self.assertRaises(
ValueError,
rules.RedirectMatch,
(1, 'redirectmatch', '301', '/the/path', '/new/path',
'extra-value'),
)