Re: Вопрос про map, переменные и аргументы

Michael Kechinov sam на mkechinov.ru
Ср Июл 15 12:08:55 UTC 2015


Ошибся с переменной в псевдокоде. Обновленный:

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 $request_shop_id $api_shard {
    include /home/user/nginx_mapping.conf;
  }

}

2015-07-15 15:07 GMT+03:00 Michael Kechinov <sam на mkechinov.ru>:

> Правильно понимаю, что в этом случае будет происходить следующее:
>
> В момент, когда считывается весь 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
>



-- 
*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/840e5412/attachment.html>


Подробная информация о списке рассылки nginx-ru