LINUX.ORG.RU
решено ФорумAdmin

Нaстроить nginx

 ,


0

1

В nginx попадает URL типа /index.php/page1 и обычное его поведение — обработать index.php, а всё, что дальше — отправить в PATH_INFO. Но когда URL реврайтится, чем-то простым вроде

location / {
    if (!-e $request_filename){
        rewrite ^(.*)$ /index.php$1 break;
    }
}
и подаётся уже укороченное /page1, он уже не ищет файл index.php, а считает его по умолчанию каталогом и возвращает соответственно 404 и внутреннюю failed (20: Not a directory). Как это вообще работает и где описано?

upd:
Всё, нашёл решение. http://www.ruby-forum.com/topic/901362
upd:
Хм, показалось, что нашёл. Сейчас / и /index.php/page1 работают нормально, а /page1 спотыкается о каталог. Конфигурация вот такая:

        location / {
            allow all;
            if (!-f $request_filename){
                rewrite ^([^/]*)(/.+)$ /index.php$2 break;
            }
        }
        location ~ ^.+\.php {
            fastcgi_pass unix:/var/run/php-fpm/default.socket;
            fastcgi_index index.php;
            include fastcgi_params;
            fastcgi_split_path_info ^((?U).+\.php)(/?.+)$;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            fastcgi_param PATH_INFO $fastcgi_path_info;
            fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
        }

Deleted

Последнее исправление: fargred (всего исправлений: 2)

Т.е. ты хочешь чтобы одна страница открывалась по /page1 и /index.php/page1? Краткий ответ: множественные урлы на одну страницу это зло.

true_admin ★★★★★
()
Ответ на: комментарий от true_admin

Нет, я хочу, чтобы осталась только /page1, Просто в случае с /index.php/page1 я её пока держу, чтоб было с чем работать.

Deleted
()
Ответ на: комментарий от Deleted

Обычно вижу что делают как-то так: http://xenforo.com/community/threads/setup-seo-full-friendly-urls-on-nginx.51...

Правда, это не запретит вызывать index.php без параметров, т.е. вызывать скрипты напрямую. Но это можно пофиксить простым правилом.

true_admin ★★★★★
()
Ответ на: комментарий от Deleted

Например, чему будет равен $fastcgi_script_name при запросе /page1?

Ну и что значит «спотыкается о каталог»? Не вызывает index.php в нём?

Да и, похоже, я вообще не понимаю задачу. Я не понимаю какой мапинг ты хочешь сделать. Я сходу подумал что тебе на все урлы нужно выдавать index.php и в PATH_INFO пихать оригинальный урл.

true_admin ★★★★★
()
Ответ на: комментарий от true_admin

Например, чему будет равен $fastcgi_script_name при запросе /page1?

/page1

Ну и что значит «спотыкается о каталог»?

Это значит, что nginx

уже не ищет файл index.php, а считает его по умолчанию каталогом и возвращает соответственно 404 и внутреннюю failed (20: Not a directory)

Да и, похоже, я вообще не понимаю задачу

Мне нужно сделать так, чтобы /page1 реврайтилось в /index.php/page1, при этом бы обрабатывался собссно index.php, а /page1 попадало в переменную PATH_INFO, как и должно по идее в случае с CGI. Ну и чтоб не реврайтилась статика, потому что нормально она отдаётся только когда запрашивается корень.

Deleted
()
Последнее исправление: fargred (всего исправлений: 1)
Ответ на: комментарий от true_admin

у тебя только один index.php на весь сайт или их много?

Один. Лежит в docroot.

Другими словами, во что должно преобразоваться /test/page1?

В смысле — реврайтиться? В /index.php/test/page1. По спецификации CGI всё, что после имени скрипта отправляется в PATH_INFO (см. ссылку выше). А там уже собссно PATH_INFO разбивается на аргументы и с ними идёт работа. Так и здесь.

Deleted
()
Ответ на: комментарий от Deleted

В оп-посте регулярка для реврайта длинная, чтобы матчить и /index.php/page1 тоже, попробовал с короткой для коротких URL, результат тот же

rewrite ^(/.+)$ /index.php$1 break;

Deleted
()
Ответ на: комментарий от Deleted
location / {
   try_files $uri $uri/ @fcgi;
}

