Re: порядок прохождения http-фаз сервера

2013-03-19 Пенетрантность Maxim Dounin
Hello!

On Mon, Mar 18, 2013 at 10:49:59PM +0400, Oleg wrote:

 On Mon, Mar 18, 2013 at 08:00:55PM +0400, Maxim Dounin wrote:
  Hello!
  
 А http-redirect может только модуль фазы NGX_HTTP_CONTENT_PHASE слать 
   или с
   фазы NGX_HTTP_ACCESS_PHASE тоже можно слать перенаправления?
  
  Можно из любой фазы (но может требовать дополнительных 
  приседаний).
 
   Так. Попробовал по-быстрому сделать перенаправление. Никаких приседаний не
 заметил, по крайней мере для фазы NGX_HTTP_ACCESS_PHASE. Может, чего-то не
 учёл, конечно, но сделал в лоб:
 
 h = r-headers_out.location;
 if ( h == NULL ) {
   h = ngx_list_push(r-headers_out.headers);
   if ( h == NULL )
 return NGX_ERROR;
 
   h-key.data = Location;
   h-key.len = sizeof(Location) - 1;
 
   r-headers_out.location = h;
 }
 h-value.data = http://ya.ru;;
 h-value.len = sizeof(http://ya.ru;) - 1;
 h-hash = 1;
 
 r-headers_out.status = NGX_HTTP_TEMPORARY_REDIRECT;
 ngx_http_send_header(r);
 
 return NGX_OK;
 
   Работает нормально.

Так, насколько я понимаю, будет мусор на выходе - сначала ответ 
302 без тела, а потом ответ на исходный запрос.  Посмотрите 
telnet'ом на ответ.

Для access-фазы проще всего добавить заголовок location, и вернуть 
NGX_HTTP_TEMPORARY_REDIRECT (BTW, хочется возвращать именно 307?).  
Собственно, так же, как и для content-фазы, ибо там есть 
специальная обработка NGX_HTTP_*.  Как-то так (выдержка из 
ngx_http_static_module.c):

ngx_http_clear_location(r);

r-headers_out.location = ngx_palloc(r-pool, sizeof(ngx_table_elt_t));
if (r-headers_out.location == NULL) {
return NGX_ERROR;
}

r-headers_out.location-value.len = len;
r-headers_out.location-value.data = location;

return NGX_HTTP_TEMPORARY_REDIRECT;

-- 
Maxim Dounin
http://nginx.org/en/donation.html

___
nginx-ru mailing list
nginx-ru@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-ru

Re: порядок прохождения http-фаз сервера

2013-03-19 Пенетрантность Oleg
On Tue, Mar 19, 2013 at 02:55:21PM +0400, Maxim Dounin wrote:
 Hello!
 
 Так, насколько я понимаю, будет мусор на выходе - сначала ответ 
 302 без тела, а потом ответ на исходный запрос.  Посмотрите 
 telnet'ом на ответ.

  Да :-). Я это предположил, но проверить забыл.
  Какие-то символы 'ba' в ответе странные:

$ telnet zbox-srv.kvm 80
Trying 192.168.77.26...
Connected to zbox-srv.kvm.
Escape character is '^]'.
GET /zboxweb/user/admin HTTP/1.1
Host: zbox-srv.kvm

HTTP/1.1 307 Temporary Redirect
Server: nginx/1.2.1
Date: Tue, 19 Mar 2013 11:24:40 GMT
Transfer-Encoding: chunked
Connection: keep-alive
Location: http://$host/zboxweb

ba
html
headtitle307 Temporary Redirect/title/head
body bgcolor=white
centerh1307 Temporary Redirect/h1/center
hrcenternginx/1.2.1/center
/body
/html

0

