Re: Вопрос про map, переменные и аргументы
Michael Kechinov
sam на mkechinov.ru
Ср Июл 15 12:07:23 UTC 2015
Правильно понимаю, что в этом случае будет происходить следующее:
В момент, когда считывается весь body срабатывает callback, в который
передается этот body.
В callback'е мы получаем значение нужного аргумента (shop_id),
устанавливаем это значение в переменную $request_shop_id, доступную в NGINX
(кстати, не нашел, как установить в PERL'е переменную, которая будет
доступна далее в конфиге NGINX'а - нашел только $r->variable, но оно просто
передает переменную между sub'ами).
Далее в секции location обращаюсь к переменной $api_shard, на нее
срабатывает map, который поместит значение, связанное со значением
$request_shop_id.
То есть на момент обращения к $api_shard у меня гарантировано будет
загружен body. Так?
Псевдо-код
http {
server {
location ... {
perl '
sub {
$r_shop_id = $r->has_request_body(\&process_body)
// Как-то установить переменную $request_shop_id в значение
$r_shop_id,
// чтобы было доступно в конфиге NGINX
}
sub process_body {
$r = shift;
if( $r->request_body ~= /shop_id=([a-z0-9]+)/) {
return "$1";
}
return "";
}
';
# Тут просто используем переменную $api_shard как-то так
proxy_set_header ShardID $api_shard;
proxy_pass http://backend;
}
}
map $arg_code $api_shard {
include /home/user/nginx_mapping.conf;
}
}
2015-07-15 13:58 GMT+03:00 Валентин Бартенев <vbart на nginx.com>:
> On Wednesday 15 July 2015 12:31:37 Michael Kechinov wrote:
> > С предыдущим пунктом разобрался. Другая проблема - при POST-запросах
> > и $r->request_body и $r->request_body_file пусты.
> >
> > POST-запрос:
> >
> > curl 'http://domain.com/push' -H 'Content-Type:
> > application/x-www-form-urlencoded; charset=UTF-8' --data
> >
> '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'
> >
> > Конфигурация NGINX:
> >
> > http {
> > perl_set $request_shop_id '
> > sub {
> > my $r = shift;
> > if ($r->request_method eq "GET") {
> > if($r->args =~ /shop_id=([a-z0-9A-Z]+)/ ) {
> > return "$1";
> > } else {
> > return "";
> > }
> > } else {
> > return $r->request_body;
> > }
> > }
> > ';
> > }
> >
> > В итоге, переменная $request_shop_id пуста.
> >
> > Где в итоге найти данные, переданные в запросе?
> >
>
> Так работать не будет. На момент perl_set тело еще не было прочитано.
>
> Смотрите пример из $r->has_request_body:
> http://nginx.org/ru/docs/http/ngx_http_perl_module.html#methods
>
> --
> Валентин Бартенев
>
>
>
> >
> >
> >
> > 2015-07-14 23:46 GMT+03:00 Michael Kechinov <sam на mkechinov.ru>:
> >
> > > С этим возникла проблема
> > >
> > > Собрал NGINX с perl'ом.
> > > Читаю документацию
> http://nginx.org/ru/docs/http/ngx_http_perl_module.html
> > > В ней написано, что "sub" может быть в контексте location
> > > А "map" может быть только в контексте http.
> > >
> > > В итоге, это не работает, потому что тестирование конфига не проходит:
> > > http {
> > > sub {
> > > my $r = shift;
> > > my $ua = $r->header_in("User-Agent");
> > > }
> > >
> > > add_header X-test "$ua";
> > >
> > > map_hash_max_size 8192;
> > > map $arg_shop_id $api_shard {
> > > include /home/rails/nginx_shop_mapping.conf;
> > > }
> > > }
> > >
> > > А это не работает, потому что маппинг происходит задолго до того, как
> > > сработает перловая функция:
> > >
> > > http {
> > >
> > > server {
> > > location {
> > > sub {
> > > my $r = shift;
> > > my $ua = $r->header_in("User-Agent");
> > > }
> > >
> > > add_header X-test "$ua";
> > > }
> > > }
> > >
> > > map_hash_max_size 8192;
> > > map $arg_shop_id $api_shard {
> > > include /home/rails/nginx_shop_mapping.conf;
> > > }
> > > }
> > >
> > >
> > > Какой посоветуете выход?
> > >
> > >
> > >
> > >
> > >
> > >
> > > 2015-07-10 12:01 GMT+03:00 Валентин Бартенев <vbart на nginx.com>:
> > >
> > >> On Friday 10 July 2015 10:10:04 Илья Шипицин wrote:
> > >> > чтобы было, как вы хотите, надо чтобы nginx сначала принял запрос
> > >> > полностью, извлек из тела параметр и только после этого
> спроксировал.
> > >> > на практике nginx проксирует запрос постепенно.
> > >> >
> > >> [..]
> > >>
> > >> На практике он как раз сначала принимает весь запрос
> > >> целиком, а потом только проксирует его на бэкенд, если
> > >> конечно специально не выключить proxy_request_buffering:
> > >> http://nginx.org/r/proxy_request_buffering
> > >>
> > >> Вытащить параметр из тела запроса можно с помощью
> > >> встроенного перла:
> > >> http://nginx.org/en/docs/http/ngx_http_perl_module.html
> > >>
> > >>
> > >> --
> > >> Валентин Бартенев
> > >> _______________________________________________
> > >> nginx-ru mailing list
> > >> nginx-ru на nginx.org
> > >> http://mailman.nginx.org/mailman/listinfo/nginx-ru
> > >>
> > >
> > >
> > >
> > > --
> > > *Michael Kechinov <http://linkedin.com/in/mkechinov>* |
> sam на mkechinov.ru |
> > > +7 950 0099233
> > > Startups development studio: mkechinov.ru | en <http://mkechinov.com>
> > > Personalization for e-commerce: rees46.com
> > > HackDay: hackday.ru
> > > Twitter-wall: twijector.com
> > >
> >
> >
> >
> > --
> > *Michael Kechinov <http://linkedin.com/in/mkechinov>* | sam на mkechinov.ru
> |
> > +7 950 0099233
> > Startups development studio: mkechinov.ru | en <http://mkechinov.com>
> > Personalization for e-commerce: rees46.com
> > HackDay: hackday.ru
> > Twitter-wall: twijector.com
> >
> _______________________________________________
> nginx-ru mailing list
> nginx-ru на nginx.org
> http://mailman.nginx.org/mailman/listinfo/nginx-ru
>
--
*Michael Kechinov <http://linkedin.com/in/mkechinov>* | sam на mkechinov.ru |
+7 950 0099233
Startups development studio: mkechinov.ru | en <http://mkechinov.com>
Personalization for e-commerce: rees46.com
HackDay: hackday.ru
Twitter-wall: twijector.com
----------- следущая часть -----------
Вложение в формате HTML было извлечено…
URL: <http://mailman.nginx.org/pipermail/nginx-ru/attachments/20150715/6f69657c/attachment.html>
Подробная информация о списке рассылки nginx-ru