location ~ ^.+\.php {
    error 404; # чтобы не скачивали скрипты

location @fcgi {
    fastcgi_pass unix:/var/run/php-fpm/default.socket;
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root/index.php;
    fastcgi_param PATH_INFO $uri;
    #хз что это fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info; 
}




true_admin ★★★★★
()
Последнее исправление: true_admin (всего исправлений: 1)
Ответ на: комментарий от true_admin

Всё это ничего не даёт.

$uri

И так известен, слеша на конце быть не может, да он и не влияет.

error 404; # чтобы не скачивали скрипты

А их что, можно просто взять и скачать? У меня нет.
$fastcgi_script_name и так знает, что он всегда index.php.
Про PATH_TRANSLATED есть всё по той же ссылке.

Deleted
()
Ответ на: комментарий от Deleted

А их что, можно просто взять и скачать?

зависит от конфига. тот что я привёл это возможно.

$fastcgi_script_name и так знает, что он всегда index.php.

у тебя не очень хорошая схема со всеми этими реврайтами и if-ами. Они не нужны. Ты хочешь выполнить два реврайта. Сначала преобразовать в /index.php$1 и потом опять преобразовать при помощи fastcgi_split_path_info.

Так работает мой конфиг или нет?

true_admin ★★★★★
()
Ответ на: комментарий от true_admin

А-а, теперь я разглядел идею. Подставить $uri целиком для PATH_INFO. Тогда try_files обретает смысл.Только теперь у меня /page1 работает как надо, а / отвалился. Он как раз выдаёт текст скрипта вместо странички. И error в моём nginx неизвестная директива.

Ты хочешь выполнить два реврайта.

Кажется, именно это я и хочу, да.

Сначала преобразовать в /index.php$1 и потом опять преобразовать при помощи fastcgi_split_path_info.

По идее как только URI обретает в себе «index.php» должна срабатывать соответствующая секция location, не? Так что по идее очерёдность хромать не должна же.

Deleted
()
Ответ на: комментарий от Deleted

В общем, пока решил это грязненько

        location / {
            rewrite ^/$ /index.php;
            try_files $uri  @fcgi;
        }

        location @fcgi {
            fastcgi_pass unix:/var/run/php-fpm/default.socket;
            include fastcgi_params;
            fastcgi_param SCRIPT_FILENAME $document_root/index.php;
            fastcgi_param PATH_INFO $uri;
            fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
        }

        location ~ ^.+\.php {
            fastcgi_pass unix:/var/run/php-fpm/default.socket;
            include fastcgi_params;
            fastcgi_split_path_info ^((?U).+\.php)(/?.+)$;
            fastcgi_param SCRIPT_FILENAME $document_root/index.php;
            fastcgi_param PATH_INFO $fastcgi_path_info;
            fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
        }

Deleted
()
Ответ на: комментарий от Deleted

И error в моём nginx неизвестная директива.

имел в виду return 404. Писал всё по-памяти, давненько я не конфигурил тпшчтп (жаргонное название nginx).

Так что по идее очерёдность хромать не должна же.

очерёдность в конфиге не играет роли, по-моему. http://nginx.org/ru/docs/http/ngx_http_core_module.html#location

Он как раз выдаёт текст скрипта вместо странички

покажи весь виртхост целиком. Я чую проблема не в том куске что я привёл. Хотя, я не эксперт в nginx, мог что попутать.

true_admin ★★★★★
()
Ответ на: комментарий от true_admin

тпшчтп (жаргонное название nginx).

А я думал это энжин-икс.

очерёдность в конфиге не играет роли, по-моему.

Синтаксически в конфиге мжду секциями не играет, ясен пень, это у меня мозга за мозгу зашла и я стал думать, а не проходит ли URL, пока реврaйтится, дважды через секцию с location php. Потом понял, что нет, потому что до реврайта php в URI отсутствовал.

покажи весь виртхост целиком.

Да это собственно он и есть. Ну плюс ещё настройка логов, root да index.

Deleted
()
Последнее исправление: fargred (всего исправлений: 1)
Ответ на: комментарий от true_admin

А что там? Не index.php случайно?

index.php

Чую, из-за него и отдаёт содержимое php-скрипта в моём варианте конфига.

Нет, это из-за $uri/. В таком виде (независимо от установленной index index.php)

        location / {
            try_files $uri @fcgi;
        }

        location @fcgi {
            fastcgi_pass unix:/var/run/php-fpm/default.socket;
            include fastcgi_params;
            fastcgi_param SCRIPT_FILENAME $document_root/index.php;
            fastcgi_param PATH_INFO $uri;
            fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
        }
nginx пропускает / и /page1 правильно, а /page1/param1 уже снова портит статику.

Решил остановиться на таком варианте, больше походит на то, что в документации

        location / {
            try_files $uri @fcgi;
        }

        location ~ ^/(index\.php|\.htaccess)$ {
            return 404;
        }

        location @fcgi {
            fastcgi_pass unix:/var/run/php-fpm/default.socket;
            include fastcgi_params;
            fastcgi_split_path_info ^(index\.php)(/?.+)$;
            fastcgi_param SCRIPT_FILENAME $document_root/index.php;
            fastcgi_param PATH_INFO $fastcgi_path_info;
            fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
        }
BTW, я пробовал сделать вот так:

        location / {
            try_files $uri index.php$uri;
        }

        location ~ ^/index\.php {
            fastcgi_pass unix:/var/run/php-fpm/default.socket;
            include fastcgi_params;
            fastcgi_split_path_info ^(index\.php)(/?.+)$;
            fastcgi_param SCRIPT_FILENAME $document_root/index.php;
            fastcgi_param PATH_INFO $fastcgi_path_info;
            fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
        }

и оно работало для всех URL и статика отдавалась, но почему в этом случае можно получить index.php в виде plain text? Он же вроде должен отдаваться на fastcgi, разве нет?

Deleted
()
Ответ на: комментарий от Deleted

Ляяяя… Проглядел.

-           fastcgi_split_path_info ^(index\.php)(/?.+)$;
-           fastcgi_param PATH_INFO $fastcgi_path_info;
+            fastcgi_param PATH_INFO $uri;
Но я не понимаю, почему конфиг не работает с fastcgi_split_path_info, которая по идее, для этого и предназначена. Если указать
try_files $uri index.php$uri
то URL==«/» будет трансформирован try_files в URI==«/index.php/», о чём свидетельствует $fastcgi_script_name в логах, равный «index.php/». Если взять более длинный URL типа /page1/param1, то
location ~ ^/index\.php {
           fastcgi_split_path_info ^(index\.php)(/?.+)$;
           fastcgi_param SCRIPT_FILENAME $document_root/index.php;
           fastcgi_param PATH_INFO $fastcgi_path_info;
…
как будто не обработает URI, потому что PATH_INFO в скрипт не попадает вообще. О, до меня дошло, что это location скорее всего не срабатывает. Та-ак…

Deleted
()
Ответ на: комментарий от true_admin

В общем, я не понимаю, как работает трансформирование в URI и окончательно запутался.

    log_format main
        '$remote_addr - $remote_user [$time_local] '
            '"$request" "$uri" "$fastcgi_script_name" $status $bytes_sent '
        '"$http_referer" "$http_user_agent" '
        '"$gzip_ratio"';
        location / {
            try_files $uri index.php$uri;
        }
        location ~ ^index.php {
# test for location match
#           rewrite ^.+$ /.htaccess permanent;
            fastcgi_pass unix:/var/run/php-fpm/default.socket;
            include fastcgi_params;
            fastcgi_split_path_info ^(index\.php)(/?.+)$;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            fastcgi_param PATH_INFO $fastcgi_path_info;
            fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
        }
127.0.0.1 - - [30/Aug/2012:08:43:02 +0400] "GET / HTTP/1.1" "index.php/" "index.php" 404 307 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:13.0) Gecko/20100101 Firefox/13.0.1" "0.44"
В error_log не попадает, и в браузер возвращается «File not found.» в виде plaintext(!), а не «404 not found» отформатированное в HTML и с подписью и версией nginx внизу.

Deleted
()
Ответ на: комментарий от Deleted

но почему в этом случае можно получить index.php в виде plain text?

потому что для php-файлы (кроме index.php) попадают в первый локейшн. Вот поэтому и надо сделать location ~ ^.+\.php

true_admin ★★★★★
()
Ответ на: комментарий от true_admin

ЯННП.

кроме index.php

Но кроме этого файла больше никаких и нет.

Deleted
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.