xref: /unit/test/test_return.py (revision 1441)
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