ПРОЕКТЫ 


  АРХИВ 


Apache-Talk @lexa.ru 

Inet-Admins @info.east.ru 

Filmscanners @halftone.co.uk 

Security-alerts @yandex-team.ru 

nginx-ru @sysoev.ru 


  СТАТЬИ 


  ПЕРСОНАЛЬНОЕ 


  ПРОГРАММЫ 



ПИШИТЕ
ПИСЬМА












     АРХИВ :: nginx-ru
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


 




Copyright © Lexa Software, 1996-2009.