Nginx-ru mailing list archive (nginx-ru@sysoev.ru)
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: allow/deny and return
On 18.10.2013 16:50, Maxim Dounin wrote:
если же посмотреть со стороны пользователей - в большинстве случаев
написание конфигурации стало проще, удобнее и безглючнее, потому что
вместо фигурного выпиливания лобзиком работающей конфигурации
на основе директив if + return + error_page
+ recursive_error_pages + proxy_intercept_errors
+ fastcgi_intercept_errors + scgi_intercept_errors
+ uwsgi_intercept_errors + ...
можно взять директиву try_files с простой и понятной логикой работы,
которая подходит для большинства наиболее частоиспользуемых случаев.
Проблема в том, что "выпиливание лобзиком" - как было, так и
осталось. Только к списку директив добавилась ещё парочка,
за которыми нужно следить - try_files и alias.
Ошибки работы try_files в location с alias ведь можно исправить?
Почти всегда конфиг с директивой try_files будет проще и понятнее,
чем при использовании комбинации директив if + return + error_page
Ведь директива error_page предназначена для обработки ошибок,
когда Файл точно должен был быть, но его там вдруг не оказалось.
Исключительная ситуация, о которой записывается информация в лог
и показывается соответствующая страница с сообщением про ошибку.
try_files - это ведь директива _выбора_ location для обработки запросов,
если файл существует - используется этот location. если нет - тогда тот.
Например, что будет проще и удобнее:
location ~ \.php$ {
error_page 404 = @virtual;
log_not_found off;
if (!-f $request_filename) {
return 404;
}
fastcgi_pass ...;
}
или
location ~ \.php$ {
try_files $uri @virtual;
fastcgi_pass ...;
}
?
Отдельно печалит, что в результате конфигурации с error_page 404
@fallback - практически исчезли, хотя аналог на try_files -
гарантированно хуже.
Аналог на try_files будет "гарантированно хуже" только в том случае,
когда для обработки запросов используется модуль static. Если другой
content handler (fastcgi_pass, proxy_pass и т.п.) - try_files лучше.
Даже в том случае, когда content handler`ом будет модуль static:
С точки зрения производительности - да, это будет чуть-чуть хуже,
один лишний syscall и маловероятная возможность "race condition".
Но с точки зрения простоты написания / сопровождения конфига -
директива try_files и в этом случае будет лучше чем error_page.
"Programs must be written for people to read,
and only incidentally for machines to execute" - Hal Abelson
- по сути nginx.conf - это программа для интерпретатора /usr/sbin/nginx
"Предпочтение простоте заложено в нашей ДНК и это вряд ли изменится
в течение нескольких миллиардов лет. ...при наличие выбора, человек
всегда выберет более простой путь." - цитата из книги Кена Сигалла
"Безумно просто. Вдохновляющие примеры Apple".
потому и пропали конфигурации с error_page 404 @fallback,
- появился более простой и более удобный вариант try_files.
P.S.
Кстати, при желании можно устранить все недостатки try_files.
try_files - это синтаксический сахар для if, return и error_page -
следовательно в процессе парсинга конфига можно транслировать директиву
try_files "высокого уровня" в набор директив "низкого уровня", которые
и будут реально исполняться nginx через ngx_http_core_try_files_phase.
например, такой фрагмент конфига:
location ... {
error_page 404 /404.html;
try_files $uri @virtual;
# static module handler;
}
всегда будет игнорировать "лишнюю" директиву error_page 404,
поэтому try_files можно развернуть в error_page 404 = @virtual;
и log_not_found off; вообще без ngx_http_core_try_files_phase.
фрагмент конфига
location ~ \.php$ {
try_files $uri @virtual;
fastcgi_pass ...;
}
можно развернуть в
location ~ \.php$ {
if (!-f $request_filename) {
internal_redirect @virtual; # это на уровне байт-кода rewrite
}
fastcgi_pass ...;
}
поскольку сгенерированная из try_files и невидимая пользователю
директива if будет работать на NGX_HTTP_TRY_FILES_PHASE, после access
- поведение конфига 100% соответствовать существующей сейчас
документации на директиву try_files.
Если я ничего не путаю, любую директиву try_files
можно транслировать в произвольную комбинацию директив
if + return + error_page, возможно с дополнительными location`ами.
Тогда нельзя будет сказать с точки зрения реализации,
что "аналог на try_files - гарантированно хуже", потому что
try_files будет идентичен аналогу на if, и даже будет лучше if,
потому что try_files работает после прохождения access-проверок.
А с точки зрения пользователя - try_files практически всегда
будет лучше, потому что это более простая и понятная директива.
--
Best regards,
Gena
_______________________________________________
nginx-ru mailing list
nginx-ru@xxxxxxxxx
http://mailman.nginx.org/mailman/listinfo/nginx-ru
|