import os import pytest from unit.applications.proto import TestApplicationProto from unit.option import option class TestRewrite(TestApplicationProto): prerequisites = {} @pytest.fixture(autouse=True) def setup_method_fixture(self): assert 'success' in self.conf( { "listeners": {"*:7080": {"pass": "routes"}}, "routes": [ { "match": {"uri": "/"}, "action": {"rewrite": "/new", "pass": "routes"}, }, {"match": {"uri": "/new"}, "action": {"return": 200}}, ], "applications": {}, "settings": {"http": {"log_route": True}}, }, ), 'set initial configuration' def set_rewrite(self, rewrite, uri): assert 'success' in self.conf( [ { "match": {"uri": "/"}, "action": {"rewrite": rewrite, "pass": "routes"}, }, {"match": {"uri": uri}, "action": {"return": 200}}, ], 'routes', ) def test_rewrite(self, findall, wait_for_record): assert self.get()['status'] == 200 assert wait_for_record(rf'\[notice\].*"routes/1" selected') is not None assert len(findall(rf'\[notice\].*URI rewritten to "/new"')) == 1 assert len(findall(rf'\[notice\].*URI rewritten')) == 1 self.set_rewrite("", "") assert self.get()['status'] == 200 def test_rewrite_variable(self): self.set_rewrite("/$host", "/localhost") assert self.get()['status'] == 200 self.set_rewrite("${uri}a", "/a") assert self.get()['status'] == 200 def test_rewrite_encoded(self): assert 'success' in self.conf( [ { "match": {"uri": "/f"}, "action": {"rewrite": "${request_uri}oo", "pass": "routes"}, }, {"match": {"uri": "/foo"}, "action": {"return": 200}}, ], 'routes', ) assert self.get(url='/%66')['status'] == 200 assert 'success' in self.conf( [ { "match": {"uri": "/f"}, "action": { "rewrite": "${request_uri}o%6F", "pass": "routes", }, }, {"match": {"uri": "/foo"}, "action": {"return": 200}}, ], 'routes', ) assert self.get(url='/%66')['status'] == 200 def test_rewrite_arguments(self): assert 'success' in self.conf( [ { "match": {"uri": "/foo", "arguments": {"arg": "val"}}, "action": {"rewrite": "/new?some", "pass": "routes"}, }, { "match": {"uri": "/new", "arguments": {"arg": "val"}}, "action": {"return": 200}, }, ], 'routes', ) assert self.get(url='/foo?arg=val')['status'] == 200 def test_rewrite_njs(self): if 'njs' not in option.available['modules'].keys(): pytest.skip('NJS is not available') self.set_rewrite("`/${host}`", "/localhost") assert self.get()['status'] == 200 def test_rewrite_location(self): def check_location(rewrite, expect): assert 'success' in self.conf( { "listeners": {"*:7080": {"pass": "routes"}}, "routes": [ { "action": { "return": 301, "location": "$uri", "rewrite": rewrite, } } ], } ) assert self.get()['headers']['Location'] == expect check_location('/new', '/new') check_location('${request_uri}new', '/new') def test_rewrite_share(self, temp_dir): os.makedirs(f'{temp_dir}/dir') os.makedirs(f'{temp_dir}/foo') with open(f'{temp_dir}/foo/index.html', 'w') as fooindex: fooindex.write('fooindex') # same action block assert 'success' in self.conf( { "listeners": {"*:7080": {"pass": "routes"}}, "routes": [ { "action": { "rewrite": "${request_uri}dir", "share": f'{temp_dir}$uri', } } ], } ) resp = self.get() assert resp['status'] == 301, 'redirect status' assert resp['headers']['Location'] == '/dir/', 'redirect Location' # request_uri index_path = f'{temp_dir}${{request_uri}}/index.html' assert 'success' in self.conf( { "listeners": {"*:7080": {"pass": "routes"}}, "routes": [ { "match": {"uri": "/foo"}, "action": { "rewrite": "${request_uri}dir", "pass": "routes", }, }, {"action": {"share": index_path}}, ], } ) assert self.get(url='/foo')['body'] == 'fooindex' # different action block assert 'success' in self.conf( { "listeners": {"*:7080": {"pass": "routes"}}, "routes": [ { "match": {"uri": "/foo"}, "action": { "rewrite": "${request_uri}dir", "pass": "routes", }, }, { "action": { "share": f'{temp_dir}/dir', } }, ], } ) resp = self.get(url='/foo') assert resp['status'] == 301, 'redirect status 2' assert resp['headers']['Location'] == '/foodir/', 'redirect Location 2' def test_rewrite_invalid(self, skip_alert): skip_alert(r'failed to apply new conf') def check_rewrite(rewrite): assert 'error' in self.conf( [ { "match": {"uri": "/"}, "action": {"rewrite": rewrite, "pass": "routes"}, }, {"action": {"return": 200}}, ], 'routes', ) check_rewrite("/$blah") check_rewrite(["/"])