11367Szelenkov@nginx.comimport os
21529Szelenkov@nginx.comimport re
31367Szelenkov@nginx.comimport shutil
41850Smax.romanov@nginx.comimport signal
51529Szelenkov@nginx.comimport time
61477Szelenkov@nginx.com
71635Szelenkov@nginx.comimport pytest
81848Szelenkov@nginx.com
91019Szelenkov@nginx.comfrom unit.applications.lang.php import TestApplicationPHP
101730Szelenkov@nginx.comfrom unit.option import option
11675Szelenkov@nginx.com
121848Szelenkov@nginx.com
131019Szelenkov@nginx.comclass TestPHPApplication(TestApplicationPHP):
141467Szelenkov@nginx.com    prerequisites = {'modules': {'php': 'all'}}
15675Szelenkov@nginx.com
16982Szelenkov@nginx.com    def before_disable_functions(self):
17982Szelenkov@nginx.com        body = self.get()['body']
18982Szelenkov@nginx.com
191596Szelenkov@nginx.com        assert re.search(r'time: \d+', body), 'disable_functions before time'
201596Szelenkov@nginx.com        assert re.search(r'exec: \/\w+', body), 'disable_functions before exec'
21865Szelenkov@nginx.com
221381St.nateldemoura@f5.com    def set_opcache(self, app, val):
231596Szelenkov@nginx.com        assert 'success' in self.conf(
241770Szelenkov@nginx.com            {"admin": {"opcache.enable": val, "opcache.enable_cli": val}},
251596Szelenkov@nginx.com            'applications/' + app + '/options',
261381St.nateldemoura@f5.com        )
271381St.nateldemoura@f5.com
281381St.nateldemoura@f5.com        opcache = self.get()['headers']['X-OPcache']
291381St.nateldemoura@f5.com
301381St.nateldemoura@f5.com        if not opcache or opcache == '-1':
311596Szelenkov@nginx.com            pytest.skip('opcache is not supported')
321381St.nateldemoura@f5.com
331596Szelenkov@nginx.com        assert opcache == val, 'opcache value'
341381St.nateldemoura@f5.com
35675Szelenkov@nginx.com    def test_php_application_variables(self):
36675Szelenkov@nginx.com        self.load('variables')
37675Szelenkov@nginx.com
38675Szelenkov@nginx.com        body = 'Test body string.'
39675Szelenkov@nginx.com
401017Szelenkov@nginx.com        resp = self.post(
411017Szelenkov@nginx.com            headers={
421017Szelenkov@nginx.com                'Host': 'localhost',
431017Szelenkov@nginx.com                'Content-Type': 'text/html',
441017Szelenkov@nginx.com                'Custom-Header': 'blah',
451017Szelenkov@nginx.com                'Connection': 'close',
461017Szelenkov@nginx.com            },
471017Szelenkov@nginx.com            body=body,
481596Szelenkov@nginx.com            url='/index.php/blah?var=val',
491017Szelenkov@nginx.com        )
50675Szelenkov@nginx.com
511596Szelenkov@nginx.com        assert resp['status'] == 200, 'status'
52675Szelenkov@nginx.com        headers = resp['headers']
53675Szelenkov@nginx.com        header_server = headers.pop('Server')
541596Szelenkov@nginx.com        assert re.search(r'Unit/[\d\.]+', header_server), 'server header'
551596Szelenkov@nginx.com        assert (
561596Szelenkov@nginx.com            headers.pop('Server-Software') == header_server
571596Szelenkov@nginx.com        ), 'server software header'
58675Szelenkov@nginx.com
59675Szelenkov@nginx.com        date = headers.pop('Date')
601596Szelenkov@nginx.com        assert date[-4:] == ' GMT', 'date header timezone'
611596Szelenkov@nginx.com        assert (
621596Szelenkov@nginx.com            abs(self.date_to_sec_epoch(date) - self.sec_epoch()) < 5
631596Szelenkov@nginx.com        ), 'date header'
64675Szelenkov@nginx.com
65675Szelenkov@nginx.com        if 'X-Powered-By' in headers:
66675Szelenkov@nginx.com            headers.pop('X-Powered-By')
67675Szelenkov@nginx.com
68675Szelenkov@nginx.com        headers.pop('Content-type')
691596Szelenkov@nginx.com        assert headers == {
701596Szelenkov@nginx.com            'Connection': 'close',
711596Szelenkov@nginx.com            'Content-Length': str(len(body)),
721596Szelenkov@nginx.com            'Request-Method': 'POST',
731596Szelenkov@nginx.com            'Path-Info': '/blah',
741596Szelenkov@nginx.com            'Request-Uri': '/index.php/blah?var=val',
751596Szelenkov@nginx.com            'Http-Host': 'localhost',
761596Szelenkov@nginx.com            'Server-Protocol': 'HTTP/1.1',
771596Szelenkov@nginx.com            'Custom-Header': 'blah',
781596Szelenkov@nginx.com        }, 'headers'
791596Szelenkov@nginx.com        assert resp['body'] == body, 'body'
80675Szelenkov@nginx.com
81894Szelenkov@nginx.com    def test_php_application_query_string(self):
82894Szelenkov@nginx.com        self.load('query_string')
83894Szelenkov@nginx.com
84894Szelenkov@nginx.com        resp = self.get(url='/?var1=val1&var2=val2')
85894Szelenkov@nginx.com
861596Szelenkov@nginx.com        assert (
871596Szelenkov@nginx.com            resp['headers']['Query-String'] == 'var1=val1&var2=val2'
881596Szelenkov@nginx.com        ), 'query string'
89894Szelenkov@nginx.com
90894Szelenkov@nginx.com    def test_php_application_query_string_empty(self):
91894Szelenkov@nginx.com        self.load('query_string')
92894Szelenkov@nginx.com
93894Szelenkov@nginx.com        resp = self.get(url='/?')
94894Szelenkov@nginx.com
951596Szelenkov@nginx.com        assert resp['status'] == 200, 'query string empty status'
961596Szelenkov@nginx.com        assert resp['headers']['Query-String'] == '', 'query string empty'
97894Szelenkov@nginx.com
981850Smax.romanov@nginx.com    def test_php_application_fastcgi_finish_request(self, unit_pid):
991701Szelenkov@nginx.com        self.load('fastcgi_finish_request')
1001701Szelenkov@nginx.com
101*1862Szelenkov@nginx.com        assert 'success' in self.conf(
102*1862Szelenkov@nginx.com            {"admin": {"auto_globals_jit": "1"}},
103*1862Szelenkov@nginx.com            'applications/fastcgi_finish_request/options',
104*1862Szelenkov@nginx.com        )
105*1862Szelenkov@nginx.com
1061701Szelenkov@nginx.com        assert self.get()['body'] == '0123'
1071701Szelenkov@nginx.com
108*1862Szelenkov@nginx.com        os.kill(unit_pid, signal.SIGUSR1)
1091770Szelenkov@nginx.com
1101850Smax.romanov@nginx.com        errs = self.findall(r'Error in fastcgi_finish_request')
1111701Szelenkov@nginx.com
1121850Smax.romanov@nginx.com        assert len(errs) == 0, 'no error'
1131701Szelenkov@nginx.com
1141850Smax.romanov@nginx.com    def test_php_application_fastcgi_finish_request_2(self, unit_pid):
1151701Szelenkov@nginx.com        self.load('fastcgi_finish_request')
1161701Szelenkov@nginx.com
117*1862Szelenkov@nginx.com        assert 'success' in self.conf(
118*1862Szelenkov@nginx.com            {"admin": {"auto_globals_jit": "1"}},
119*1862Szelenkov@nginx.com            'applications/fastcgi_finish_request/options',
120*1862Szelenkov@nginx.com        )
121*1862Szelenkov@nginx.com
1221701Szelenkov@nginx.com        resp = self.get(url='/?skip')
1231701Szelenkov@nginx.com        assert resp['status'] == 200
1241701Szelenkov@nginx.com        assert resp['body'] == ''
1251701Szelenkov@nginx.com
126*1862Szelenkov@nginx.com        os.kill(unit_pid, signal.SIGUSR1)
1271701Szelenkov@nginx.com
1281850Smax.romanov@nginx.com        errs = self.findall(r'Error in fastcgi_finish_request')
1291701Szelenkov@nginx.com
1301850Smax.romanov@nginx.com        assert len(errs) == 0, 'no error'
1311701Szelenkov@nginx.com
132894Szelenkov@nginx.com    def test_php_application_query_string_absent(self):
133894Szelenkov@nginx.com        self.load('query_string')
134894Szelenkov@nginx.com
135894Szelenkov@nginx.com        resp = self.get()
136894Szelenkov@nginx.com
1371596Szelenkov@nginx.com        assert resp['status'] == 200, 'query string absent status'
1381596Szelenkov@nginx.com        assert resp['headers']['Query-String'] == '', 'query string absent'
139894Szelenkov@nginx.com
140675Szelenkov@nginx.com    def test_php_application_phpinfo(self):
141675Szelenkov@nginx.com        self.load('phpinfo')
142675Szelenkov@nginx.com
143675Szelenkov@nginx.com        resp = self.get()
144675Szelenkov@nginx.com
1451596Szelenkov@nginx.com        assert resp['status'] == 200, 'status'
1461596Szelenkov@nginx.com        assert resp['body'] != '', 'body not empty'
147675Szelenkov@nginx.com
1481090Svbart@nginx.com    def test_php_application_header_status(self):
1491090Svbart@nginx.com        self.load('header')
1501090Svbart@nginx.com
1511596Szelenkov@nginx.com        assert (
1521090Svbart@nginx.com            self.get(
1531090Svbart@nginx.com                headers={
1541090Svbart@nginx.com                    'Host': 'localhost',
1551090Svbart@nginx.com                    'Connection': 'close',
1561090Svbart@nginx.com                    'X-Header': 'HTTP/1.1 404 Not Found',
1571090Svbart@nginx.com                }
1581596Szelenkov@nginx.com            )['status']
1591596Szelenkov@nginx.com            == 404
1601596Szelenkov@nginx.com        ), 'status'
1611090Svbart@nginx.com
1621596Szelenkov@nginx.com        assert (
1631090Svbart@nginx.com            self.get(
1641090Svbart@nginx.com                headers={
1651090Svbart@nginx.com                    'Host': 'localhost',
1661090Svbart@nginx.com                    'Connection': 'close',
1671090Svbart@nginx.com                    'X-Header': 'http/1.1 404 Not Found',
1681090Svbart@nginx.com                }
1691596Szelenkov@nginx.com            )['status']
1701596Szelenkov@nginx.com            == 404
1711596Szelenkov@nginx.com        ), 'status case insensitive'
1721090Svbart@nginx.com
1731596Szelenkov@nginx.com        assert (
1741090Svbart@nginx.com            self.get(
1751090Svbart@nginx.com                headers={
1761090Svbart@nginx.com                    'Host': 'localhost',
1771090Svbart@nginx.com                    'Connection': 'close',
1781090Svbart@nginx.com                    'X-Header': 'HTTP/ 404 Not Found',
1791090Svbart@nginx.com                }
1801596Szelenkov@nginx.com            )['status']
1811596Szelenkov@nginx.com            == 404
1821596Szelenkov@nginx.com        ), 'status version empty'
1831090Svbart@nginx.com
184675Szelenkov@nginx.com    def test_php_application_404(self):
185675Szelenkov@nginx.com        self.load('404')
186675Szelenkov@nginx.com
187675Szelenkov@nginx.com        resp = self.get()
188675Szelenkov@nginx.com
1891596Szelenkov@nginx.com        assert resp['status'] == 404, '404 status'
1901596Szelenkov@nginx.com        assert re.search(
1911596Szelenkov@nginx.com            r'<title>404 Not Found</title>', resp['body']
1921596Szelenkov@nginx.com        ), '404 body'
193675Szelenkov@nginx.com
194675Szelenkov@nginx.com    def test_php_application_keepalive_body(self):
195675Szelenkov@nginx.com        self.load('mirror')
196675Szelenkov@nginx.com
1971596Szelenkov@nginx.com        assert self.get()['status'] == 200, 'init'
1981029Szelenkov@nginx.com
1991453Szelenkov@nginx.com        body = '0123456789' * 500
2001017Szelenkov@nginx.com        (resp, sock) = self.post(
2011017Szelenkov@nginx.com            headers={
2021017Szelenkov@nginx.com                'Host': 'localhost',
2031017Szelenkov@nginx.com                'Connection': 'keep-alive',
2041017Szelenkov@nginx.com                'Content-Type': 'text/html',
2051017Szelenkov@nginx.com            },
2061017Szelenkov@nginx.com            start=True,
2071453Szelenkov@nginx.com            body=body,
2081029Szelenkov@nginx.com            read_timeout=1,
2091017Szelenkov@nginx.com        )
210675Szelenkov@nginx.com
2111596Szelenkov@nginx.com        assert resp['body'] == body, 'keep-alive 1'
212675Szelenkov@nginx.com
2131453Szelenkov@nginx.com        body = '0123456789'
2141017Szelenkov@nginx.com        resp = self.post(
2151017Szelenkov@nginx.com            headers={
2161017Szelenkov@nginx.com                'Host': 'localhost',
2171017Szelenkov@nginx.com                'Connection': 'close',
2181017Szelenkov@nginx.com                'Content-Type': 'text/html',
2191017Szelenkov@nginx.com            },
2201017Szelenkov@nginx.com            sock=sock,
2211453Szelenkov@nginx.com            body=body,
2221017Szelenkov@nginx.com        )
223675Szelenkov@nginx.com
2241596Szelenkov@nginx.com        assert resp['body'] == body, 'keep-alive 2'
225675Szelenkov@nginx.com
226675Szelenkov@nginx.com    def test_php_application_conditional(self):
227675Szelenkov@nginx.com        self.load('conditional')
228675Szelenkov@nginx.com
2291596Szelenkov@nginx.com        assert re.search(r'True', self.get()['body']), 'conditional true'
2301596Szelenkov@nginx.com        assert re.search(r'False', self.post()['body']), 'conditional false'
231675Szelenkov@nginx.com
232675Szelenkov@nginx.com    def test_php_application_get_variables(self):
233675Szelenkov@nginx.com        self.load('get_variables')
234675Szelenkov@nginx.com
235675Szelenkov@nginx.com        resp = self.get(url='/?var1=val1&var2=&var3')
2361596Szelenkov@nginx.com        assert resp['headers']['X-Var-1'] == 'val1', 'GET variables'
2371636Svbart@nginx.com        assert resp['headers']['X-Var-2'] == '', 'GET variables 2'
2381636Svbart@nginx.com        assert resp['headers']['X-Var-3'] == '', 'GET variables 3'
2391636Svbart@nginx.com        assert resp['headers']['X-Var-4'] == 'not set', 'GET variables 4'
240675Szelenkov@nginx.com
241675Szelenkov@nginx.com    def test_php_application_post_variables(self):
242675Szelenkov@nginx.com        self.load('post_variables')
243675Szelenkov@nginx.com
2441017Szelenkov@nginx.com        resp = self.post(
2451017Szelenkov@nginx.com            headers={
2461017Szelenkov@nginx.com                'Content-Type': 'application/x-www-form-urlencoded',
2471017Szelenkov@nginx.com                'Host': 'localhost',
2481017Szelenkov@nginx.com                'Connection': 'close',
2491017Szelenkov@nginx.com            },
2501017Szelenkov@nginx.com            body='var1=val1&var2=',
2511017Szelenkov@nginx.com        )
2521596Szelenkov@nginx.com        assert resp['headers']['X-Var-1'] == 'val1', 'POST variables'
2531636Svbart@nginx.com        assert resp['headers']['X-Var-2'] == '', 'POST variables 2'
2541636Svbart@nginx.com        assert resp['headers']['X-Var-3'] == 'not set', 'POST variables 3'
255675Szelenkov@nginx.com
256675Szelenkov@nginx.com    def test_php_application_cookies(self):
257675Szelenkov@nginx.com        self.load('cookies')
258675Szelenkov@nginx.com
2591017Szelenkov@nginx.com        resp = self.get(
2601017Szelenkov@nginx.com            headers={
2611017Szelenkov@nginx.com                'Cookie': 'var=val; var2=val2',
2621017Szelenkov@nginx.com                'Host': 'localhost',
2631017Szelenkov@nginx.com                'Connection': 'close',
2641017Szelenkov@nginx.com            }
2651017Szelenkov@nginx.com        )
266675Szelenkov@nginx.com
2671596Szelenkov@nginx.com        assert resp['headers']['X-Cookie-1'] == 'val', 'cookie'
2681596Szelenkov@nginx.com        assert resp['headers']['X-Cookie-2'] == 'val2', 'cookie'
269675Szelenkov@nginx.com
270692Szelenkov@nginx.com    def test_php_application_ini_precision(self):
271692Szelenkov@nginx.com        self.load('ini_precision')
272692Szelenkov@nginx.com
2731596Szelenkov@nginx.com        assert self.get()['headers']['X-Precision'] != '4', 'ini value default'
2741017Szelenkov@nginx.com
2751775Szelenkov@nginx.com        assert 'success' in self.conf(
2761017Szelenkov@nginx.com            {"file": "ini/php.ini"}, 'applications/ini_precision/options'
2771017Szelenkov@nginx.com        )
278692Szelenkov@nginx.com
2791596Szelenkov@nginx.com        assert (
2801596Szelenkov@nginx.com            self.get()['headers']['X-File']
2811596Szelenkov@nginx.com            == option.test_dir + '/php/ini_precision/ini/php.ini'
2821596Szelenkov@nginx.com        ), 'ini file'
2831596Szelenkov@nginx.com        assert self.get()['headers']['X-Precision'] == '4', 'ini value'
284692Szelenkov@nginx.com
2851596Szelenkov@nginx.com    @pytest.mark.skip('not yet')
286721Szelenkov@nginx.com    def test_php_application_ini_admin_user(self):
287721Szelenkov@nginx.com        self.load('ini_precision')
288721Szelenkov@nginx.com
2891596Szelenkov@nginx.com        assert 'error' in self.conf(
2901596Szelenkov@nginx.com            {"user": {"precision": "4"}, "admin": {"precision": "5"}},
2911596Szelenkov@nginx.com            'applications/ini_precision/options',
2921596Szelenkov@nginx.com        ), 'ini admin user'
293721Szelenkov@nginx.com
294721Szelenkov@nginx.com    def test_php_application_ini_admin(self):
295721Szelenkov@nginx.com        self.load('ini_precision')
296721Szelenkov@nginx.com
2971775Szelenkov@nginx.com        assert 'success' in self.conf(
2981017Szelenkov@nginx.com            {"file": "php.ini", "admin": {"precision": "5"}},
2991017Szelenkov@nginx.com            'applications/ini_precision/options',
3001017Szelenkov@nginx.com        )
301721Szelenkov@nginx.com
3021596Szelenkov@nginx.com        assert self.get()['headers']['X-Precision'] == '5', 'ini value admin'
303721Szelenkov@nginx.com
304721Szelenkov@nginx.com    def test_php_application_ini_user(self):
305721Szelenkov@nginx.com        self.load('ini_precision')
306721Szelenkov@nginx.com
3071775Szelenkov@nginx.com        assert 'success' in self.conf(
3081017Szelenkov@nginx.com            {"file": "php.ini", "user": {"precision": "5"}},
3091017Szelenkov@nginx.com            'applications/ini_precision/options',
3101017Szelenkov@nginx.com        )
311721Szelenkov@nginx.com
3121596Szelenkov@nginx.com        assert self.get()['headers']['X-Precision'] == '5', 'ini value user'
313721Szelenkov@nginx.com
314721Szelenkov@nginx.com    def test_php_application_ini_user_2(self):
315721Szelenkov@nginx.com        self.load('ini_precision')
316721Szelenkov@nginx.com
3171775Szelenkov@nginx.com        assert 'success' in self.conf(
3181017Szelenkov@nginx.com            {"file": "ini/php.ini"}, 'applications/ini_precision/options'
3191017Szelenkov@nginx.com        )
320721Szelenkov@nginx.com
3211596Szelenkov@nginx.com        assert self.get()['headers']['X-Precision'] == '4', 'ini user file'
322721Szelenkov@nginx.com
3231775Szelenkov@nginx.com        assert 'success' in self.conf(
3241017Szelenkov@nginx.com            {"precision": "5"}, 'applications/ini_precision/options/user'
3251017Szelenkov@nginx.com        )
326721Szelenkov@nginx.com
3271596Szelenkov@nginx.com        assert self.get()['headers']['X-Precision'] == '5', 'ini value user'
328721Szelenkov@nginx.com
329721Szelenkov@nginx.com    def test_php_application_ini_set_admin(self):
330721Szelenkov@nginx.com        self.load('ini_precision')
331721Szelenkov@nginx.com
3321775Szelenkov@nginx.com        assert 'success' in self.conf(
3331017Szelenkov@nginx.com            {"admin": {"precision": "5"}}, 'applications/ini_precision/options'
3341017Szelenkov@nginx.com        )
335721Szelenkov@nginx.com
3361596Szelenkov@nginx.com        assert (
3371596Szelenkov@nginx.com            self.get(url='/?precision=6')['headers']['X-Precision'] == '5'
3381596Szelenkov@nginx.com        ), 'ini set admin'
339721Szelenkov@nginx.com
340721Szelenkov@nginx.com    def test_php_application_ini_set_user(self):
341721Szelenkov@nginx.com        self.load('ini_precision')
342721Szelenkov@nginx.com
3431775Szelenkov@nginx.com        assert 'success' in self.conf(
3441017Szelenkov@nginx.com            {"user": {"precision": "5"}}, 'applications/ini_precision/options'
3451017Szelenkov@nginx.com        )
346721Szelenkov@nginx.com
3471596Szelenkov@nginx.com        assert (
3481596Szelenkov@nginx.com            self.get(url='/?precision=6')['headers']['X-Precision'] == '6'
3491596Szelenkov@nginx.com        ), 'ini set user'
350721Szelenkov@nginx.com
351721Szelenkov@nginx.com    def test_php_application_ini_repeat(self):
352721Szelenkov@nginx.com        self.load('ini_precision')
353721Szelenkov@nginx.com
3541775Szelenkov@nginx.com        assert 'success' in self.conf(
3551017Szelenkov@nginx.com            {"user": {"precision": "5"}}, 'applications/ini_precision/options'
3561017Szelenkov@nginx.com        )
357721Szelenkov@nginx.com
3581596Szelenkov@nginx.com        assert self.get()['headers']['X-Precision'] == '5', 'ini value'
359721Szelenkov@nginx.com
3601596Szelenkov@nginx.com        assert self.get()['headers']['X-Precision'] == '5', 'ini value repeat'
361721Szelenkov@nginx.com
362865Szelenkov@nginx.com    def test_php_application_disable_functions_exec(self):
363982Szelenkov@nginx.com        self.load('time_exec')
364982Szelenkov@nginx.com
365982Szelenkov@nginx.com        self.before_disable_functions()
366865Szelenkov@nginx.com
3671775Szelenkov@nginx.com        assert 'success' in self.conf(
3681017Szelenkov@nginx.com            {"admin": {"disable_functions": "exec"}},
3691017Szelenkov@nginx.com            'applications/time_exec/options',
3701017Szelenkov@nginx.com        )
371865Szelenkov@nginx.com
372982Szelenkov@nginx.com        body = self.get()['body']
373865Szelenkov@nginx.com
3741596Szelenkov@nginx.com        assert re.search(r'time: \d+', body), 'disable_functions time'
3751596Szelenkov@nginx.com        assert not re.search(r'exec: \/\w+', body), 'disable_functions exec'
376865Szelenkov@nginx.com
377865Szelenkov@nginx.com    def test_php_application_disable_functions_comma(self):
378982Szelenkov@nginx.com        self.load('time_exec')
379865Szelenkov@nginx.com
380982Szelenkov@nginx.com        self.before_disable_functions()
381865Szelenkov@nginx.com
3821775Szelenkov@nginx.com        assert 'success' in self.conf(
3831017Szelenkov@nginx.com            {"admin": {"disable_functions": "exec,time"}},
3841017Szelenkov@nginx.com            'applications/time_exec/options',
3851017Szelenkov@nginx.com        )
386865Szelenkov@nginx.com
387982Szelenkov@nginx.com        body = self.get()['body']
388982Szelenkov@nginx.com
3891596Szelenkov@nginx.com        assert not re.search(
3901596Szelenkov@nginx.com            r'time: \d+', body
3911596Szelenkov@nginx.com        ), 'disable_functions comma time'
3921596Szelenkov@nginx.com        assert not re.search(
3931596Szelenkov@nginx.com            r'exec: \/\w+', body
3941596Szelenkov@nginx.com        ), 'disable_functions comma exec'
395865Szelenkov@nginx.com
3961742Szelenkov@nginx.com    def test_php_application_auth(self):
3971742Szelenkov@nginx.com        self.load('auth')
3981742Szelenkov@nginx.com
3991742Szelenkov@nginx.com        resp = self.get()
4001742Szelenkov@nginx.com        assert resp['status'] == 200, 'status'
4011742Szelenkov@nginx.com        assert resp['headers']['X-Digest'] == 'not set', 'digest'
4021742Szelenkov@nginx.com        assert resp['headers']['X-User'] == 'not set', 'user'
4031742Szelenkov@nginx.com        assert resp['headers']['X-Password'] == 'not set', 'password'
4041742Szelenkov@nginx.com
4051742Szelenkov@nginx.com        resp = self.get(
4061742Szelenkov@nginx.com            headers={
4071742Szelenkov@nginx.com                'Host': 'localhost',
4081742Szelenkov@nginx.com                'Authorization': 'Basic dXNlcjpwYXNzd29yZA==',
4091742Szelenkov@nginx.com                'Connection': 'close',
4101742Szelenkov@nginx.com            }
4111742Szelenkov@nginx.com        )
4121742Szelenkov@nginx.com        assert resp['status'] == 200, 'basic status'
4131742Szelenkov@nginx.com        assert resp['headers']['X-Digest'] == 'not set', 'basic digest'
4141742Szelenkov@nginx.com        assert resp['headers']['X-User'] == 'user', 'basic user'
4151742Szelenkov@nginx.com        assert resp['headers']['X-Password'] == 'password', 'basic password'
4161742Szelenkov@nginx.com
4171742Szelenkov@nginx.com        resp = self.get(
4181742Szelenkov@nginx.com            headers={
4191742Szelenkov@nginx.com                'Host': 'localhost',
4201742Szelenkov@nginx.com                'Authorization': 'Digest username="blah", realm="", uri="/"',
4211742Szelenkov@nginx.com                'Connection': 'close',
4221742Szelenkov@nginx.com            }
4231742Szelenkov@nginx.com        )
4241742Szelenkov@nginx.com        assert resp['status'] == 200, 'digest status'
4251742Szelenkov@nginx.com        assert (
4261742Szelenkov@nginx.com            resp['headers']['X-Digest'] == 'username="blah", realm="", uri="/"'
4271742Szelenkov@nginx.com        ), 'digest digest'
4281742Szelenkov@nginx.com        assert resp['headers']['X-User'] == 'not set', 'digest user'
4291742Szelenkov@nginx.com        assert resp['headers']['X-Password'] == 'not set', 'digest password'
4301742Szelenkov@nginx.com
4311742Szelenkov@nginx.com    def test_php_application_auth_invalid(self):
4321742Szelenkov@nginx.com        self.load('auth')
4331742Szelenkov@nginx.com
4341742Szelenkov@nginx.com        def check_auth(auth):
4351848Szelenkov@nginx.com            resp = self.get(
4361848Szelenkov@nginx.com                headers={
4371848Szelenkov@nginx.com                    'Host': 'localhost',
4381848Szelenkov@nginx.com                    'Authorization': auth,
4391848Szelenkov@nginx.com                    'Connection': 'close',
4401848Szelenkov@nginx.com                }
4411848Szelenkov@nginx.com            )
4421742Szelenkov@nginx.com
4431742Szelenkov@nginx.com            assert resp['status'] == 200, 'status'
4441742Szelenkov@nginx.com            assert resp['headers']['X-Digest'] == 'not set', 'Digest'
4451742Szelenkov@nginx.com            assert resp['headers']['X-User'] == 'not set', 'User'
4461742Szelenkov@nginx.com            assert resp['headers']['X-Password'] == 'not set', 'Password'
4471742Szelenkov@nginx.com
4481742Szelenkov@nginx.com        check_auth('Basic dXN%cjpwYXNzd29yZA==')
4491742Szelenkov@nginx.com        check_auth('Basic XNlcjpwYXNzd29yZA==')
4501742Szelenkov@nginx.com        check_auth('Basic DdXNlcjpwYXNzd29yZA==')
4511742Szelenkov@nginx.com        check_auth('Basic blah')
4521742Szelenkov@nginx.com        check_auth('Basic')
4531742Szelenkov@nginx.com        check_auth('Digest')
4541742Szelenkov@nginx.com        check_auth('blah')
4551742Szelenkov@nginx.com
456865Szelenkov@nginx.com    def test_php_application_disable_functions_space(self):
457982Szelenkov@nginx.com        self.load('time_exec')
458865Szelenkov@nginx.com
459982Szelenkov@nginx.com        self.before_disable_functions()
460865Szelenkov@nginx.com
4611775Szelenkov@nginx.com        assert 'success' in self.conf(
4621017Szelenkov@nginx.com            {"admin": {"disable_functions": "exec time"}},
4631017Szelenkov@nginx.com            'applications/time_exec/options',
4641017Szelenkov@nginx.com        )
465865Szelenkov@nginx.com
466982Szelenkov@nginx.com        body = self.get()['body']
467982Szelenkov@nginx.com
4681596Szelenkov@nginx.com        assert not re.search(
4691596Szelenkov@nginx.com            r'time: \d+', body
4701596Szelenkov@nginx.com        ), 'disable_functions space time'
4711596Szelenkov@nginx.com        assert not re.search(
4721596Szelenkov@nginx.com            r'exec: \/\w+', body
4731596Szelenkov@nginx.com        ), 'disable_functions space exec'
474865Szelenkov@nginx.com
475865Szelenkov@nginx.com    def test_php_application_disable_functions_user(self):
476982Szelenkov@nginx.com        self.load('time_exec')
477982Szelenkov@nginx.com
478982Szelenkov@nginx.com        self.before_disable_functions()
479865Szelenkov@nginx.com
4801775Szelenkov@nginx.com        assert 'success' in self.conf(
4811017Szelenkov@nginx.com            {"user": {"disable_functions": "exec"}},
4821017Szelenkov@nginx.com            'applications/time_exec/options',
4831017Szelenkov@nginx.com        )
484865Szelenkov@nginx.com
485982Szelenkov@nginx.com        body = self.get()['body']
486982Szelenkov@nginx.com
4871596Szelenkov@nginx.com        assert re.search(r'time: \d+', body), 'disable_functions user time'
4881596Szelenkov@nginx.com        assert not re.search(
4891596Szelenkov@nginx.com            r'exec: \/\w+', body
4901596Szelenkov@nginx.com        ), 'disable_functions user exec'
491865Szelenkov@nginx.com
492865Szelenkov@nginx.com    def test_php_application_disable_functions_nonexistent(self):
493982Szelenkov@nginx.com        self.load('time_exec')
494982Szelenkov@nginx.com
495982Szelenkov@nginx.com        self.before_disable_functions()
496865Szelenkov@nginx.com
4971775Szelenkov@nginx.com        assert 'success' in self.conf(
4981017Szelenkov@nginx.com            {"admin": {"disable_functions": "blah"}},
4991017Szelenkov@nginx.com            'applications/time_exec/options',
5001017Szelenkov@nginx.com        )
501865Szelenkov@nginx.com
502982Szelenkov@nginx.com        body = self.get()['body']
503865Szelenkov@nginx.com
5041596Szelenkov@nginx.com        assert re.search(
5051596Szelenkov@nginx.com            r'time: \d+', body
5061596Szelenkov@nginx.com        ), 'disable_functions nonexistent time'
5071596Szelenkov@nginx.com        assert re.search(
5081596Szelenkov@nginx.com            r'exec: \/\w+', body
5091596Szelenkov@nginx.com        ), 'disable_functions nonexistent exec'
510865Szelenkov@nginx.com
511865Szelenkov@nginx.com    def test_php_application_disable_classes(self):
512865Szelenkov@nginx.com        self.load('date_time')
513865Szelenkov@nginx.com
5141596Szelenkov@nginx.com        assert re.search(
5151596Szelenkov@nginx.com            r'012345', self.get()['body']
5161596Szelenkov@nginx.com        ), 'disable_classes before'
517865Szelenkov@nginx.com
5181775Szelenkov@nginx.com        assert 'success' in self.conf(
5191017Szelenkov@nginx.com            {"admin": {"disable_classes": "DateTime"}},
5201017Szelenkov@nginx.com            'applications/date_time/options',
5211017Szelenkov@nginx.com        )
522865Szelenkov@nginx.com
5231596Szelenkov@nginx.com        assert not re.search(
5241596Szelenkov@nginx.com            r'012345', self.get()['body']
5251596Szelenkov@nginx.com        ), 'disable_classes before'
526865Szelenkov@nginx.com
527865Szelenkov@nginx.com    def test_php_application_disable_classes_user(self):
528865Szelenkov@nginx.com        self.load('date_time')
529865Szelenkov@nginx.com
5301596Szelenkov@nginx.com        assert re.search(
5311596Szelenkov@nginx.com            r'012345', self.get()['body']
5321596Szelenkov@nginx.com        ), 'disable_classes before'
533982Szelenkov@nginx.com
5341775Szelenkov@nginx.com        assert 'success' in self.conf(
5351017Szelenkov@nginx.com            {"user": {"disable_classes": "DateTime"}},
5361017Szelenkov@nginx.com            'applications/date_time/options',
5371017Szelenkov@nginx.com        )
538865Szelenkov@nginx.com
5391596Szelenkov@nginx.com        assert not re.search(
5401596Szelenkov@nginx.com            r'012345', self.get()['body']
5411596Szelenkov@nginx.com        ), 'disable_classes before'
5421017Szelenkov@nginx.com
5431850Smax.romanov@nginx.com    def test_php_application_error_log(self):
5441529Szelenkov@nginx.com        self.load('error_log')
5451529Szelenkov@nginx.com
5461596Szelenkov@nginx.com        assert self.get()['status'] == 200, 'status'
5471529Szelenkov@nginx.com
5481529Szelenkov@nginx.com        time.sleep(1)
5491529Szelenkov@nginx.com
5501596Szelenkov@nginx.com        assert self.get()['status'] == 200, 'status 2'
5511529Szelenkov@nginx.com
5521529Szelenkov@nginx.com        pattern = r'\d{4}\/\d\d\/\d\d\s\d\d:.+\[notice\].+Error in application'
5531529Szelenkov@nginx.com
5541596Szelenkov@nginx.com        assert self.wait_for_record(pattern) is not None, 'errors print'
5551529Szelenkov@nginx.com
5561850Smax.romanov@nginx.com        errs = self.findall(pattern)
5571850Smax.romanov@nginx.com
5581850Smax.romanov@nginx.com        assert len(errs) == 2, 'error_log count'
5591529Szelenkov@nginx.com
5601850Smax.romanov@nginx.com        date = errs[0].split('[')[0]
5611850Smax.romanov@nginx.com        date2 = errs[1].split('[')[0]
5621850Smax.romanov@nginx.com        assert date != date2, 'date diff'
5631529Szelenkov@nginx.com
5641105Szelenkov@nginx.com    def test_php_application_script(self):
5651596Szelenkov@nginx.com        assert 'success' in self.conf(
5661596Szelenkov@nginx.com            {
5671596Szelenkov@nginx.com                "listeners": {"*:7080": {"pass": "applications/script"}},
5681596Szelenkov@nginx.com                "applications": {
5691596Szelenkov@nginx.com                    "script": {
5701596Szelenkov@nginx.com                        "type": "php",
5711596Szelenkov@nginx.com                        "processes": {"spare": 0},
5721596Szelenkov@nginx.com                        "root": option.test_dir + "/php/script",
5731596Szelenkov@nginx.com                        "script": "phpinfo.php",
5741596Szelenkov@nginx.com                    }
5751596Szelenkov@nginx.com                },
5761596Szelenkov@nginx.com            }
5771596Szelenkov@nginx.com        ), 'configure script'
5781105Szelenkov@nginx.com
5791105Szelenkov@nginx.com        resp = self.get()
5801105Szelenkov@nginx.com
5811596Szelenkov@nginx.com        assert resp['status'] == 200, 'status'
5821596Szelenkov@nginx.com        assert resp['body'] != '', 'body not empty'
5831105Szelenkov@nginx.com
5841105Szelenkov@nginx.com    def test_php_application_index_default(self):
5851596Szelenkov@nginx.com        assert 'success' in self.conf(
5861596Szelenkov@nginx.com            {
5871596Szelenkov@nginx.com                "listeners": {"*:7080": {"pass": "applications/phpinfo"}},
5881596Szelenkov@nginx.com                "applications": {
5891596Szelenkov@nginx.com                    "phpinfo": {
5901596Szelenkov@nginx.com                        "type": "php",
5911596Szelenkov@nginx.com                        "processes": {"spare": 0},
5921596Szelenkov@nginx.com                        "root": option.test_dir + "/php/phpinfo",
5931596Szelenkov@nginx.com                    }
5941596Szelenkov@nginx.com                },
5951596Szelenkov@nginx.com            }
5961596Szelenkov@nginx.com        ), 'configure index default'
5971105Szelenkov@nginx.com
5981346St.nateldemoura@f5.com        resp = self.get()
5991346St.nateldemoura@f5.com
6001596Szelenkov@nginx.com        assert resp['status'] == 200, 'status'
6011596Szelenkov@nginx.com        assert resp['body'] != '', 'body not empty'
6021346St.nateldemoura@f5.com
6031654Szelenkov@nginx.com    def test_php_application_extension_check(self, temp_dir):
6041346St.nateldemoura@f5.com        self.load('phpinfo')
6051346St.nateldemoura@f5.com
6061596Szelenkov@nginx.com        assert self.get(url='/index.wrong')['status'] != 200, 'status'
6071596Szelenkov@nginx.com
6081654Szelenkov@nginx.com        new_root = temp_dir + "/php"
6091596Szelenkov@nginx.com        os.mkdir(new_root)
6101596Szelenkov@nginx.com        shutil.copy(option.test_dir + '/php/phpinfo/index.wrong', new_root)
6111596Szelenkov@nginx.com
6121596Szelenkov@nginx.com        assert 'success' in self.conf(
6131596Szelenkov@nginx.com            {
6141596Szelenkov@nginx.com                "listeners": {"*:7080": {"pass": "applications/phpinfo"}},
6151596Szelenkov@nginx.com                "applications": {
6161596Szelenkov@nginx.com                    "phpinfo": {
6171596Szelenkov@nginx.com                        "type": "php",
6181596Szelenkov@nginx.com                        "processes": {"spare": 0},
6191596Szelenkov@nginx.com                        "root": new_root,
6201596Szelenkov@nginx.com                        "working_directory": new_root,
6211596Szelenkov@nginx.com                    }
6221596Szelenkov@nginx.com                },
6231596Szelenkov@nginx.com            }
6241596Szelenkov@nginx.com        ), 'configure new root'
6251596Szelenkov@nginx.com
6261596Szelenkov@nginx.com        resp = self.get()
6271596Szelenkov@nginx.com        assert str(resp['status']) + resp['body'] != '200', 'status new root'
6281596Szelenkov@nginx.com
6291596Szelenkov@nginx.com    def run_php_application_cwd_root_tests(self):
6301596Szelenkov@nginx.com        assert 'success' in self.conf_delete(
6311596Szelenkov@nginx.com            'applications/cwd/working_directory'
6321346St.nateldemoura@f5.com        )
633865Szelenkov@nginx.com
6341596Szelenkov@nginx.com        script_cwd = option.test_dir + '/php/cwd'
6351367Szelenkov@nginx.com
6361596Szelenkov@nginx.com        resp = self.get()
6371596Szelenkov@nginx.com        assert resp['status'] == 200, 'status ok'
6381596Szelenkov@nginx.com        assert resp['body'] == script_cwd, 'default cwd'
6391596Szelenkov@nginx.com
6401596Szelenkov@nginx.com        assert 'success' in self.conf(
6411596Szelenkov@nginx.com            '"' + option.test_dir + '"', 'applications/cwd/working_directory',
6421367Szelenkov@nginx.com        )
6431367Szelenkov@nginx.com
6441367Szelenkov@nginx.com        resp = self.get()
6451596Szelenkov@nginx.com        assert resp['status'] == 200, 'status ok'
6461596Szelenkov@nginx.com        assert resp['body'] == script_cwd, 'wdir cwd'
6471381St.nateldemoura@f5.com
6481381St.nateldemoura@f5.com        resp = self.get(url='/?chdir=/')
6491596Szelenkov@nginx.com        assert resp['status'] == 200, 'status ok'
6501596Szelenkov@nginx.com        assert resp['body'] == '/', 'cwd after chdir'
6511381St.nateldemoura@f5.com
6521381St.nateldemoura@f5.com        # cwd must be restored
6531381St.nateldemoura@f5.com
6541381St.nateldemoura@f5.com        resp = self.get()
6551596Szelenkov@nginx.com        assert resp['status'] == 200, 'status ok'
6561596Szelenkov@nginx.com        assert resp['body'] == script_cwd, 'cwd restored'
6571381St.nateldemoura@f5.com
6581381St.nateldemoura@f5.com        resp = self.get(url='/subdir/')
6591596Szelenkov@nginx.com        assert resp['body'] == script_cwd + '/subdir', 'cwd subdir'
6601381St.nateldemoura@f5.com
6611381St.nateldemoura@f5.com    def test_php_application_cwd_root(self):
6621381St.nateldemoura@f5.com        self.load('cwd')
6631381St.nateldemoura@f5.com        self.run_php_application_cwd_root_tests()
6641381St.nateldemoura@f5.com
6651381St.nateldemoura@f5.com    def test_php_application_cwd_opcache_disabled(self):
6661381St.nateldemoura@f5.com        self.load('cwd')
6671381St.nateldemoura@f5.com        self.set_opcache('cwd', '0')
6681381St.nateldemoura@f5.com        self.run_php_application_cwd_root_tests()
6691381St.nateldemoura@f5.com
6701381St.nateldemoura@f5.com    def test_php_application_cwd_opcache_enabled(self):
6711381St.nateldemoura@f5.com        self.load('cwd')
6721381St.nateldemoura@f5.com        self.set_opcache('cwd', '1')
6731381St.nateldemoura@f5.com        self.run_php_application_cwd_root_tests()
6741381St.nateldemoura@f5.com
6751381St.nateldemoura@f5.com    def run_php_application_cwd_script_tests(self):
6761381St.nateldemoura@f5.com        self.load('cwd')
6771381St.nateldemoura@f5.com
6781596Szelenkov@nginx.com        script_cwd = option.test_dir + '/php/cwd'
6791381St.nateldemoura@f5.com
6801596Szelenkov@nginx.com        assert 'success' in self.conf_delete(
6811596Szelenkov@nginx.com            'applications/cwd/working_directory'
6821381St.nateldemoura@f5.com        )
6831381St.nateldemoura@f5.com
6841596Szelenkov@nginx.com        assert 'success' in self.conf('"index.php"', 'applications/cwd/script')
6851381St.nateldemoura@f5.com
6861596Szelenkov@nginx.com        assert self.get()['body'] == script_cwd, 'default cwd'
6871596Szelenkov@nginx.com
6881596Szelenkov@nginx.com        assert self.get(url='/?chdir=/')['body'] == '/', 'cwd after chdir'
6891381St.nateldemoura@f5.com
6901381St.nateldemoura@f5.com        # cwd must be restored
6911596Szelenkov@nginx.com        assert self.get()['body'] == script_cwd, 'cwd restored'
6921381St.nateldemoura@f5.com
6931381St.nateldemoura@f5.com    def test_php_application_cwd_script(self):
6941381St.nateldemoura@f5.com        self.load('cwd')
6951381St.nateldemoura@f5.com        self.run_php_application_cwd_script_tests()
6961381St.nateldemoura@f5.com
6971381St.nateldemoura@f5.com    def test_php_application_cwd_script_opcache_disabled(self):
6981381St.nateldemoura@f5.com        self.load('cwd')
6991381St.nateldemoura@f5.com        self.set_opcache('cwd', '0')
7001381St.nateldemoura@f5.com        self.run_php_application_cwd_script_tests()
7011381St.nateldemoura@f5.com
7021381St.nateldemoura@f5.com    def test_php_application_cwd_script_opcache_enabled(self):
7031381St.nateldemoura@f5.com        self.load('cwd')
7041381St.nateldemoura@f5.com        self.set_opcache('cwd', '1')
7051381St.nateldemoura@f5.com        self.run_php_application_cwd_script_tests()
7061381St.nateldemoura@f5.com
7071381St.nateldemoura@f5.com    def test_php_application_path_relative(self):
7081381St.nateldemoura@f5.com        self.load('open')
7091381St.nateldemoura@f5.com
7101596Szelenkov@nginx.com        assert self.get()['body'] == 'test', 'relative path'
7111381St.nateldemoura@f5.com
7121596Szelenkov@nginx.com        assert (
7131596Szelenkov@nginx.com            self.get(url='/?chdir=/')['body'] != 'test'
7141596Szelenkov@nginx.com        ), 'relative path w/ chdir'
7151367Szelenkov@nginx.com
7161596Szelenkov@nginx.com        assert self.get()['body'] == 'test', 'relative path 2'
717