<div dir="ltr">Ошибся с переменной в псевдокоде. Обновленный:<div><br></div><div><div><font face="monospace, monospace">http {</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">  server {</font></div><div><font face="monospace, monospace">   </font></div><div><font face="monospace, monospace">    location ... {</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">      perl '</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">        sub {</font></div><div><font face="monospace, monospace">          $r_shop_id = $r->has_request_body(\&process_body)</font></div><div><font face="monospace, monospace">          // Как-то установить переменную $request_shop_id в значение $r_shop_id, </font></div><div><font face="monospace, monospace">          // чтобы было доступно в конфиге NGINX</font></div><div><font face="monospace, monospace">        }</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">        sub process_body {</font></div><div><font face="monospace, monospace">          $r = shift;</font></div><div><font face="monospace, monospace">          if( $r->request_body ~= /shop_id=([a-z0-9]+)/) {</font></div><div><font face="monospace, monospace">            return "$1";</font></div><div><font face="monospace, monospace">          }</font></div><div><font face="monospace, monospace">          return "";</font></div><div><font face="monospace, monospace">        }</font></div><div><font face="monospace, monospace">      ';</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">      # Тут просто используем переменную $api_shard как-то так</font></div><div><font face="monospace, monospace">      proxy_set_header ShardID $api_shard;</font></div><div><font face="monospace, monospace">      proxy_pass <a href="http://backend">http://backend</a>;</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">    }</font></div><div><font face="monospace, monospace">  }</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">  map $request_shop_id $api_shard {</font></div><div><font face="monospace, monospace">    include /home/user/nginx_mapping.conf;</font></div><div><font face="monospace, monospace">  }</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">}</font></div></div></div><div class="gmail_extra"><br><div class="gmail_quote">2015-07-15 15:07 GMT+03:00 Michael Kechinov <span dir="ltr"><<a href="mailto:sam@mkechinov.ru" target="_blank">sam@mkechinov.ru</a>></span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Правильно понимаю, что в этом случае будет происходить следующее:<div><br></div><div>В момент, когда считывается весь body срабатывает callback, в который передается этот body.</div><div>В callback'е мы получаем значение нужного аргумента (shop_id), устанавливаем это значение в переменную $request_shop_id, доступную в NGINX (кстати, не нашел, как установить в PERL'е переменную, которая будет доступна далее в конфиге NGINX'а - нашел только $r->variable, но оно просто передает переменную между sub'ами).</div><div>Далее в секции location обращаюсь к переменной $api_shard, на нее срабатывает map, который поместит значение, связанное со значением $request_shop_id.</div><div>То есть на момент обращения к $api_shard у меня гарантировано будет загружен body. Так?</div><div><br></div><div><br></div><div>Псевдо-код</div><div><br></div><div><div><font face="monospace, monospace">http {</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">  server {</font></div><div><font face="monospace, monospace">   </font></div><div><font face="monospace, monospace">    location ... {</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">      perl '</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">        sub {</font></div><div><font face="monospace, monospace">          $r_shop_id = $r->has_request_body(\&process_body)</font></div><div><font face="monospace, monospace">          // Как-то установить переменную $request_shop_id в значение $r_shop_id, </font></div><div><font face="monospace, monospace">          // чтобы было доступно в конфиге NGINX</font></div><div><font face="monospace, monospace">        }</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">        sub process_body {</font></div><div><font face="monospace, monospace">          $r = shift;</font></div><div><font face="monospace, monospace">          if( $r->request_body ~= /shop_id=([a-z0-9]+)/) {</font></div><div><font face="monospace, monospace">            return "$1";</font></div><div><font face="monospace, monospace">          }</font></div><div><font face="monospace, monospace">          return "";</font></div><div><font face="monospace, monospace">        }</font></div><div><font face="monospace, monospace">      ';</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">      # Тут просто используем переменную $api_shard как-то так</font></div><div><font face="monospace, monospace">      proxy_set_header ShardID $api_shard;</font></div><div><font face="monospace, monospace">      proxy_pass <a href="http://backend" target="_blank">http://backend</a>;</font></div><span class=""><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">    }</font></div><div><font face="monospace, monospace">  }</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">  map $arg_code $api_shard {</font></div><div><font face="monospace, monospace">    include /home/user/nginx_mapping.conf;</font></div><div><font face="monospace, monospace">  }</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">}</font></div></span></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div></div><div class="gmail_extra"><div><div class="h5"><br><div class="gmail_quote">2015-07-15 13:58 GMT+03:00 Валентин Бартенев <span dir="ltr"><<a href="mailto:vbart@nginx.com" target="_blank">vbart@nginx.com</a>></span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span>On Wednesday 15 July 2015 12:31:37 Michael Kechinov wrote:<br>
> С предыдущим пунктом разобрался. Другая проблема - при POST-запросах<br>
> и $r->request_body и $r->request_body_file пусты.<br>
><br>
> POST-запрос:<br>
><br>
> curl '<a href="http://domain.com/push" rel="noreferrer" target="_blank">http://domain.com/push</a>' -H 'Content-Type:<br>
> application/x-www-form-urlencoded; charset=UTF-8' --data<br>
> 'event=view&shop_id=f95342356fa619749015b7225f3b7db3&ssid=583c5f49-e86b-477b-98f9-87507bf0e3af&count=1&item_id%5B%5D=34753&price%5B%5D=14196&is_available%5B%5D=1'<br>
><br>
> Конфигурация NGINX:<br>
><br>
> http {<br>
>     perl_set $request_shop_id '<br>
>         sub {<br>
>             my $r = shift;<br>
>             if ($r->request_method eq "GET") {<br>
>                 if($r->args =~ /shop_id=([a-z0-9A-Z]+)/ ) {<br>
>                     return "$1";<br>
>                 } else {<br>
>                     return "";<br>
>                 }<br>
>             } else {<br>
>                 return $r->request_body;<br>
>             }<br>
>         }<br>
>     ';<br>
> }<br>
><br>
> В итоге, переменная $request_shop_id пуста.<br>
><br>
> Где в итоге найти данные, переданные в запросе?<br>
><br>
<br>
</span>Так работать не будет.  На момент perl_set тело еще не было прочитано.<br>
<br>
Смотрите пример из $r->has_request_body:<br>
<a href="http://nginx.org/ru/docs/http/ngx_http_perl_module.html#methods" rel="noreferrer" target="_blank">http://nginx.org/ru/docs/http/ngx_http_perl_module.html#methods</a><br>
<br>
--<br>
Валентин Бартенев<br>
<div><div><br>
<br>
<br>
><br>
><br>
><br>
> 2015-07-14 23:46 GMT+03:00 Michael Kechinov <<a href="mailto:sam@mkechinov.ru" target="_blank">sam@mkechinov.ru</a>>:<br>
><br>
> > С этим возникла проблема<br>
> ><br>
> > Собрал NGINX с perl'ом.<br>
> > Читаю документацию <a href="http://nginx.org/ru/docs/http/ngx_http_perl_module.html" rel="noreferrer" target="_blank">http://nginx.org/ru/docs/http/ngx_http_perl_module.html</a><br>
> > В ней написано, что "sub" может быть в контексте location<br>
> > А "map" может быть только в контексте http.<br>
> ><br>
> > В итоге, это не работает, потому что тестирование конфига не проходит:<br>
> > http {<br>
> >     sub {<br>
> >         my $r = shift;<br>
> >         my $ua = $r->header_in("User-Agent");<br>
> >     }<br>
> ><br>
> >     add_header X-test "$ua";<br>
> ><br>
> >     map_hash_max_size 8192;<br>
> >     map $arg_shop_id $api_shard {<br>
> >         include /home/rails/nginx_shop_mapping.conf;<br>
> >     }<br>
> > }<br>
> ><br>
> > А это не работает, потому что маппинг происходит задолго до того, как<br>
> > сработает перловая функция:<br>
> ><br>
> > http {<br>
> ><br>
> >     server {<br>
> >         location {<br>
> >             sub {<br>
> >                 my $r = shift;<br>
> >                 my $ua = $r->header_in("User-Agent");<br>
> >             }<br>
> ><br>
> >             add_header X-test "$ua";<br>
> >         }<br>
> >     }<br>
> ><br>
> >     map_hash_max_size 8192;<br>
> >     map $arg_shop_id $api_shard {<br>
> >         include /home/rails/nginx_shop_mapping.conf;<br>
> >     }<br>
> > }<br>
> ><br>
> ><br>
> > Какой посоветуете выход?<br>
> ><br>
> ><br>
> ><br>
> ><br>
> ><br>
> ><br>
> > 2015-07-10 12:01 GMT+03:00 Валентин Бартенев <<a href="mailto:vbart@nginx.com" target="_blank">vbart@nginx.com</a>>:<br>
> ><br>
> >> On Friday 10 July 2015 10:10:04 Илья Шипицин wrote:<br>
> >> > чтобы было, как вы хотите, надо чтобы nginx сначала принял запрос<br>
> >> > полностью, извлек из тела параметр и только после этого спроксировал.<br>
> >> > на практике nginx проксирует запрос постепенно.<br>
> >> ><br>
> >> [..]<br>
> >><br>
> >> На практике он как раз сначала принимает весь запрос<br>
> >> целиком, а потом только проксирует его на бэкенд, если<br>
> >> конечно специально не выключить proxy_request_buffering:<br>
> >> <a href="http://nginx.org/r/proxy_request_buffering" rel="noreferrer" target="_blank">http://nginx.org/r/proxy_request_buffering</a><br>
> >><br>
> >> Вытащить параметр из тела запроса можно с помощью<br>
> >> встроенного перла:<br>
> >> <a href="http://nginx.org/en/docs/http/ngx_http_perl_module.html" rel="noreferrer" target="_blank">http://nginx.org/en/docs/http/ngx_http_perl_module.html</a><br>
> >><br>
> >><br>
> >> --<br>
> >> Валентин Бартенев<br>
> >> _______________________________________________<br>
> >> nginx-ru mailing list<br>
> >> <a href="mailto:nginx-ru@nginx.org" target="_blank">nginx-ru@nginx.org</a><br>
> >> <a href="http://mailman.nginx.org/mailman/listinfo/nginx-ru" rel="noreferrer" target="_blank">http://mailman.nginx.org/mailman/listinfo/nginx-ru</a><br>
> >><br>
> ><br>
> ><br>
> ><br>
> > --<br>
</div></div>> > *Michael Kechinov <<a href="http://linkedin.com/in/mkechinov" rel="noreferrer" target="_blank">http://linkedin.com/in/mkechinov</a>>* | <a href="mailto:sam@mkechinov.ru" target="_blank">sam@mkechinov.ru</a> |<br>
> > +7 950 0099233<br>
> > Startups development studio: <a href="http://mkechinov.ru" rel="noreferrer" target="_blank">mkechinov.ru</a> | en <<a href="http://mkechinov.com" rel="noreferrer" target="_blank">http://mkechinov.com</a>><br>
<span>> > Personalization for e-commerce: <a href="http://rees46.com" rel="noreferrer" target="_blank">rees46.com</a><br>
> > HackDay: <a href="http://hackday.ru" rel="noreferrer" target="_blank">hackday.ru</a><br>
> > Twitter-wall: <a href="http://twijector.com" rel="noreferrer" target="_blank">twijector.com</a><br>
> ><br>
><br>
><br>
><br>
> --<br>
</span>> *Michael Kechinov <<a href="http://linkedin.com/in/mkechinov" rel="noreferrer" target="_blank">http://linkedin.com/in/mkechinov</a>>* | <a href="mailto:sam@mkechinov.ru" target="_blank">sam@mkechinov.ru</a> |<br>
> +7 950 0099233<br>
> Startups development studio: <a href="http://mkechinov.ru" rel="noreferrer" target="_blank">mkechinov.ru</a> | en <<a href="http://mkechinov.com" rel="noreferrer" target="_blank">http://mkechinov.com</a>><br>
<span>> Personalization for e-commerce: <a href="http://rees46.com" rel="noreferrer" target="_blank">rees46.com</a><br>
> HackDay: <a href="http://hackday.ru" rel="noreferrer" target="_blank">hackday.ru</a><br>
> Twitter-wall: <a href="http://twijector.com" rel="noreferrer" target="_blank">twijector.com</a><br>
><br>
</span><div><div>_______________________________________________<br>
nginx-ru mailing list<br>
<a href="mailto:nginx-ru@nginx.org" target="_blank">nginx-ru@nginx.org</a><br>
<a href="http://mailman.nginx.org/mailman/listinfo/nginx-ru" rel="noreferrer" target="_blank">http://mailman.nginx.org/mailman/listinfo/nginx-ru</a></div></div></blockquote></div><br><br clear="all"><div><br></div></div></div><span class="HOEnZb"><font color="#888888">-- <br></font></span><div><div dir="ltr"><span class="HOEnZb"><font color="#888888"><b><a href="http://linkedin.com/in/mkechinov" target="_blank">Michael Kechinov</a></b> | <a href="mailto:sam@mkechinov.ru" target="_blank">sam@mkechinov.ru</a> | +7 950 0099233</font></span><span class=""><br><div>Startups development studio: <a href="http://mkechinov.ru/" target="_blank">mkechinov.ru</a> | <a href="http://mkechinov.com" target="_blank">en</a></div></span><span class=""><div>Personalization for e-commerce: <a href="http://rees46.com" target="_blank">rees46.com</a></div><div>HackDay: <a href="http://hackday.ru/" target="_blank">hackday.ru</a> <br>Twitter-wall: <a href="http://twijector.com" target="_blank">twijector.com</a></div></span></div></div>
</div>
</blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature"><div dir="ltr"><b><a href="http://linkedin.com/in/mkechinov" target="_blank">Michael Kechinov</a></b> | <a href="mailto:sam@mkechinov.ru" target="_blank">sam@mkechinov.ru</a> | +7 950 0099233<br><div>Startups development studio: <a href="http://mkechinov.ru/" target="_blank">mkechinov.ru</a> | <a href="http://mkechinov.com" target="_blank">en</a></div><div>Personalization for e-commerce: <a href="http://rees46.com" target="_blank">rees46.com</a></div><div>HackDay: <a href="http://hackday.ru/" target="_blank">hackday.ru</a> <br>Twitter-wall: <a href="http://twijector.com" target="_blank">twijector.com</a></div></div></div>
</div>