quit
html
headtitle400 Bad Request/title/head
body bgcolor=white
centerh1400 Bad Request/h1/center
hrcenternginx/1.2.1/center
/body
/html
Connection closed by foreign host.


 Для access-фазы проще всего добавить заголовок location, и вернуть 
 NGX_HTTP_TEMPORARY_REDIRECT (BTW, хочется возвращать именно 307?).  
 Собственно, так же, как и для content-фазы, ибо там есть 
 специальная обработка NGX_HTTP_*.  Как-то так (выдержка из 
 ngx_http_static_module.c):
 
 ngx_http_clear_location(r);
 
 r-headers_out.location = ngx_palloc(r-pool, sizeof(ngx_table_elt_t));
 if (r-headers_out.location == NULL) {
 return NGX_ERROR;
 }
 
 r-headers_out.location-value.len = len;
 r-headers_out.location-value.data = location;
 
 return NGX_HTTP_TEMPORARY_REDIRECT;

  Т.е. устанавливать r-headers_out.status и делать ngx_http_send_header(r)
необязательно?

___
nginx-ru mailing list
nginx-ru@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-ru

порядок прохождения http-фаз сервера

2013-03-18 Пенетрантность Oleg
  Привет всем.

  Фазы сервера:

typedef enum {
NGX_HTTP_POST_READ_PHASE = 0,

NGX_HTTP_SERVER_REWRITE_PHASE,

NGX_HTTP_FIND_CONFIG_PHASE,
NGX_HTTP_REWRITE_PHASE,
NGX_HTTP_POST_REWRITE_PHASE,

NGX_HTTP_PREACCESS_PHASE,

NGX_HTTP_ACCESS_PHASE,
NGX_HTTP_POST_ACCESS_PHASE,

NGX_HTTP_TRY_FILES_PHASE,
NGX_HTTP_CONTENT_PHASE,

NGX_HTTP_LOG_PHASE
} ngx_http_phases;

  проходят в порядке их перечисления?

___
nginx-ru mailing list
nginx-ru@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-ru

Re: порядок прохождения http-фаз сервера

2013-03-18 Пенетрантность Maxim Dounin
Hello!

On Mon, Mar 18, 2013 at 05:24:25PM +0400, Oleg wrote:

   Привет всем.
 
   Фазы сервера:
 
 typedef enum {
 NGX_HTTP_POST_READ_PHASE = 0,
 
 NGX_HTTP_SERVER_REWRITE_PHASE,
 
 NGX_HTTP_FIND_CONFIG_PHASE,
 NGX_HTTP_REWRITE_PHASE,
 NGX_HTTP_POST_REWRITE_PHASE,
 
 NGX_HTTP_PREACCESS_PHASE,
 
 NGX_HTTP_ACCESS_PHASE,
 NGX_HTTP_POST_ACCESS_PHASE,
 
 NGX_HTTP_TRY_FILES_PHASE,
 NGX_HTTP_CONTENT_PHASE,
 
 NGX_HTTP_LOG_PHASE
 } ngx_http_phases;
 
   проходят в порядке их перечисления?

Да.

(Называется это обычно фазы обработки запроса.)

-- 
Maxim Dounin
http://nginx.org/en/donation.html

___
nginx-ru mailing list
nginx-ru@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-ru

Re: порядок прохождения http-фаз сервера

2013-03-18 Пенетрантность Oleg
On Mon, Mar 18, 2013 at 05:40:42PM +0400, Maxim Dounin wrote:
 Hello!
 
 On Mon, Mar 18, 2013 at 05:24:25PM +0400, Oleg wrote:
 
Привет всем.
  
Фазы сервера:
  
  typedef enum {
  NGX_HTTP_POST_READ_PHASE = 0,
  
  NGX_HTTP_SERVER_REWRITE_PHASE,
  
  NGX_HTTP_FIND_CONFIG_PHASE,
  NGX_HTTP_REWRITE_PHASE,
  NGX_HTTP_POST_REWRITE_PHASE,
  
  NGX_HTTP_PREACCESS_PHASE,
  
  NGX_HTTP_ACCESS_PHASE,
  NGX_HTTP_POST_ACCESS_PHASE,
  
  NGX_HTTP_TRY_FILES_PHASE,
  NGX_HTTP_CONTENT_PHASE,
  
  NGX_HTTP_LOG_PHASE
  } ngx_http_phases;
  
проходят в порядке их перечисления?
 
 Да.
 
 (Называется это обычно фазы обработки запроса.)

  Т.е. сделать редирект в конфиге на основе результата аутентификации не
