11434Szelenkov@nginx.comimport re 21434Szelenkov@nginx.comimport unittest 31434Szelenkov@nginx.comfrom unit.applications.proto import TestApplicationProto 41434Szelenkov@nginx.com 51434Szelenkov@nginx.com 61434Szelenkov@nginx.comclass TestReturn(TestApplicationProto): 71434Szelenkov@nginx.com prerequisites = {} 81434Szelenkov@nginx.com 91434Szelenkov@nginx.com def setUp(self): 101434Szelenkov@nginx.com super().setUp() 111434Szelenkov@nginx.com 121434Szelenkov@nginx.com self._load_conf( 131434Szelenkov@nginx.com { 141434Szelenkov@nginx.com "listeners": {"*:7080": {"pass": "routes"}}, 151434Szelenkov@nginx.com "routes": [{"action": {"return": 200}}], 161434Szelenkov@nginx.com "applications": {}, 171434Szelenkov@nginx.com } 181434Szelenkov@nginx.com ) 191434Szelenkov@nginx.com 201434Szelenkov@nginx.com def get_resps_sc(self, req=10): 211434Szelenkov@nginx.com to_send = b"""GET / HTTP/1.1 221434Szelenkov@nginx.comHost: localhost 231434Szelenkov@nginx.com 241434Szelenkov@nginx.com""" * ( 251434Szelenkov@nginx.com req - 1 261434Szelenkov@nginx.com ) 271434Szelenkov@nginx.com 281434Szelenkov@nginx.com to_send += b"""GET / HTTP/1.1 291434Szelenkov@nginx.comHost: localhost 301434Szelenkov@nginx.comConnection: close 311434Szelenkov@nginx.com 321434Szelenkov@nginx.com""" 331434Szelenkov@nginx.com 341434Szelenkov@nginx.com return self.http(to_send, raw_resp=True, raw=True) 351434Szelenkov@nginx.com 361434Szelenkov@nginx.com def test_return(self): 371434Szelenkov@nginx.com resp = self.get() 381434Szelenkov@nginx.com self.assertEqual(resp['status'], 200) 391434Szelenkov@nginx.com self.assertIn('Server', resp['headers']) 401434Szelenkov@nginx.com self.assertIn('Date', resp['headers']) 411434Szelenkov@nginx.com self.assertEqual(resp['headers']['Content-Length'], '0') 421434Szelenkov@nginx.com self.assertEqual(resp['headers']['Connection'], 'close') 431434Szelenkov@nginx.com self.assertEqual(resp['body'], '', 'body') 441434Szelenkov@nginx.com 451434Szelenkov@nginx.com resp = self.post(body='blah') 461434Szelenkov@nginx.com self.assertEqual(resp['status'], 200) 471434Szelenkov@nginx.com self.assertEqual(resp['body'], '', 'body') 481434Szelenkov@nginx.com 491434Szelenkov@nginx.com resp = self.get_resps_sc() 501434Szelenkov@nginx.com self.assertEqual(len(re.findall('200 OK', resp)), 10) 511434Szelenkov@nginx.com self.assertEqual(len(re.findall('Connection:', resp)), 1) 521434Szelenkov@nginx.com self.assertEqual(len(re.findall('Connection: close', resp)), 1) 531434Szelenkov@nginx.com 541434Szelenkov@nginx.com resp = self.get(http_10=True) 551434Szelenkov@nginx.com self.assertEqual(resp['status'], 200) 561434Szelenkov@nginx.com self.assertIn('Server', resp['headers']) 571434Szelenkov@nginx.com self.assertIn('Date', resp['headers']) 581434Szelenkov@nginx.com self.assertEqual(resp['headers']['Content-Length'], '0') 591434Szelenkov@nginx.com self.assertNotIn('Connection', resp['headers']) 601434Szelenkov@nginx.com self.assertEqual(resp['body'], '', 'body') 611434Szelenkov@nginx.com 621434Szelenkov@nginx.com def test_return_update(self): 631434Szelenkov@nginx.com self.assertIn('success', self.conf('0', 'routes/0/action/return')) 641434Szelenkov@nginx.com 651434Szelenkov@nginx.com resp = self.get() 661434Szelenkov@nginx.com self.assertEqual(resp['status'], 0) 671434Szelenkov@nginx.com self.assertEqual(resp['body'], '') 681434Szelenkov@nginx.com 691434Szelenkov@nginx.com self.assertIn('success', self.conf('404', 'routes/0/action/return')) 701434Szelenkov@nginx.com 711434Szelenkov@nginx.com resp = self.get() 721434Szelenkov@nginx.com self.assertEqual(resp['status'], 404) 731434Szelenkov@nginx.com self.assertNotEqual(resp['body'], '') 741434Szelenkov@nginx.com 751434Szelenkov@nginx.com self.assertIn('success', self.conf('598', 'routes/0/action/return')) 761434Szelenkov@nginx.com 771434Szelenkov@nginx.com resp = self.get() 781434Szelenkov@nginx.com self.assertEqual(resp['status'], 598) 791434Szelenkov@nginx.com self.assertNotEqual(resp['body'], '') 801434Szelenkov@nginx.com 811434Szelenkov@nginx.com self.assertIn('success', self.conf('999', 'routes/0/action/return')) 821434Szelenkov@nginx.com 831434Szelenkov@nginx.com resp = self.get() 841434Szelenkov@nginx.com self.assertEqual(resp['status'], 999) 851434Szelenkov@nginx.com self.assertEqual(resp['body'], '') 861434Szelenkov@nginx.com 871435Szelenkov@nginx.com def test_return_location(self): 881435Szelenkov@nginx.com reserved = ":/?#[]@!$&'()*+,;=" 891435Szelenkov@nginx.com unreserved = ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" 901435Szelenkov@nginx.com "0123456789-._~") 911435Szelenkov@nginx.com unsafe = " \"%<>\\^`{|}" 921435Szelenkov@nginx.com unsafe_enc = "%20%22%25%3C%3E%5C%5E%60%7B%7C%7D" 931435Szelenkov@nginx.com 941435Szelenkov@nginx.com def check_location(location, expect=None): 951435Szelenkov@nginx.com if expect is None: 961435Szelenkov@nginx.com expect = location 971435Szelenkov@nginx.com 981435Szelenkov@nginx.com self.assertIn( 991435Szelenkov@nginx.com 'success', 1001435Szelenkov@nginx.com self.conf( 1011435Szelenkov@nginx.com {"return": 301, "location": location}, 'routes/0/action' 1021435Szelenkov@nginx.com ), 1031435Szelenkov@nginx.com 'configure location' 1041435Szelenkov@nginx.com ) 1051435Szelenkov@nginx.com 1061435Szelenkov@nginx.com self.assertEqual(self.get()['headers']['Location'], expect) 1071435Szelenkov@nginx.com 1081435Szelenkov@nginx.com # FAIL: can't specify empty header value. 1091435Szelenkov@nginx.com # check_location("") 1101435Szelenkov@nginx.com 1111435Szelenkov@nginx.com check_location(reserved) 1121435Szelenkov@nginx.com 1131435Szelenkov@nginx.com # After first "?" all other "?" encoded. 1141435Szelenkov@nginx.com check_location("/?" + reserved, "/?:/%3F#[]@!$&'()*+,;=") 1151435Szelenkov@nginx.com check_location("???", "?%3F%3F") 1161435Szelenkov@nginx.com 1171435Szelenkov@nginx.com # After first "#" all other "?" or "#" encoded. 1181435Szelenkov@nginx.com check_location("/#" + reserved, "/#:/%3F%23[]@!$&'()*+,;=") 1191435Szelenkov@nginx.com check_location("##?#?", "#%23%3F%23%3F") 1201435Szelenkov@nginx.com 1211435Szelenkov@nginx.com # After first "?" next "#" not encoded. 1221435Szelenkov@nginx.com check_location("/?#" + reserved, "/?#:/%3F%23[]@!$&'()*+,;=") 1231435Szelenkov@nginx.com check_location("??##", "?%3F#%23") 1241435Szelenkov@nginx.com check_location("/?##?", "/?#%23%3F") 1251435Szelenkov@nginx.com 1261435Szelenkov@nginx.com # Unreserved never encoded. 1271435Szelenkov@nginx.com check_location(unreserved) 1281435Szelenkov@nginx.com check_location("/" + unreserved + "?" + unreserved + "#" + unreserved) 1291435Szelenkov@nginx.com 1301435Szelenkov@nginx.com # Unsafe always encoded. 1311435Szelenkov@nginx.com check_location(unsafe, unsafe_enc) 1321435Szelenkov@nginx.com check_location("?" + unsafe, "?" + unsafe_enc) 1331435Szelenkov@nginx.com check_location("#" + unsafe, "#" + unsafe_enc) 1341435Szelenkov@nginx.com 1351435Szelenkov@nginx.com # %00-%20 and %7F-%FF always encoded. 1361435Szelenkov@nginx.com check_location(u"\u0000\u0018\u001F\u0020\u0021", "%00%18%1F%20!") 1371435Szelenkov@nginx.com check_location(u"\u007F\u0080н\u20BD", "%7F%C2%80%D0%BD%E2%82%BD") 1381435Szelenkov@nginx.com 1391435Szelenkov@nginx.com # Encoded string detection. If at least one char need to be encoded 1401435Szelenkov@nginx.com # then whole string will be encoded. 1411435Szelenkov@nginx.com check_location("%20") 1421435Szelenkov@nginx.com check_location("/%20?%20#%20") 1431435Szelenkov@nginx.com check_location(" %20", "%20%2520") 1441435Szelenkov@nginx.com check_location("%20 ", "%2520%20") 1451435Szelenkov@nginx.com check_location("/%20?%20#%20 ", "/%2520?%2520#%2520%20") 1461435Szelenkov@nginx.com 1471435Szelenkov@nginx.com def test_return_location_edit(self): 1481435Szelenkov@nginx.com self.assertIn( 1491435Szelenkov@nginx.com 'success', 1501435Szelenkov@nginx.com self.conf( 1511435Szelenkov@nginx.com {"return": 302, "location": "blah"}, 'routes/0/action' 1521435Szelenkov@nginx.com ), 1531435Szelenkov@nginx.com 'configure init location' 1541435Szelenkov@nginx.com ) 1551435Szelenkov@nginx.com self.assertEqual(self.get()['headers']['Location'], 'blah') 1561435Szelenkov@nginx.com 1571435Szelenkov@nginx.com self.assertIn( 1581435Szelenkov@nginx.com 'success', 1591435Szelenkov@nginx.com self.conf_delete('routes/0/action/location'), 1601435Szelenkov@nginx.com 'location delete' 1611435Szelenkov@nginx.com ) 1621435Szelenkov@nginx.com self.assertNotIn('Location', self.get()['headers']) 1631435Szelenkov@nginx.com 1641435Szelenkov@nginx.com self.assertIn( 1651435Szelenkov@nginx.com 'success', 1661435Szelenkov@nginx.com self.conf('"blah"', 'routes/0/action/location'), 1671435Szelenkov@nginx.com 'location restore' 1681435Szelenkov@nginx.com ) 1691435Szelenkov@nginx.com self.assertEqual(self.get()['headers']['Location'], 'blah') 1701435Szelenkov@nginx.com 1711435Szelenkov@nginx.com self.assertIn( 1721435Szelenkov@nginx.com 'error', 1731435Szelenkov@nginx.com self.conf_post('"blah"', 'routes/0/action/location'), 1741435Szelenkov@nginx.com 'location method not allowed' 1751435Szelenkov@nginx.com ) 1761435Szelenkov@nginx.com self.assertEqual(self.get()['headers']['Location'], 'blah') 1771435Szelenkov@nginx.com 1781434Szelenkov@nginx.com def test_return_invalid(self): 1791434Szelenkov@nginx.com def check_error(conf): 1801434Szelenkov@nginx.com self.assertIn('error', self.conf(conf, 'routes/0/action')) 1811434Szelenkov@nginx.com 1821434Szelenkov@nginx.com check_error({"return": "200"}) 1831434Szelenkov@nginx.com check_error({"return": []}) 184*1441Szelenkov@nginx.com check_error({"return": 80.1}) 1851434Szelenkov@nginx.com check_error({"return": 1000}) 1861434Szelenkov@nginx.com check_error({"return": 200, "share": "/blah"}) 1871434Szelenkov@nginx.com 1881434Szelenkov@nginx.com self.assertIn( 1891434Szelenkov@nginx.com 'error', self.conf('001', 'routes/0/action/return'), 'leading zero' 1901434Szelenkov@nginx.com ) 1911434Szelenkov@nginx.com 1921435Szelenkov@nginx.com check_error({"return": 301, "location": 0}) 1931435Szelenkov@nginx.com check_error({"return": 301, "location": []}) 1941435Szelenkov@nginx.com 1951434Szelenkov@nginx.com 1961434Szelenkov@nginx.comif __name__ == '__main__': 1971434Szelenkov@nginx.com TestReturn.main() 198