Я переключаюсь с Apache на Nginx / fcgi, и у меня возникла небольшая проблема при попытке настроить правила перезаписи приложений.
Код обрабатывает маршруты с помощью PATH_INFO, например, example.com/foo/bar/ будет перенаправлен на example.com/index.php/foo/bar/
Я изменил конфигурацию сервера, чтобы передать PATH_INFO:
location ~ \.php$ {
include /etc/nginx/fastcgi_params;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_split_path_info ^(.+\.php)(.*)$;
fastcgi_param SCRIPT_FILENAME /var/www/public$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
}
И обработчик перезаписи:
location / {
root /var/www/public;
index index.html index.htm index.php;
if (!-f $request_filename) {
rewrite ^(.*)/(.*)$ /index.php/$2 break;
}
}
С участием 'rewrite_log на', URL-адрес правильно маршрутизируется:
[error]: *2 open() "/var/www/public/index.php/test" failed (20: Not a directory), client: 192.168.0.254, server: example.com, request: "GET /test HTTP/1.1", host: "example.com", referrer: "http://example.com/index.php"
Однако, похоже, он ищет каталог «test». Как я могу заставить его запросить index.php, передав скрипту / test?
Что ж, у вас много проблем, во-первых, вы следуете дерьмовому руководству, которое сильно устарело. if (!-f
обычно не рекомендуется, если вместо него предлагается try_files.
Во-вторых, у вас есть директивы в местоположении / контексте, которые должны быть в контексте сервера, чтобы вы могли избежать дублирования пути в переменной SCRIPT_FILENAME.
Во-вторых, вы используете флаг прерывания в своей перезаписи, это фактически означает, что он не должен повторно оценивать сопоставление местоположения. Это фактически заставляет запрос никогда не покидать местоположение / блок и вместо этого обрабатывается как запрос статического файла.
В-третьих. Посмотри на свой location ~ \.php$ {
Nginx сопоставляет местоположения с URI, и вы специально указываете Nginx обрабатывать только те URI, которые заканчиваются на .php, но если вы перепишете в index.php / test /, он не сработает.
Наконец. Вы используете PATH_INFO, в то время как должны использовать REQUEST_URI. Разница в том, что для того, чтобы PATH_INFO работал, вы должны указать Nginx передать любой запрос с .php в PHP, а затем PHP должен найти нужный файл.
Это означает, что вы разрешаете отправлять в PHP такие запросы, как example.org/uploads/image.jpg/index.php, а также разрешаете PHP выполнять файл /uploads/image.jpg. Если злонамеренный пользователь загрузил этот файл с PHP в нем, теперь на вашем сервере выполняется произвольный код. Это очень реальный эксплойт, которому я лично видел, как люди уязвимы.
Пожалуйста, прекратите использование руководств в случайном порядке, потому что 90% из них - сплошной мусор, вместо этого прочтите вики. Возможно, вам будет сложно узнать об используемом вами веб-сервере, но альтернативой является взлом вашего сервера.