xref: /unit/test/test_static_types.py (revision 1971:3410f9d2a662)
1from pathlib import Path
2
3import pytest
4from unit.applications.proto import TestApplicationProto
5
6
7class TestStaticTypes(TestApplicationProto):
8    prerequisites = {}
9
10    @pytest.fixture(autouse=True)
11    def setup_method_fixture(self, temp_dir):
12        Path(temp_dir + '/assets').mkdir()
13        for ext in ['.xml', '.mp4', '.php', '', '.txt', '.html', '.png']:
14            Path(temp_dir + '/assets/file' + ext).write_text(ext)
15
16        Path(temp_dir + '/assets/index.html').write_text('index')
17
18        self._load_conf(
19            {
20                "listeners": {
21                    "*:7080": {"pass": "routes"},
22                    "*:7081": {"pass": "routes"},
23                },
24                "routes": [{"action": {"share": temp_dir + "/assets$uri"}}],
25                "applications": {},
26            }
27        )
28
29    def action_update(self, conf):
30        assert 'success' in self.conf(conf, 'routes/0/action')
31
32    def check_body(self, http_url, body):
33        resp = self.get(url=http_url)
34        assert resp['status'] == 200, 'status'
35        assert resp['body'] == body, 'body'
36
37    def test_static_types_basic(self, temp_dir):
38        self.action_update({"share": temp_dir + "/assets$uri"})
39        self.check_body('/index.html', 'index')
40        self.check_body('/file.xml', '.xml')
41
42        self.action_update(
43            {"share": temp_dir + "/assets$uri", "types": "application/xml"}
44        )
45        self.check_body('/file.xml', '.xml')
46
47        self.action_update(
48            {"share": temp_dir + "/assets$uri", "types": ["application/xml"]}
49        )
50        self.check_body('/file.xml', '.xml')
51
52        self.action_update({"share": temp_dir + "/assets$uri", "types": [""]})
53        assert self.get(url='/file.xml')['status'] == 403, 'no mtype'
54
55    def test_static_types_wildcard(self, temp_dir):
56        self.action_update(
57            {"share": temp_dir + "/assets$uri", "types": ["application/*"]}
58        )
59        self.check_body('/file.xml', '.xml')
60        assert self.get(url='/file.mp4')['status'] == 403, 'app * mtype mp4'
61
62        self.action_update(
63            {"share": temp_dir + "/assets$uri", "types": ["video/*"]}
64        )
65        assert self.get(url='/file.xml')['status'] == 403, 'video * mtype xml'
66        self.check_body('/file.mp4', '.mp4')
67
68    def test_static_types_negation(self, temp_dir):
69        self.action_update(
70            {"share": temp_dir + "/assets$uri", "types": ["!application/xml"]}
71        )
72        assert self.get(url='/file.xml')['status'] == 403, 'forbidden negation'
73        self.check_body('/file.mp4', '.mp4')
74
75        # sorting negation
76        self.action_update(
77            {
78                "share": temp_dir + "/assets$uri",
79                "types": ["!video/*", "image/png", "!image/jpg"],
80            }
81        )
82        assert self.get(url='/file.mp4')['status'] == 403, 'negation sort mp4'
83        self.check_body('/file.png', '.png')
84        assert self.get(url='/file.jpg')['status'] == 403, 'negation sort jpg'
85
86    def test_static_types_regex(self, temp_dir):
87        self.action_update(
88            {"share": temp_dir + "/assets$uri", "types": ["~text/(html|plain)"]}
89        )
90        assert self.get(url='/file.php')['status'] == 403, 'regex fail'
91        self.check_body('/file.html', '.html')
92        self.check_body('/file.txt', '.txt')
93
94    def test_static_types_case(self, temp_dir):
95        self.action_update(
96            {"share": temp_dir + "/assets$uri", "types": ["!APpliCaTiOn/xMl"]}
97        )
98        self.check_body('/file.mp4', '.mp4')
99        assert (
100            self.get(url='/file.xml')['status'] == 403
101        ), 'mixed case xml negation'
102
103        self.action_update(
104            {"share": temp_dir + "/assets$uri", "types": ["vIdEo/mp4"]}
105        )
106        assert self.get(url='/file.mp4')['status'] == 200, 'mixed case'
107        assert (
108            self.get(url='/file.xml')['status'] == 403
109        ), 'mixed case video negation'
110
111        self.action_update(
112            {"share": temp_dir + "/assets$uri", "types": ["vIdEo/*"]}
113        )
114        self.check_body('/file.mp4', '.mp4')
115        assert (
116            self.get(url='/file.xml')['status'] == 403
117        ), 'mixed case video * negation'
118
119    def test_static_types_fallback(self, temp_dir):
120        assert 'success' in self.conf(
121            [
122                {
123                    "match": {"destination": "*:7081"},
124                    "action": {"return": 200},
125                },
126                {
127                    "action": {
128                        "share": temp_dir + "/assets$uri",
129                        "types": ["!application/x-httpd-php"],
130                        "fallback": {"proxy": "http://127.0.0.1:7081"},
131                    }
132                },
133            ],
134            'routes',
135        ), 'configure fallback proxy route'
136
137        self.check_body('/file.php', '')
138        self.check_body('/file.mp4', '.mp4')
139
140    def test_static_types_index(self, temp_dir):
141        self.action_update(
142            {"share": temp_dir + "/assets$uri", "types": "application/xml"}
143        )
144        self.check_body('/', 'index')
145        self.check_body('/file.xml', '.xml')
146        assert self.get(url='/index.html')['status'] == 403, 'forbidden mtype'
147        assert self.get(url='/file.mp4')['status'] == 403, 'forbidden mtype'
148
149    def test_static_types_custom_mime(self, temp_dir):
150        self._load_conf(
151            {
152                "listeners": {"*:7080": {"pass": "routes"}},
153                "routes": [{"action": {"share": temp_dir + "/assets$uri"}}],
154                "applications": {},
155                "settings": {
156                    "http": {
157                        "static": {"mime_types": {"test/mime-type": ["file"]}}
158                    }
159                },
160            }
161        )
162
163        self.action_update({"share": temp_dir + "/assets$uri", "types": [""]})
164        assert self.get(url='/file')['status'] == 403, 'forbidden custom mime'
165
166        self.action_update(
167            {"share": temp_dir + "/assets$uri", "types": ["test/mime-type"]}
168        )
169        self.check_body('/file', '')
170