index internal redirect

Gena Makhomed gmm на csdoc.com
Вс Июн 19 23:19:29 MSD 2011


On 19.06.2011 20:25, Валентин Бартенев wrote:

>> "инвертируя результат проверки" - это как, - использовать
>> для обработки запроса не-найденный и не-существующий файл?
>
> Я напомню, изначально задача была поставлена такая: "делать внутренний
> редирект при нахождении файла (как сейчас делается для index)".
>
> try_files  !$uri  @php;
>
> Эту задачу решает. Если файл будет найден, то произойдет обработка в @php.
> Если нет, то запрос будет обработан в текущем локейшене.

изначально задача несколько иная ставилась, насколько я понял.
если $uri равно /index.html - то директива try_files должна делать
внутренний редирект в location, которому соответствует /index.html
так работает директива index - делает вот такой внутренний редирект.

сейчас директива try_files никогда не делает врутренних редиректов,
если файл существует, а просто обрабатывает его в текущем локейшине.

и эта обработка, насколько я понимаю может быть только двух видов -
или отдача файла как статики, или отправка на proxy/fastcgi/uwsgi/...

>> а если этого файла нет:
>>
>> try_files  !$uri  @php;
>>
>> то где произойдет обработка, разве не в том же самом location @php ?
>
> Гм. Если бы было написано  try_files  $uri  @php;
> то произошла бы в "том же самом location @php "
> а поскольку ! изменяет результат проверки на обратный, и произойдет в текущем.

если файла нет, как же тогда директива try_files сможет обработать
его в текущем локейшине? обрабатывать-то нечего, файл не существует.

чем плохо использовать символ ! давая ему новый смысл.
в nginx уже есть mod_rewrite, в этом модуле есть if,
и для этого if`а символ ! означает логическую операцию
отрицания, как и в языке программирования С.

если в одном месте конфига ! означает логический оператор,
а в другом месте конфига, совсем рядом ! имеет совсем другой
смысл, то из-за таких частых переключений контекста чтение
и понимание такого конфига человеком значительно замедляются.

например, в С оператор ! имеет только один смысл.
оператор * имеет два смысла и это слегка запутывает новичков,
хотя в одном случае * - это унарный оператор, а во втором бинарный,
и отличить их один от другого достаточно легко по количеству операндов.

здесь же - предлагается двумя разными смыслами перегружать
один и тот же унарный оператор, в зависимости от контекста.

>> http://www.lexa.ru/nginx-ru/msg34942.html
>
> Я не увидел в примере по ссылке ничего схожего с моим предложением.
>
> Мое (особенно второе, с использованием @) решение задачи не предполагает
> введение каких-либо новых значков и обозначений, а лишь расширяет возможности
> применение уже существующих, привычных.
>
> Не надо из крайности в крайность бросаться, и говорить, что все, что
> использует односимвольные значки сразу уже становится похожим на sendmail.

не сразу становится похожим, но это уже движение в том направлении.
сейчас вводим символ ! через несколько месяцев захочется добавить
в try_files еще какой-то модификатор, будем использовать символы
% ^ & * + [ ] и конфиг тогда будет гораздо труднее читать и понимать.

а после того, как добавятся ! % ^ & * - выбросить их уже будет нельзя,
чтобы не сломать обратную совместимость с существующими конфигурациями.

и новую функциональность к try_files будет добавить тоже очень трудно, 
потому что количество спецсимволов ограничено,
и рано или поздно они все просто закончатся.

да еще эти спецсимволы будут в разных местах конфига
иметь совершенно различный смысл, в зависимости от контекста.

> sendmail-фобия также опасна и деструктивна, как и sendmail-филия.

можете ли привести пример, когда "sendmail-фобия"
приводила к каким-то опасным и деструктивным последствиям.

если на одном полюсе поставить конфиги сендмейла,
то очень близко к другому полюсу будет язык python,
с очень чистым, ясным, простым, но тем не менее,
очень выразительным синтаксисом. так же рядом будут
конфиги haproxy и squid`а, хотя и там и там достаточно
много директив и есть достаточно мощные выражения через acl.

