captures in regex location
Igor Sysoev
is at rambler-co.ru
Fri Mar 6 09:48:13 MSK 2009
On Fri, Mar 06, 2009 at 01:22:30AM +0300, Vladimir Sopot wrote:
> Хотелось бы, как раз, сохранить текущий порядок: проверка
> существования файла переписывает URI в "старый" формат, "когда
> компьютеры были большими" и адресация на сайте была несколько другая
> (при этом файла вообще может и не существовать). А тем, которые EN,
> уже однозначно подсовывается новый формат и посылается вдаль, туда,
> где о старом варианте ничего не знают.
>
> А в чем вообще прелесть "новых технологий" и location ~* upic\.jpg$ {}
> (ну и location ~* "^(................)$" {})?
Новые технологии - это captures в locations.
Что касается location ~* upic\.jpg$ {}, то вот это
location / {
...
}
location ~* upic\.jpg$ {
...
}
всегда было правильным методом в отличие от:
location / {
if ($request_uri ~* upic.jpg) {
break;
}
}
Правило такое - $request_uri и "$request_file_name ~" в if означает, что
это неправильно, так для этих вещей специально были сделаны оптимизированные
locations.
> On Mar 6, 2009, at 12:32 AM, Igor Sysoev wrote:
>
> >On Fri, Mar 06, 2009 at 12:15:28AM +0300, Vladimir Sopot wrote:
> >
> >>
> >>On Mar 5, 2009, at 11:37 PM, Igor Sysoev wrote:
> >>
> >>>On Thu, Mar 05, 2009 at 11:30:14PM +0300, Vladimir Sopot wrote:
> >>>
> >>>>А-ха!
> >>>>
> >>>>В моем if-е подразумевался break, чтобы больше условий (типа
> >>>>проверки
> >>>>географии и пр.) в этом server-е не выполнялось. Что должно быть
> >>>>внутри нового location-а для того же функционала?
> >>>
> >>>Как выглядят if'ы ?
> >>
> >>Наверняка, что-то не так с last-break, но работает :)
> >>
> >> if ($request_uri ~* upic.jpg) {
> >> break;
> >> }
> >>
> >> if (!-f $request_filename) {
> >> rewrite "^(................)$" http://$2$3$4 last;
> >> return 404;
> >> }
> >>
> >> if ($country = EN) {
> >> rewrite (.*) http://somewhere.com$1 break;
> >> }
> >
> >location ~* upic\.jpg$ {
> > ...
> >}
> >
> >location ~* "^(................)$" {
> >
> > if ($country = EN) {
> > rewrite ^ http://somewhere.com$request_uri?;
> > }
> >
> > error_page 404 http://$2$3$4;
> >}
> >
> >Только в этом случае "if ($country = EN)" будет выполняться до
> >проверки
> >существования файла.
> >
> >А ещё можно сделать так:
> >
> >server_name ~^([bos])(\d)p\.site;
> >
> > set $root /wwwroot/site/$2/$1/;
> > root $root;
> >}
> >
> >Но
> >
> > if ($request_uri ~* upic.jpg) {
> > break;
> > }
> >
> >нужно однозначно менять на
> >
> > location ~* upic\.jpg$ {
> > ...
> > }
> >
> >>>>On Mar 5, 2009, at 10:43 PM, Igor Sysoev wrote:
> >>>>
> >>>>>On Thu, Mar 05, 2009 at 10:34:51PM +0300, Vladimir Sopot wrote:
> >>>>>
> >>>>>>Mot*^&@W$ ;".%($ :^?:(;!
> >>>>>>
> >>>>>>Спасибо, действительно, надо обращать больше внимания на имена
> >>>>>>файлов
> >>>>>>и места сохранения аттачей.
> >>>>>>
> >>>>>>Но всплыл другой непонятный "фич" -
> >>>>>>
> >>>>>>server {
> >>>>>> server_name ~^([bos])(\d)p\.site;
> >>>>>> root /wwwroot/site/$2/$1/;
> >>>>>> }
> >>>>>>
> >>>>>>работает отлично. Но как только внутри, после root ... появляется
> >>>>>>
> >>>>>> if ($request_uri ~* upic.jpg) {
> >>>>>> # не важно что, хотя бы даже пустота
> >>>>>> }
> >>>>>>
> >>>>>>всё снова ломается :(
> >>>>>
> >>>>>regex в if/rewrite меняют captures, даже если они не сработали.
> >>>>>Несовпавший location regex не трогает captures. Поэтому нужно
> >>>>>переходить
> >>>>>на прогрессивные технологии:
> >>>>>
> >>>>>location ~* upic\.jpg {
> >>>>>...
> >>>>>}
> >>>>>
> >>>>>>P.S. спасибо за ненужную "|" :)
> >>>>>>
> >>>>>>On Mar 5, 2009, at 6:56 PM, Igor Sysoev wrote:
> >>>>>>
> >>>>>>>On Thu, Mar 05, 2009 at 06:46:03PM +0300, Vladimir Sopot wrote:
> >>>>>>>
> >>>>>>>>В эту сторону я уже думал и на такой location - ругается, да.
> >>>>>>>>
> >>>>>>>>Но патч вроде ложится -
> >>>>>>>>
> >>>>>>>>nginx-0.7.39/src/http # patch -p2 <patch.location_captures
> >>>>>>>
> >>>>>>>Это первый патч, нужен patch.location_captures1
> >>>>>>>
> >>>>>>>>patching file ngx_http_core_module.c
> >>>>>>>>patching file ngx_http_request.h
> >>>>>>>>patching file ngx_http_script.c
> >>>>>>>>patching file ngx_http_script.h
> >>>>>>>>patching file modules/ngx_http_rewrite_module.c
> >>>>>>>>
> >>>>>>>>и objs/nginx получается другого размера, если без патча.
> >>>>>>>>
> >>>>>>>>On Mar 5, 2009, at 5:30 PM, Igor Sysoev wrote:
> >>>>>>>>
> >>>>>>>>>On Thu, Mar 05, 2009 at 05:22:43PM +0300, Vladimir Sopot
> >>>>>>>>>wrote:
> >>>>>>>>>
> >>>>>>>>>>Увы,
> >>>>>>>>>>
> >>>>>>>>>>2009/03/05 16:54:16 [error] 18720#0: *5440 open() "/wwwroot/
> >>>>>>>>>>site///e/
> >>>>>>>>>>ea/0/12720.jpg" failed (2: No such file or directory),
> >>>>>>>>>>client: 94.188.35.148, server: ~^(s)(\d)\.site, request:
> >>>>>>>>>>"GET /e/
> >>>>>>>>>>ea/
> >>>>>>>>>>0/12720.jpg HTTP/1.1", host: "s0.site", referrer:
> >>>>>>>>>>"http://site/ea/12720.html"
> >>>>>>>>>>
> >>>>>>>>>>Тоесть сервер точно матчится, но вот $1-2 не
> >>>>>>>>>>устанавливаются :(
> >>>>>>>>>>
> >>>>>>>>>>Куда бы еще копнуть? Уж больно хочется и конфиг порезать и на
> >>>>>>>>>>регекспах сэкономить :)
> >>>>>>>>>
> >>>>>>>>>А патч точно приложен ?
> >>>>>>>>>Что показывает nginx, если в конфиг добавить такое:
> >>>>>>>>>
> >>>>>>>>>location ~ \.TXT$ {
> >>>>>>>>>alias /wwwroot/;
> >>>>>>>>>}
> >>>>>>>>>
> >>>>>>>>>?
> >>>>>>>>>
> >>>>>>>>>># uname -a
> >>>>>>>>>>Linux site 2.6.27.7-9-default #1 SMP 2008-12-04 18:10:04
> >>>>>>>>>>+0100
> >>>>>>>>>>x86_64
> >>>>>>>>>>x86_64 x86_64 GNU/Linux
> >>>>>>>>>>
> >>>>>>>>>># ./configure \
> >>>>>>>>>>--with-http_stub_status_module \
> >>>>>>>>>>--without-mail_pop3_module \
> >>>>>>>>>>--without-mail_imap_module \
> >>>>>>>>>>--without-mail_smtp_module \
> >>>>>>>>>>--without-http_access_module \
> >>>>>>>>>>--without-http_autoindex_module \
> >>>>>>>>>>--without-http_browser_module \
> >>>>>>>>>>--without-http_charset_module \
> >>>>>>>>>>--without-http_limit_zone_module \
> >>>>>>>>>>--without-http_map_module \
> >>>>>>>>>>--without-http_memcached_module \
> >>>>>>>>>>--without-http_referer_module \
> >>>>>>>>>>--without-http_ssi_module \
> >>>>>>>>>>--without-http_userid_module \
> >>>>>>>>>>--without-http_proxy_module \
> >>>>>>>>>>--without-http_proxy_module
> >>>>>>>>>>...........
> >>>>>>>>>>checking for PCRE library ... found
> >>>>>>>>>>...........
> >>>>>>>>>>Configuration summary
> >>>>>>>>>>+ using system PCRE library
> >>>>>>>>>>...........
> >>>>>>>>>># pcre-config --version
> >>>>>>>>>>7.8
> >>>>>>>>>>
> >>>>>>>>>>On Mar 5, 2009, at 4:14 PM, Igor Sysoev wrote:
> >>>>>>>>>>
> >>>>>>>>>>>On Thu, Mar 05, 2009 at 03:46:55PM +0300, Vladimir Sopot
> >>>>>>>>>>>wrote:
> >>>>>>>>>>>
> >>>>>>>>>>>>Помимо описанного сервера есть еще секции
> >>>>>>>>>>>>
> >>>>>>>>>>>>server {
> >>>>>>>>>>>>server_name ~^([b|o])(\d)\.site;
> >>>>>>>>>>>> .......
> >>>>>>>>>>>> }
> >>>>>>>>>>>>
> >>>>>>>>>>>>server {
> >>>>>>>>>>>>listen *:80 default bind sndbuf=64k;
> >>>>>>>>>>>>server_name site
> >>>>>>>>>>>> ..........
> >>>>>>>>>>>> }
> >>>>>>>>>>>>
> >>>>>>>>>>>>и добавление пустого сервера не исправило ситуацию.
> >>>>>>>>>>>
> >>>>>>>>>>>У меня для
> >>>>>>>>>>>
> >>>>>>>>>>>server {
> >>>>>>>>>>>listen 8000;
> >>>>>>>>>>>server_name ~^([b|o])(\d)z\.site;
> >>>>>>>>>>>
> >>>>>>>>>>>root /wwwroot/site/$1/$2/;
> >>>>>>>>>>>}
> >>>>>>>>>>>
> >>>>>>>>>>>в логах такая ошибка:
> >>>>>>>>>>>
> >>>>>>>>>>>[error] 58504#0: *1 open() "/wwwroot/site/b/1/dir/
> >>>>>>>>>>>index.html"
> >>>>>>>>>>>failed
> >>>>>>>>>>>(2: No such file or directory), client: 127.0.0.1, server:
> >>>>>>>>>>>~^([b|
> >>>>>>>>>>>o])
> >>>>>>>>>>>(\d)z\.site, request: "GET /dir/index.html HTTP/1.0", host:
> >>>>>>>>>>>"b1z.site"
> >>>>>>>>>>>
> >>>>>>>>>>>То есть, путь "/wwwroot/site/b/1/dir/index.html" формиурется
> >>>>>>>>>>>правильно.
> >>>>>>>>>>>
> >>>>>>>>>>>Кстати, "|" в "([b|o])" - лишняя.
> >>>>>>>>>>>
> >>>>>>>>>>>>On Mar 5, 2009, at 2:43 PM, Igor Sysoev wrote:
> >>>>>>>>>>>>
> >>>>>>>>>>>>>On Thu, Mar 05, 2009 at 01:57:49PM +0300, Vladimir Sopot
> >>>>>>>>>>>>>wrote:
> >>>>>>>>>>>>>
> >>>>>>>>>>>>>>Спасибо, но что-то оно не того
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>>>server {
> >>>>>>>>>>>>>>server_name ~^([b|o])(\d)z\.site;
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>>># if ($host ~* (.)(\d)) {
> >>>>>>>>>>>>>>set $store_type $1;
> >>>>>>>>>>>>>>set $store_id $2;
> >>>>>>>>>>>>>># }
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>>>root /wwwroot/site/$store_id/$store_type/;
> >>>>>>>>>>>>>>}
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>>>В таком виде не работает (404), если убрать комментарии -
> >>>>>>>>>>>>>>все
> >>>>>>>>>>>>>>становится на свои места. Забрать root внутрь location /
> >>>>>>>>>>>>>>{ }
> >>>>>>>>>>>>>>тоже
> >>>>>>>>>>>>>>ничего не дает. root /wwwroot/site/$2/$1/ тоже не
> >>>>>>>>>>>>>>работает
> >>>>>>>>>>>>>
> >>>>>>>>>>>>>Скорее всего, regex вообще не исполняется, потому что
> >>>>>>>>>>>>>сервер
> >>>>>>>>>>>>>один -
> >>>>>>>>>>>>>проверять нечего. Нужно добавить пустой сервер, чтобы
> >>>>>>>>>>>>>nginx
> >>>>>>>>>>>>>начал
> >>>>>>>>>>>>>проверять
> >>>>>>>>>>>>>server_name:
> >>>>>>>>>>>>>
> >>>>>>>>>>>>>server { server_name _; }
> >>>>>>>>>>>>>
> >>>>>>>>>>>>>>On Mar 5, 2009, at 1:17 PM, Igor Sysoev wrote:
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>On Thu, Mar 05, 2009 at 12:14:55PM +0200, Andrew
> >>>>>>>>>>>>>>>Sitnikov
> >>>>>>>>>>>>>>>wrote:
> >>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>>>А можно такое же ещё и для server_name?
> >>>>>>>>>>>>>>>>IS> Новый патч с поддержкой server_name.
> >>>>>>>>>>>>>>>>можно пример ?
> >>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>Наверное, как-то так:
> >>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>server {
> >>>>>>>>>>>>>>>listen 8000;
> >>>>>>>>>>>>>>>server_name ~^(?:www\.)?(.+)$;
> >>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>location / {
> >>>>>>>>>>>>>>>root /path/to/$1;
> >>>>>>>>>>>>>>>}
> >>>>>>>>>>>>>>>}
> >>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>--
> >>>>>>>>>>>>>>>Игорь Сысоев
> >>>>>>>>>>>>>>>http://sysoev.ru
> >>>>>>
> >>>>>
> >>>>>--
> >>>>>Игорь Сысоев
> >>>>>http://sysoev.ru
> >>>>>
> >>>>>
> >>>>
> >>>
> >>>--
> >>>Игорь Сысоев
> >>>http://sysoev.ru
> >>>
> >>>
> >>
> >
> >--
> >Игорь Сысоев
> >http://sysoev.ru
> >
> >
>
--
Игорь Сысоев
http://sysoev.ru
More information about the nginx-ru
mailing list