diff options
author | Andrew Clayton <a.clayton@nginx.com> | 2022-09-16 14:38:53 +0100 |
---|---|---|
committer | Andrew Clayton <a.clayton@nginx.com> | 2022-11-02 14:22:39 +0000 |
commit | a03274456b54cbc39e220b9dd73c3fc3fb935e46 (patch) | |
tree | b0ba7a067a1399f2a56f1d6cad8198e874683740 /test | |
parent | 58248a6220540db89e69c928a5d8ad6be2a326fb (diff) | |
download | unit-a03274456b54cbc39e220b9dd73c3fc3fb935e46.tar.gz unit-a03274456b54cbc39e220b9dd73c3fc3fb935e46.tar.bz2 |
PHP: allowed to specify URLs without a trailing '/'.
Both @lucatacconi & @mwoodpatrick reported what appears to be the same
issue on GitHub. Namely that when using the PHP language module and
trying to access a URL that is a directory but without specifying the
trailing '/', they were getting a '503 Service Unavailable' error.
Note: This is when _not_ using the 'script' option.
E.g with the following config
{
"listeners": {
"[::1]:8080": {
"pass": "applications/php"
}
},
"applications": {
"php": {
"type": "php",
"root": "/var/tmp/unit-php"
}
}
}
and with a directory path of /var/tmp/unit-php/foo containing an
index.php, you would see the following
$ curl http://localhost/foo
<title>Error 503</title>
Error 503
However
$ curl http://localhost/foo/
would work and serve up the index.php
This commit fixes the above so you get the desired behaviour without
specifying the trailing '/' by doing the following
1] If the URL doesn't end in .php and doesn't have a trailing '/'
then check if the requested path is a directory.
2) If it is a directory then create a 301 re-direct pointing to it.
This matches the behaviour of the likes of nginx, Apache and
lighttpd.
This also matches the behaviour of the "share" action in Unit.
This doesn't effect the behaviour of the 'script' option which bypasses
the nxt_php_dynamic_request() function.
This also adds a couple of tests to test/test_php_application.py to
ensure this continues to work.
Closes: <https://github.com/nginx/unit/issues/717>
Closes: <https://github.com/nginx/unit/issues/753>
Signed-off-by: Andrew Clayton <a.clayton@nginx.com>
Diffstat (limited to 'test')
-rw-r--r-- | test/test_php_application.py | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/test/test_php_application.py b/test/test_php_application.py index f1dcc995..f442f551 100644 --- a/test/test_php_application.py +++ b/test/test_php_application.py @@ -4,6 +4,7 @@ import re import shutil import signal import time +from pathlib import Path import pytest from unit.applications.lang.php import TestApplicationPHP @@ -620,6 +621,49 @@ opcache.preload_user = %(user)s assert resp['status'] == 200, 'status' assert resp['body'] != '', 'body not empty' + def test_php_application_trailing_slash(self, temp_dir): + new_root = temp_dir + "/php-root" + os.makedirs(new_root + '/path') + + Path(new_root + '/path/index.php').write_text('<?php echo "OK\n"; ?>') + + addr = temp_dir + '/sock' + + assert 'success' in self.conf( + { + "listeners": { + "*:7080": {"pass": "applications/php-path"}, + "unix:" + addr: {"pass": "applications/php-path"}, + }, + "applications": { + "php-path": { + "type": self.get_application_type(), + "processes": {"spare": 0}, + "root": new_root, + } + }, + } + ), 'configure trailing slash' + + assert self.get(url='/path/')['status'] == 200, 'uri with trailing /' + + resp = self.get(url='/path?q=a') + assert resp['status'] == 301, 'uri without trailing /' + assert ( + resp['headers']['Location'] == 'http://localhost:7080/path/?q=a' + ), 'Location with query string' + + resp = self.get( + sock_type='unix', + addr=addr, + url='/path', + headers={'Host': 'foo', 'Connection': 'close'}, + ) + assert resp['status'] == 301, 'uri without trailing /' + assert ( + resp['headers']['Location'] == 'http://foo/path/' + ), 'Location with custom Host over UDS' + def test_php_application_extension_check(self, temp_dir): self.load('phpinfo') |