пока что все увиденные мой примеры не показывают какого-либо
вреда от того, что разработчики при дизайне языка держались
подальше от синтаксиса sendmail`а, apache mod_rewrite и т.п.

>> если не понимать синтаксиса этого модификатора,
>> то разумеется, что это будет страшнее и непонятнее.
>> (хотя вчера/сегодня я детально расписал его семантику)
>>
>> да, длиннее, зато не страдает читабельность конфига.
>> у сендмейла вот сократили все по максимуму 1 символ == 1 опция.
>> только вот что-то очень мало желающих поддерживать такие конфиги.

> Зачем вводить какие-то новые операторы на вроде "::"

это не оператор. эта последовательность символов предлагается
использовать для того, чтобы можно было задавать модификатор.

internal_redirect:: или internal_redirect( куда_именно )::

сами по себе :: в конфиге и внутри try_files, без задания
модификатора - это будет просто синтаксическая ошибка.

> и придумывать кучу новых ключевых слов, плодить сущности?

не согласен. у нас уже есть сущность, называется "внутренний редирект".
но имени для этой сущности нет. и чтобы можно было называть вещи своими
именами я и предлагаю модификатор для try_files, который будет делать
операцию "внутренний редирект" так и назвать - internal_redirect::

аналогично и с модификатором, который позволит задать абсолютное имя
файла. сущность уже есть, а имени для этой сущности пока что еще нет.

Бритва Оккама, откуда и взята часть вышеприведенной фразы звучит так:

«Не следует множить сущее без необходимости» (либо «Не следует 
привлекать новые сущности без самой крайней на то необходимости»). Этот 
принцип формирует базис методологического редукционизма, также 
называемый принципом бережливости, или законом экономии.

так вот в данном случае, такая крайняя необходимость есть.
альтернативный вариант (использовать спецсимволы % ^ & * и т.п.)
- будет гораздо хуже, чем создание явных имен для сущностей -
двух новых модификаторов директивы try_files.

> А потом всех призывать изучать этот новый синтаксис,

нет, только тех, кому нужно будет работать с этими новыми сущностями.
кому эти новые features не нужны - у них все будет работать как и раньше.

если добавлять новые *зависимые от контекста* семантические значения
для хорошо известного унарного оператора '!' - это разве будет лучше?

> на описание которого у вас ушло аж несколько длиннющих писем в этой
> же ветке ниже.

письма получились длинными потому что русский язык для меня не родной,
я его только учил в школе. для кого русский язык родной - наверное
- смогли бы то же самое выразить более кратко и более понятно чем я.

> И уж что-что, а длинна и громоздкость - читабельности не способствует.

тоже не согласен. два примера: язык perl и язык python.

perl - очень сжатый и очень краткий, мощный и очень выразительный 
синтаксис. но чтобы прочитать и понято потом исходник на perl`е -
потребуется достаточно много времени и сил. временами я даже свои
собственные исходники не сразу могу понять. вот, например:

  my $host = $r->header_in( 'Host' ) || '';
         my $name = join( '.', map { if( /^xn--(.*)$/ ) { 
decode_punycode( $1 ) } else { $_ } } split( /\./, $host ) );

python - язык с большим количеством ключевых слов и с минимальным
использванием спецсимволов, можно сказать, длинна и громоздкость
во всей красе. но вместе с тем, программы на python`е очень легко
читаются, даже если их писал совсем другой человек и в другом стиле.
и основной упор там желается не на синтаксисе, а на хорошо продуманном
дизайне языка программирования с отлично продуманной объектной моделью.
в результате на python`е пишутеся очень большие и высококачественные,
высокопроизводительные системы, которых или вообще невозможно,
или очень трудно создать на языке программирования perl.
например: hg, SQLAlchemy, Werkzeug и т.д. и т.п.
подробнее: http://www.python.org/about/success/

