Re: Порядок прохождения хендлеров в фазе

2018-02-22 Пенетрантность Igor Savenko
Спасибо! :) Понятно

22 февраля 2018 г., 18:52 пользователь Maxim Dounin 
написал:

> Hello!
>
> On Thu, Feb 22, 2018 at 06:15:35PM +0200, Igor Savenko wrote:
>
> > Большое спасибо, Максим! Тем временем, я обратил внимание на то, каким
> > образом в openresty реализован фукнционал сдвига выполнения модуля в
> самый
> > конец фазы:
> >
> > if (!lmcf->postponed_to_access_phase_end) {
> >
> > lmcf->postponed_to_access_phase_end = 1;
> >
> > cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
> >
> > ph = cmcf->phase_engine.handlers;
> > cur_ph = [r->phase_handler];
>
> [...]
>
> > Актуален ли данный подход? Это хак, недокументированная возможность или
> > широкоизвестная в узких кругах функциональность?
>
> Приблизительно всё, что можно найти в openresty - это хаки разной
> степени тяжести.  Процитированный код - характерный представитель.
>
> Во-первых, он лезет во внутренние структуры http core.  Однажды мы
> что-нибудь поменяем внутри - и оно всё сломается с удивительными
> спецэффектами.
>
> Во-вторых, он пытается менять конфигурацию внутри работающего
> рабочего процесса.  Это просто глупо, так как приведёт к тому, что
> соответствующие структуры будут дублироваться в памяти разных
> рабочих процессов.
>
> Не надо делать так.
>
> --
> Maxim Dounin
> http://mdounin.ru/
> ___
> nginx-ru mailing list
> nginx-ru@nginx.org
> http://mailman.nginx.org/mailman/listinfo/nginx-ru
>
___
nginx-ru mailing list
nginx-ru@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-ru

Re: Порядок прохождения хендлеров в фазе

2018-02-22 Пенетрантность Maxim Dounin
Hello!

On Thu, Feb 22, 2018 at 06:15:35PM +0200, Igor Savenko wrote:

> Большое спасибо, Максим! Тем временем, я обратил внимание на то, каким
> образом в openresty реализован фукнционал сдвига выполнения модуля в самый
> конец фазы:
> 
> if (!lmcf->postponed_to_access_phase_end) {
> 
> lmcf->postponed_to_access_phase_end = 1;
> 
> cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
> 
> ph = cmcf->phase_engine.handlers;
> cur_ph = [r->phase_handler];

[...]

> Актуален ли данный подход? Это хак, недокументированная возможность или
> широкоизвестная в узких кругах функциональность?

Приблизительно всё, что можно найти в openresty - это хаки разной
степени тяжести.  Процитированный код - характерный представитель.  

Во-первых, он лезет во внутренние структуры http core.  Однажды мы 
что-нибудь поменяем внутри - и оно всё сломается с удивительными 
спецэффектами.

Во-вторых, он пытается менять конфигурацию внутри работающего 
рабочего процесса.  Это просто глупо, так как приведёт к тому, что 
соответствующие структуры будут дублироваться в памяти разных 
рабочих процессов.

Не надо делать так.

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

Re: Порядок прохождения хендлеров в фазе

2018-02-22 Пенетрантность Igor Savenko
Большое спасибо, Максим! Тем временем, я обратил внимание на то, каким
образом в openresty реализован фукнционал сдвига выполнения модуля в самый
конец фазы:

if (!lmcf->postponed_to_access_phase_end) {

lmcf->postponed_to_access_phase_end = 1;

cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);

ph = cmcf->phase_engine.handlers;
cur_ph = [r->phase_handler];

/* we should skip the post_access phase handler here too */
last_ph = [cur_ph->next - 2];

dd("ph cur: %d, ph next: %d", (int) r->phase_handler,
   (int) (cur_ph->next - 2));

#if 0
if (cur_ph == last_ph) {
dd("XXX our handler is already the last access phase handler");
}
#endif

if (cur_ph < last_ph) {
dd("swaping the contents of cur_ph and last_ph...");

tmp = *cur_ph;

memmove(cur_ph, cur_ph + 1,
(last_ph - cur_ph) * sizeof (ngx_http_phase_handler_t));

*last_ph = tmp;

r->phase_handler--; /* redo the current ph */

return NGX_DECLINED;
}
}

Актуален ли данный подход? Это хак, недокументированная возможность или
широкоизвестная в узких кругах функциональность?

22 февраля 2018 г., 18:08 пользователь Maxim Dounin 
написал:

> Hello!
>
> On Thu, Feb 22, 2018 at 03:10:04PM +0200, Igor Savenko wrote:
>
> > Добрый день! Есть ли способ указать, что данный хендлер (в моем случае
> > ModSecurity handler в access-phase) должен вызываться последним Или после
> > определенного хендлера? Или, как воркэраунд, в данном модуле проверить
> > определенное условие, и если оно не выставлено, выдать NGX_DECLINED,
> чтобы
> > потом этот модуль в акцесс-фазе был вызван вновь, после того, как
> остальные
> > хендлеры уже отработали?
>
> Порядок вызова модулей в фазе определяется при сборке - сначала
> вызываются обработчики тех модулей, которые идут в списке модулей
> последними (и соответственно добавили свой обработчик в фазу
> последними).  Соответственно в access-фазе сторонние модули в
> общем случае будут вызываться раньше встроенных, а взаимный
> порядок сторонних модулей определяется порядком опций --add-module.
>
> Чуть больше контроля есть при динамической загрузке - с помощью
> переменной ngx_module_order можно задать произвольную позицию,
> куда следует загружать модуль.
>
> Но вообще, если порядок вдруг важен - стоит подумать о том,
> правильно ли выбрана фаза.  Если хочется позвать обработчик
> последним - то, возможно, вам нужна другая фаза.
>
> > Влияет ли на этот фукнционал состояние директивы satisfy ?
>
> Директива satisfy определяет, будет ли требоватся разрешение на
> выполнение от всех модулей access-фазы (all) или хотя бы от одного
> (any).  В случае "satisfy all" все модули фазы вызываются
> последовательно, если хотя бы один из них вернёт ошибку -
> пользователю будет возвращена ошибка.  В случае "satisfy any" все
> модули фазы вызываются последовательно, пока хотя бы один из них
> не разрешит выполнение запроса.  После этого обработка запроса
> переходит к следующей фазе, остальные модули фазы не вызываются.
>
> Вышеописанное следует учитывать при создании модулей для
> access-фазы - в случае "satisfy any" они могут не быть вызваны
> вовсе (если какой-то другой модуль разрешил выполнение запроса), и
> сами не должны возвращать NGX_OK, если не хотят явно разрешить
> доступ клиенту, минуя проверки других модулей.
>
> --
> Maxim Dounin
> http://mdounin.ru/
> ___
> nginx-ru mailing list
> nginx-ru@nginx.org
> http://mailman.nginx.org/mailman/listinfo/nginx-ru
___
nginx-ru mailing list
nginx-ru@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-ru

Re: Порядок прохождения хендлеров в фазе

2018-02-22 Пенетрантность Maxim Dounin
Hello!

On Thu, Feb 22, 2018 at 03:10:04PM +0200, Igor Savenko wrote:

> Добрый день! Есть ли способ указать, что данный хендлер (в моем случае
> ModSecurity handler в access-phase) должен вызываться последним Или после
> определенного хендлера? Или, как воркэраунд, в данном модуле проверить
> определенное условие, и если оно не выставлено, выдать NGX_DECLINED, чтобы
> потом этот модуль в акцесс-фазе был вызван вновь, после того, как остальные
> хендлеры уже отработали?

Порядок вызова модулей в фазе определяется при сборке - сначала 
вызываются обработчики тех модулей, которые идут в списке модулей 
последними (и соответственно добавили свой обработчик в фазу 
последними).  Соответственно в access-фазе сторонние модули в 
общем случае будут вызываться раньше встроенных, а взаимный 
порядок сторонних модулей определяется порядком опций --add-module.

Чуть больше контроля есть при динамической загрузке - с помощью 
переменной ngx_module_order можно задать произвольную позицию, 
куда следует загружать модуль.

Но вообще, если порядок вдруг важен - стоит подумать о том, 
правильно ли выбрана фаза.  Если хочется позвать обработчик 
последним - то, возможно, вам нужна другая фаза.

> Влияет ли на этот фукнционал состояние директивы satisfy ?

Директива satisfy определяет, будет ли требоватся разрешение на 
выполнение от всех модулей access-фазы (all) или хотя бы от одного 
(any).  В случае "satisfy all" все модули фазы вызываются 
последовательно, если хотя бы один из них вернёт ошибку - 
пользователю будет возвращена ошибка.  В случае "satisfy any" все 
модули фазы вызываются последовательно, пока хотя бы один из них 
не разрешит выполнение запроса.  После этого обработка запроса 
переходит к следующей фазе, остальные модули фазы не вызываются.

Вышеописанное следует учитывать при создании модулей для 
access-фазы - в случае "satisfy any" они могут не быть вызваны 
вовсе (если какой-то другой модуль разрешил выполнение запроса), и 
сами не должны возвращать NGX_OK, если не хотят явно разрешить 
доступ клиенту, минуя проверки других модулей.

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