xref: /unit/test/test_return.py (revision 2099:110766ffd5d9)
11434Szelenkov@nginx.comimport re
21477Szelenkov@nginx.com
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
91596Szelenkov@nginx.com    def setup_method(self):
101434Szelenkov@nginx.com        self._load_conf(
111434Szelenkov@nginx.com            {
121434Szelenkov@nginx.com                "listeners": {"*:7080": {"pass": "routes"}},
131434Szelenkov@nginx.com                "routes": [{"action": {"return": 200}}],
141434Szelenkov@nginx.com                "applications": {},
151434Szelenkov@nginx.com            }
161434Szelenkov@nginx.com        )
171434Szelenkov@nginx.com
181434Szelenkov@nginx.com    def get_resps_sc(self, req=10):
191434Szelenkov@nginx.com        to_send = b"""GET / HTTP/1.1
201434Szelenkov@nginx.comHost: localhost
211434Szelenkov@nginx.com
221434Szelenkov@nginx.com""" * (
231434Szelenkov@nginx.com            req - 1
241434Szelenkov@nginx.com        )
251434Szelenkov@nginx.com
261434Szelenkov@nginx.com        to_send += b"""GET / HTTP/1.1
271434Szelenkov@nginx.comHost: localhost
281434Szelenkov@nginx.comConnection: close
291434Szelenkov@nginx.com
301434Szelenkov@nginx.com"""
311434Szelenkov@nginx.com
321434Szelenkov@nginx.com        return self.http(to_send, raw_resp=True, raw=True)
331434Szelenkov@nginx.com
341434Szelenkov@nginx.com    def test_return(self):
351434Szelenkov@nginx.com        resp = self.get()
361596Szelenkov@nginx.com        assert resp['status'] == 200
371596Szelenkov@nginx.com        assert 'Server' in resp['headers']
381596Szelenkov@nginx.com        assert 'Date' in resp['headers']
391596Szelenkov@nginx.com        assert resp['headers']['Content-Length'] == '0'
401596Szelenkov@nginx.com        assert resp['headers']['Connection'] == 'close'
411596Szelenkov@nginx.com        assert resp['body'] == '', 'body'
421434Szelenkov@nginx.com
431434Szelenkov@nginx.com        resp = self.post(body='blah')
441596Szelenkov@nginx.com        assert resp['status'] == 200
451596Szelenkov@nginx.com        assert resp['body'] == '', 'body'
461434Szelenkov@nginx.com
471434Szelenkov@nginx.com        resp = self.get_resps_sc()
481596Szelenkov@nginx.com        assert len(re.findall('200 OK', resp)) == 10
491596Szelenkov@nginx.com        assert len(re.findall('Connection:', resp)) == 1
501596Szelenkov@nginx.com        assert len(re.findall('Connection: close', resp)) == 1
511434Szelenkov@nginx.com
521434Szelenkov@nginx.com        resp = self.get(http_10=True)
531596Szelenkov@nginx.com        assert resp['status'] == 200
541596Szelenkov@nginx.com        assert 'Server' in resp['headers']
551596Szelenkov@nginx.com        assert 'Date' in resp['headers']
561596Szelenkov@nginx.com        assert resp['headers']['Content-Length'] == '0'
571596Szelenkov@nginx.com        assert 'Connection' not in resp['headers']
581596Szelenkov@nginx.com        assert resp['body'] == '', 'body'
591434Szelenkov@nginx.com
601434Szelenkov@nginx.com    def test_return_update(self):
611596Szelenkov@nginx.com        assert 'success' in self.conf('0', 'routes/0/action/return')
621434Szelenkov@nginx.com
631434Szelenkov@nginx.com        resp = self.get()
641596Szelenkov@nginx.com        assert resp['status'] == 0
651596Szelenkov@nginx.com        assert resp['body'] == ''
661434Szelenkov@nginx.com
671596Szelenkov@nginx.com        assert 'success' in self.conf('404', 'routes/0/action/return')
681434Szelenkov@nginx.com
691434Szelenkov@nginx.com        resp = self.get()
701596Szelenkov@nginx.com        assert resp['status'] == 404
711596Szelenkov@nginx.com        assert resp['body'] != ''
721434Szelenkov@nginx.com
731596Szelenkov@nginx.com        assert 'success' in self.conf('598', 'routes/0/action/return')
741434Szelenkov@nginx.com
751434Szelenkov@nginx.com        resp = self.get()
761596Szelenkov@nginx.com        assert resp['status'] == 598
771596Szelenkov@nginx.com        assert resp['body'] != ''
781434Szelenkov@nginx.com
791596Szelenkov@nginx.com        assert 'success' in self.conf('999', 'routes/0/action/return')
801434Szelenkov@nginx.com
811434Szelenkov@nginx.com        resp = self.get()
821596Szelenkov@nginx.com        assert resp['status'] == 999
831596Szelenkov@nginx.com        assert resp['body'] == ''
841434Szelenkov@nginx.com
851435Szelenkov@nginx.com    def test_return_location(self):
862082Salx.manpages@gmail.com        reserved = ":/?#[]@!&'()*+,;="
871596Szelenkov@nginx.com        unreserved = (
881596Szelenkov@nginx.com            "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
891596Szelenkov@nginx.com            "0123456789-._~"
901596Szelenkov@nginx.com        )
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
981596Szelenkov@nginx.com            assert 'success' in self.conf(
991596Szelenkov@nginx.com                {"return": 301, "location": location}, 'routes/0/action'
1001596Szelenkov@nginx.com            ), 'configure location'
1011435Szelenkov@nginx.com
1021596Szelenkov@nginx.com            assert self.get()['headers']['Location'] == expect
1031435Szelenkov@nginx.com
1041435Szelenkov@nginx.com        # FAIL: can't specify empty header value.
1051435Szelenkov@nginx.com        # check_location("")
1061435Szelenkov@nginx.com
1071435Szelenkov@nginx.com        check_location(reserved)
1081435Szelenkov@nginx.com
1091435Szelenkov@nginx.com        # After first "?" all other "?" encoded.
1102082Salx.manpages@gmail.com        check_location("/?" + reserved, "/?:/%3F#[]@!&'()*+,;=")
1111435Szelenkov@nginx.com        check_location("???", "?%3F%3F")
1121435Szelenkov@nginx.com
1131435Szelenkov@nginx.com        # After first "#" all other "?" or "#" encoded.
1142082Salx.manpages@gmail.com        check_location("/#" + reserved, "/#:/%3F%23[]@!&'()*+,;=")
1151435Szelenkov@nginx.com        check_location("##?#?", "#%23%3F%23%3F")
1161435Szelenkov@nginx.com
1171435Szelenkov@nginx.com        # After first "?" next "#" not encoded.
1182082Salx.manpages@gmail.com        check_location("/?#" + reserved, "/?#:/%3F%23[]@!&'()*+,;=")
1191435Szelenkov@nginx.com        check_location("??##", "?%3F#%23")
1201435Szelenkov@nginx.com        check_location("/?##?", "/?#%23%3F")
1211435Szelenkov@nginx.com
1221435Szelenkov@nginx.com        # Unreserved never encoded.
1231435Szelenkov@nginx.com        check_location(unreserved)
1241435Szelenkov@nginx.com        check_location("/" + unreserved + "?" + unreserved + "#" + unreserved)
1251435Szelenkov@nginx.com
1261435Szelenkov@nginx.com        # Unsafe always encoded.
1271435Szelenkov@nginx.com        check_location(unsafe, unsafe_enc)
1281435Szelenkov@nginx.com        check_location("?" + unsafe, "?" + unsafe_enc)
1291435Szelenkov@nginx.com        check_location("#" + unsafe, "#" + unsafe_enc)
1301435Szelenkov@nginx.com
1311435Szelenkov@nginx.com        # %00-%20 and %7F-%FF always encoded.
1321435Szelenkov@nginx.com        check_location(u"\u0000\u0018\u001F\u0020\u0021", "%00%18%1F%20!")
1331435Szelenkov@nginx.com        check_location(u"\u007F\u0080н\u20BD", "%7F%C2%80%D0%BD%E2%82%BD")
1341435Szelenkov@nginx.com
1351435Szelenkov@nginx.com        # Encoded string detection.  If at least one char need to be encoded
1361435Szelenkov@nginx.com        # then whole string will be encoded.
1371435Szelenkov@nginx.com        check_location("%20")
1381435Szelenkov@nginx.com        check_location("/%20?%20#%20")
1391435Szelenkov@nginx.com        check_location(" %20", "%20%2520")
1401435Szelenkov@nginx.com        check_location("%20 ", "%2520%20")
1411435Szelenkov@nginx.com        check_location("/%20?%20#%20 ", "/%2520?%2520#%2520%20")
1421435Szelenkov@nginx.com
1431435Szelenkov@nginx.com    def test_return_location_edit(self):
1441596Szelenkov@nginx.com        assert 'success' in self.conf(
1451596Szelenkov@nginx.com            {"return": 302, "location": "blah"}, 'routes/0/action'
1461596Szelenkov@nginx.com        ), 'configure init location'
1471596Szelenkov@nginx.com        assert self.get()['headers']['Location'] == 'blah'
1481596Szelenkov@nginx.com
1491596Szelenkov@nginx.com        assert 'success' in self.conf_delete(
1501596Szelenkov@nginx.com            'routes/0/action/location'
1511596Szelenkov@nginx.com        ), 'location delete'
1521596Szelenkov@nginx.com        assert 'Location' not in self.get()['headers']
1531435Szelenkov@nginx.com
1541596Szelenkov@nginx.com        assert 'success' in self.conf(
1551596Szelenkov@nginx.com            '"blah"', 'routes/0/action/location'
1561596Szelenkov@nginx.com        ), 'location restore'
1571596Szelenkov@nginx.com        assert self.get()['headers']['Location'] == 'blah'
1581435Szelenkov@nginx.com
1591596Szelenkov@nginx.com        assert 'error' in self.conf_post(
1601596Szelenkov@nginx.com            '"blah"', 'routes/0/action/location'
1611596Szelenkov@nginx.com        ), 'location method not allowed'
1621596Szelenkov@nginx.com        assert self.get()['headers']['Location'] == 'blah'
1631435Szelenkov@nginx.com
1642083Salx.manpages@gmail.com        assert 'success' in self.conf(
1652083Salx.manpages@gmail.com            '"https://${host}${uri}"', 'routes/0/action/location'
1662083Salx.manpages@gmail.com        ), 'location with variables'
1672083Salx.manpages@gmail.com        assert self.get()['headers']['Location'] == 'https://localhost/'
1682083Salx.manpages@gmail.com
1692083Salx.manpages@gmail.com        assert 'success' in self.conf(
1702083Salx.manpages@gmail.com            '"/#$host"', 'routes/0/action/location'
1712083Salx.manpages@gmail.com        ), 'location with encoding and a variable'
1722083Salx.manpages@gmail.com        assert self.get()['headers']['Location'] == '/#localhost'
1732083Salx.manpages@gmail.com
1742083Salx.manpages@gmail.com        assert (
1752083Salx.manpages@gmail.com            self.get(headers={"Host": "#foo?bar", "Connection": "close"})[
1762083Salx.manpages@gmail.com                'headers'
1772083Salx.manpages@gmail.com            ]['Location']
1782083Salx.manpages@gmail.com            == "/#%23foo%3Fbar"
1792083Salx.manpages@gmail.com        ), 'location with a variable with encoding'
1802083Salx.manpages@gmail.com
181*2099Salx.manpages@gmail.com        assert 'success' in self.conf(
182*2099Salx.manpages@gmail.com            '""', 'routes/0/action/location'
183*2099Salx.manpages@gmail.com        ), 'location empty'
184*2099Salx.manpages@gmail.com        assert self.get()['headers']['Location'] == ''
185*2099Salx.manpages@gmail.com
186*2099Salx.manpages@gmail.com        assert 'success' in self.conf(
187*2099Salx.manpages@gmail.com            '"${host}"', 'routes/0/action/location'
188*2099Salx.manpages@gmail.com        ), 'location empty with variable'
189*2099Salx.manpages@gmail.com        assert (
190*2099Salx.manpages@gmail.com            self.get(headers={"Host": "", "Connection": "close"})['headers'][
191*2099Salx.manpages@gmail.com                'Location'
192*2099Salx.manpages@gmail.com            ]
193*2099Salx.manpages@gmail.com            == ""
194*2099Salx.manpages@gmail.com        ), 'location with empty variable'
195*2099Salx.manpages@gmail.com
1961434Szelenkov@nginx.com    def test_return_invalid(self):
1971434Szelenkov@nginx.com        def check_error(conf):
1981596Szelenkov@nginx.com            assert 'error' in self.conf(conf, 'routes/0/action')
1991434Szelenkov@nginx.com
2001434Szelenkov@nginx.com        check_error({"return": "200"})
2011434Szelenkov@nginx.com        check_error({"return": []})
2021441Szelenkov@nginx.com        check_error({"return": 80.1})
2031434Szelenkov@nginx.com        check_error({"return": 1000})
2041443Szelenkov@nginx.com        check_error({"return": -1})
2051434Szelenkov@nginx.com        check_error({"return": 200, "share": "/blah"})
2062083Salx.manpages@gmail.com        check_error({"return": 200, "location": "$hos"})
2072083Salx.manpages@gmail.com        check_error({"return": 200, "location": "$hostblah"})
2081434Szelenkov@nginx.com
2091596Szelenkov@nginx.com        assert 'error' in self.conf(
2101596Szelenkov@nginx.com            '001', 'routes/0/action/return'
2111596Szelenkov@nginx.com        ), 'leading zero'
2121434Szelenkov@nginx.com
2131435Szelenkov@nginx.com        check_error({"return": 301, "location": 0})
2141435Szelenkov@nginx.com        check_error({"return": 301, "location": []})
215