или вот в Red Hat Enterprise Linux / CentOS -
и сам инсталятор Anaconda и менеджер пакетов yum
и плагины к нему и большое количество софта -
написаны именно на python`е. а perl - даже из состава
базовой системы FreeBSD вынесли еще много лет тому назад.

> Ну и сколько нового кода надо добавить, чтобы "распарсить" все возможные
> случаи записи:
>   internal_redirect( @dir_list )::$uri/
>   internal_redirect(@dir_list)::$uri/
>   internal_redirect (@dir_list)::$uri/
>   internal_redirect(@dir_list) :: $uri/
> или нет, так нельзя?

программы или конфиги пишутся таким образом, чтобы их могли читать
сразу два парсера - и человек и машина. если мы будем оптимизировать
синтаксис конфигурационного файла для облегчения его чтения машиной,
то мы действительно сможем сэкономить несколько тысяч, или даже 
миллионов тактов машинных инструкций. и процессор выделит меньше
тепла и nginx сможет запуститься на 0.0001 секунды быстрее.

только вот кроме машины эти конфиги читает еще и человек -
системный администратор. причем читает он их гораздо чаще,
чем пишет/правит/создает. и ухудшение читабельности конфига
для человека будет означать потерю им дополнительных секунд
и минут на процесс понимания смысла им написанного в конфиге.

может быть лучше все-таки экономить время человека, а не машины?

> Вы предлагаете введение абсолютно новой сущности, новой синтаксической
> конструкции, ранее нигде не используемой, и ни на что не похожей.

просто процитирую здесь фрагмент своего другого сообщения:

===========================================================================

на русском языке:

"... сделать внутренний редирект в локейшн @maintenance
если существует файл /system/maintenance.status ..."

на языке конфига nginx:

try_files internal_redirect( @maintenance )::/system/maintenance.status
           $uri
           $uri/
           @backend
           ;

===========================================================================

и вот такой второй вариант:

try_files /system/maintenance.status at maintenance $uri $uri/ @backend;

в плане легкости парсинга конфига человеком и перевода с языка конфига 
nginx`а на русский язык мой вариант мне кажется лучшим, хотя бы потому,
что человек на то чтобы понять и прочитать мой вариант конфига потратит
гораздо меньше времени чем он будет тратить попытавшись распарсить
этот сжатый, краткий и очень нечитабельный вариант синтаксиса.

хотя для машинного парсера конфига второй вариант будет проще и легче.

...

> Я уж молчу, про то, сколько опечаток можно сделать набирая по многу раз:
> internal_redirect( @dir_list )::$uri/

а зачем одно и то же набирать по многу раз?

> и о том, что вообще-то так строчки переносить не принято,

никто не запрещал. и конфиги nginx и конфиги postfix`а можно так писать.

> тогда уж совсем, превратите try_files в блочную директиву и пишите:
>
>   try_files {
> 	internal_redirect( @php )::$uri
> 	internal_redirect( @dir_list )::$uri/
> 	=404
> }
>
> хоть чуть-чуть красивее будет.

не вижу в этом никакой особой красоты.

>> try_files  $uri.php at php =404;
>>
>> сплошнойтекстбезпробеловплохочитается.
>
> Сплошной текст без пробелов:

> nginx-ru at nginx.org

это не "текст без пробелов", а служебная информация.
точно такая же, как и например, IP адрес 11.22.33.44

кроме того, nginx-ru at nginx.org - это есть одна сущность,
электронный почтовый адрес, которая не делится на части.

а $uri.php at php - это есть целая синтаксическая конструкция,
состоящая из двух совершенно разных компонентов и составного оператора,
который можно условно назвать "оператор-отсутствие-пробельного-символа".
смысл этой трудночитаемой синтаксической конструкции "$uri.php at php"
будет примерно таким, если перевести его на человеческий язык:

if( os.path.exists( os.path.join( $document_root, $uri.php ) ) )
{
     nginx.internal_redirect( @php )
}
else
{
     ...
}

и такими темпами очень легко будет превратить nginx в sendmail
если, разумеется, спецсимволы % ^ & * [ ] не закончатся раньше.

> http://lib.ru/SENDMAIL/sendmail_cf.txt
>
> /home/vbart/Development/Nginx/ngx-ctpp2

в путях и урлах символ '/' играет роль разделителя слов.

> internal_redirect

в языке программирования С символ '_'
в идентификаторах играет ту же самую роль,
что и пробелы в письменном русском языке.

поэтому идентификатор

internal_redirect

читается очень легко, а вот

internalredirect

- это уже трудночитаемый набор символов, и двух слов тут не видно.

и даже есть научное объяснение, почему так происходит:

======================================================================

По рзелульаттам илссеовадний одонго анлигйсокго унвиертисета, не иеемт 
занчнеия, в кокам пряокде рсапожолена бкувы в солве. Галвоне, чотбы 
преавя и пслоендяя бквуы блыи на мсете. Осатьлыне бкувы мгоут селдовтаь 
в плоонм бсепордяке, все-рвано ткест чтаитсея без побрелм. Пичрионй 
эгото ялвятеся то, что мы не чиатем кдаужю бкуву по отдльенотси, а все 
солво цликеом.

======================================================================

и вот именно поэтому, если не будет нормальных пробелов между словами -
то читать и воспринимать такой "текст" человеку будет гораздо труднее.

этоможнолегкопроверитьсамостоятельнопрактическиналюбомфрагментетекста

-- 
Best regards,
  Gena




Подробная информация о списке рассылки nginx-ru