Nginx, regex-домены, "root /your/app/$1/htdocs"

Maxim Dounin mdounin at mdounin.ru
Fri Nov 6 15:57:43 MSK 2009


Hello!

On Fri, Nov 06, 2009 at 02:16:11PM +0300, Dmitry Koterov wrote:

> Т.е. $1 заменяется на значение не в тот момент, когда он встречается в
> переменной, а в самый последний, когда переменная вставляется в ту или иную
> директиву?

Все переменные (и $1 не исключение) подставляются в тот момент, 
когда строка содержащая переменные реально используется.

> Я ожидал, что в конструкции
> 
> set $docroot /your/app/$1/htdocs;
> 
> в $docroot попадет уже ОКОНЧАТЕЛЬНАЯ строка, в которой нет упоминаний $1 и
> т.д... Аналогично, что в

Да, попадёт.  Когда отработает соответствующий set.  Это случится 
где-то в районе фазы серверных rewrite'ов (если set на уровне 
server{}).

Шутка состоит в том, что эта самая фаза - выполняется повторно при 
очередном поиске совпадения между uri и location (после rewrite ... 
last).  И там снова отрабатывает set.  И заново ставит $docroot, 
но на этот раз в $1 уже может быть совсем не то что ожидалось.

> root /your/app/$1/htdocs
> 
> директиве root будет скормлена уже интерполированная строка, без информации
> о $1.

Директиве root что-либо "кормится" на этапе парсинга конфига, и $1 
(а равно и других переменных) там нет вообще.  Так что 
интерполяция происходит непосредственно перед использованием, т.е. 
в тот момент когда uri будет преобразовываться в путь на файловой 
системе.

Maxim Dounin

> 
> 
> 2009/11/6 Maxim Dounin <mdounin at mdounin.ru>
> 
> > Hello!
> >
> > On Fri, Nov 06, 2009 at 01:08:21PM +0300, Dmitry Koterov wrote:
> >
> > > Похоже на баг.
> > > nginx/0.7.62
> > >
> > > Я обнаружил, что связка вот таких директив не работает (fastcgi_php не
> > > срабатывает):
> > >
> > > server_name ~^([a-z0-9]+)\.example\.com$
> > > root /your/app/$1/htdocs
> > > fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
> > >
> > > А вот такие, по смыслу, казалось бы, идентичные, - работают:
> > >
> > > server_name ~^([a-z0-9]+)\.example\.com$
> > > set $docroot /your/app/$1/htdocs;
> > > root $docroot;
> > > fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
> > >
> > > Видимо, если в root содержатся regexp-маркеры (типа $1), они неправильно
> > > обрабатываются в $document_root, в итоге fastcgi_param не срабатывает.
> >
> > $1 - это capture от последнего выполнившегося регекспа.  Если по
> > дороге от матчинга server_name до fastcgi_pass случится хотя бы
> > один regexp (e.g. regexp location, причём не обязательно
> > совпавший) - первая конфигруация ожидаемо сломается.
> >
> > А вторая конфигурация сломается если случится регексп и внутренний
> > редирект с повторным поиском совпавшего location'а (e.g. regexp
> > location + rewrite ... last).
> >
> > Maxim Dounin
> >
> >





More information about the nginx-ru mailing list