получится, я правильно понимаю?
  Например, надо сделать в случае неудачной аутентификации редирект на страницу
с логином/паролем:

  location = /login {
# тут страница для аутентификации и редиректом на /user/$USERNAME в случае
# удачи.
fastcgi_pass 127.0.0.1:9000;
include fastcgi_params;
fastcgi_param SERVER_NAME $http_host;
  }
  location /user/user1 {
# аутентификация по cookie, полученном в локации /login
auth_cookie CGISESSID;
auth_cookie_path /tmp;

# cookie кончился
if ( $auth_cookie_fail ) {
  return 302 http://$host/login;
}

proxy_pass http://127.0.0.2:2001/;
include proxy_params;
  }

  $auth_cookie_fail устанавливается модулем auth_cookie. Я так понимаю, так
не получится?

___
nginx-ru mailing list
nginx-ru@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-ru

Re: порядок прохождения http-фаз сервера

2013-03-18 Пенетрантность Maxim Dounin
Hello!

On Mon, Mar 18, 2013 at 06:34:53PM +0400, Oleg wrote:

 On Mon, Mar 18, 2013 at 05:40:42PM +0400, Maxim Dounin wrote:
  Hello!
  
  On Mon, Mar 18, 2013 at 05:24:25PM +0400, Oleg wrote:
  
 Привет всем.
   
 Фазы сервера:
   
   typedef enum {
   NGX_HTTP_POST_READ_PHASE = 0,
   
   NGX_HTTP_SERVER_REWRITE_PHASE,
   
   NGX_HTTP_FIND_CONFIG_PHASE,
   NGX_HTTP_REWRITE_PHASE,
   NGX_HTTP_POST_REWRITE_PHASE,
   
   NGX_HTTP_PREACCESS_PHASE,
   
   NGX_HTTP_ACCESS_PHASE,
   NGX_HTTP_POST_ACCESS_PHASE,
   
   NGX_HTTP_TRY_FILES_PHASE,
   NGX_HTTP_CONTENT_PHASE,
   
   NGX_HTTP_LOG_PHASE
   } ngx_http_phases;
   
 проходят в порядке их перечисления?
  
  Да.
  
  (Называется это обычно фазы обработки запроса.)
 
   Т.е. сделать редирект в конфиге на основе результата аутентификации не
 получится, я правильно понимаю?
   Например, надо сделать в случае неудачной аутентификации редирект на 
 страницу
 с логином/паролем:
 
   location = /login {
 # тут страница для аутентификации и редиректом на /user/$USERNAME в случае
 # удачи.
 fastcgi_pass 127.0.0.1:9000;
 include fastcgi_params;
 fastcgi_param SERVER_NAME $http_host;
   }
   location /user/user1 {
 # аутентификация по cookie, полученном в локации /login
 auth_cookie CGISESSID;
 auth_cookie_path /tmp;
 
 # cookie кончился
 if ( $auth_cookie_fail ) {
   return 302 http://$host/login;
 }
 
 proxy_pass http://127.0.0.2:2001/;
 include proxy_params;
   }
 
   $auth_cookie_fail устанавливается модулем auth_cookie. Я так понимаю, так
 не получится?

Совершенно верно.

-- 
Maxim Dounin
http://nginx.org/en/donation.html

___
nginx-ru mailing list
nginx-ru@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-ru

Re: порядок прохождения http-фаз сервера

2013-03-18 Пенетрантность Oleg
On Mon, Mar 18, 2013 at 06:53:22PM +0400, Maxim Dounin wrote:
 Hello!
 
Например, надо сделать в случае неудачной аутентификации редирект на 
  страницу
  с логином/паролем:
  
location = /login {
  # тут страница для аутентификации и редиректом на /user/$USERNAME в 
  случае
  # удачи.
  fastcgi_pass 127.0.0.1:9000;
  include fastcgi_params;
  fastcgi_param SERVER_NAME $http_host;
}
location /user/user1 {
  # аутентификация по cookie, полученном в локации /login
  auth_cookie CGISESSID;
  auth_cookie_path /tmp;
  
  # cookie кончился
  if ( $auth_cookie_fail ) {
return 302 http://$host/login;
  }
  
  proxy_pass http://127.0.0.2:2001/;
  include proxy_params;
}
  
