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