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