$auth_cookie_fail устанавливается модулем auth_cookie. Я так понимаю, так
  не получится?
 
 Совершенно верно.

  А http-redirect может только модуль фазы NGX_HTTP_CONTENT_PHASE слать или с
фазы NGX_HTTP_ACCESS_PHASE тоже можно слать перенаправления?
  И ещё вопрос. Здесь - http://www.evanmiller.org/nginx-modules-guide.html -
написано, что хэндлер контента может быть только один и вешается так:

  clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
  clcf-handler = ngx_http_circle_gif_handler;

  Про хэндлеры фаз обработки запроса там, кстати, я ничего не нашёл.
  Вопрос в чём. Можно ли повесить несколько handler'ов содержимого через
фазу обработки запроса NGX_HTTP_CONTENT_PHASE? И можно ли это сделать так,
что бы он вызывался гарантировано до proxy_pass?
  Тогда, я могу там делать http-redirect на основе переменных, допустим.

___
nginx-ru mailing list
nginx-ru@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-ru

Re: порядок прохождения http-фаз сервера

2013-03-18 Пенетрантность Maxim Dounin
Hello!

On Mon, Mar 18, 2013 at 07:38:07PM +0400, Oleg wrote:

 On Mon, Mar 18, 2013 at 06:53:22PM +0400, Maxim Dounin wrote:
  Hello!
  
 Например, надо сделать в случае неудачной аутентификации редирект на 
   страницу
   с логином/паролем:
   
 location = /login {
   # тут страница для аутентификации и редиректом на /user/$USERNAME в 
   случае
   # удачи.
   fastcgi_pass 127.0.0.1:9000;
   include fastcgi_params;
   fastcgi_param SERVER_NAME $http_host;
 }
 location /user/user1 {
   # аутентификация по cookie, полученном в локации /login
   auth_cookie CGISESSID;
   auth_cookie_path /tmp;
   
   # cookie кончился
   if ( $auth_cookie_fail ) {
 return 302 http://$host/login;
   }
   
   proxy_pass http://127.0.0.2:2001/;
   include proxy_params;
 }
   
 $auth_cookie_fail устанавливается модулем auth_cookie. Я так понимаю, 
   так
   не получится?
  
  Совершенно верно.
 
   А http-redirect может только модуль фазы NGX_HTTP_CONTENT_PHASE слать или с
 фазы NGX_HTTP_ACCESS_PHASE тоже можно слать перенаправления?

Можно из любой фазы (но может требовать дополнительных 
приседаний).

   И ещё вопрос. Здесь - http://www.evanmiller.org/nginx-modules-guide.html -
 написано, что хэндлер контента может быть только один и вешается так:
 
   clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
   clcf-handler = ngx_http_circle_gif_handler;

Так вешаются content-обработчики, вызываемые для данного 
location'а.  Такие обработчики делать - проще всего, и в 
большинстве случаев именно они и нужны.  Опять же, такие 
обработчики - никак не влияют на обработку запросов в других 
location'ах.  Именно так работает proxy_pass (+ memcached, 
fastcgi, uwsgi, scgi), empty_gif, stub_status, perl и т.п.

Но это не всё, что бывает в content-фазе.  Если clcf-handler не 
стоит, или отказался от обработки запроса, то последовательно 
вызываются модули content-фазы, такие как random_index, index, 
autoindex, static.

   Про хэндлеры фаз обработки запроса там, кстати, я ничего не нашёл.
   Вопрос в чём. Можно ли повесить несколько handler'ов содержимого через
 фазу обработки запроса NGX_HTTP_CONTENT_PHASE? И можно ли это сделать так,
 что бы он вызывался гарантировано до proxy_pass?
   Тогда, я могу там делать http-redirect на основе переменных, допустим.

Нет, так работать не будет.  Если стоит clcf-handler - то на 
обротчики content-фазы смотреть никто не будет.  Если вам нужно 
своим модулем проверить результат работы модуля access-фазы, то 
это надо делать в access-фазе же (и при этом убедившись, что 
satisfy стоит в all).

