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