Загляните в ngx_http_core_module.c, там всё более или менее 
понятно.

-- 
Maxim Dounin
http://nginx.org/en/donation.html

___
nginx-ru mailing list
nginx-ru@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-ru

Re: порядок прохождения http-фаз сервера

2013-03-18 Пенетрантность Oleg
On Mon, Mar 18, 2013 at 08:00:55PM +0400, Maxim Dounin wrote:
 Hello!
 
А http-redirect может только модуль фазы NGX_HTTP_CONTENT_PHASE слать или 
  с
  фазы NGX_HTTP_ACCESS_PHASE тоже можно слать перенаправления?
 
 Можно из любой фазы (но может требовать дополнительных 
 приседаний).

  Хм, думал есть какой-либо правильный способ, так сказать.

И ещё вопрос. Здесь - http://www.evanmiller.org/nginx-modules-guide.html -
  написано, что хэндлер контента может быть только один и вешается так:
  
clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
clcf-handler = ngx_http_circle_gif_handler;
 
 Так вешаются content-обработчики, вызываемые для данного 
 location'а.  Такие обработчики делать - проще всего, и в 
 большинстве случаев именно они и нужны.  Опять же, такие 
 обработчики - никак не влияют на обработку запросов в других 
 location'ах.  Именно так работает proxy_pass (+ memcached, 
 fastcgi, uwsgi, scgi), empty_gif, stub_status, perl и т.п.
 
 Но это не всё, что бывает в content-фазе.  Если clcf-handler не 
 стоит, или отказался от обработки запроса, то последовательно 
 вызываются модули content-фазы, такие как random_index, index, 
 autoindex, static.
 
Про хэндлеры фаз обработки запроса там, кстати, я ничего не нашёл.
Вопрос в чём. Можно ли повесить несколько handler'ов содержимого через
  фазу обработки запроса NGX_HTTP_CONTENT_PHASE? И можно ли это сделать так,
  что бы он вызывался гарантировано до proxy_pass?
Тогда, я могу там делать http-redirect на основе переменных, допустим.
 
 Нет, так работать не будет.  Если стоит clcf-handler - то на 
 обротчики content-фазы смотреть никто не будет.  Если вам нужно 
 своим модулем проверить результат работы модуля access-фазы, то 
 это надо делать в access-фазе же (и при этом убедившись, что 
 satisfy стоит в all).

  Большое спасибо за разъяснения. Думаю городить ещё модуль нет смысла в
моём случае. Надо всё в одном модуле делать.

 Загляните в ngx_http_core_module.c, там всё более или менее 
 понятно.

  Спасибо за указание направления. Попытаюсь там что-нибудь накопать.

___
nginx-ru mailing list
nginx-ru@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-ru

Re: порядок прохождения http-фаз сервера

2013-03-18 Пенетрантность Oleg
On Mon, Mar 18, 2013 at 08:00:55PM +0400, Maxim Dounin wrote:
 Hello!
 
А http-redirect может только модуль фазы NGX_HTTP_CONTENT_PHASE слать или 
  с
  фазы NGX_HTTP_ACCESS_PHASE тоже можно слать перенаправления?
 
 Можно из любой фазы (но может требовать дополнительных 
 приседаний).

  Так. Попробовал по-быстрому сделать перенаправление. Никаких приседаний не
заметил, по крайней мере для фазы NGX_HTTP_ACCESS_PHASE. Может, чего-то не
учёл, конечно, но сделал в лоб:

h = r-headers_out.location;
if ( h == NULL ) {
  h = ngx_list_push(r-headers_out.headers);
  if ( h == NULL )
return NGX_ERROR;

  h-key.data = Location;
  h-key.len = sizeof(Location) - 1;

  r-headers_out.location = h;
}
h-value.data = http://ya.ru;;
h-value.len = sizeof(http://ya.ru;) - 1;
h-hash = 1;

r-headers_out.status = NGX_HTTP_TEMPORARY_REDIRECT;
ngx_http_send_header(r);

return NGX_OK;

  Работает нормально.

___
nginx-ru mailing list
nginx-ru@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-ru