<div dir="ltr">Большое спасибо, Максим! Тем временем, я обратил внимание на то, каким образом в openresty реализован фукнционал сдвига выполнения модуля в самый конец фазы:<br><br><div><font face="monospace, monospace"> if (!lmcf->postponed_to_access_phase_end) {</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace"> lmcf->postponed_to_access_phase_end = 1;</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace"> cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace"> ph = cmcf->phase_engine.handlers;</font></div><div><font face="monospace, monospace"> cur_ph = &ph[r->phase_handler];</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace"> /* we should skip the post_access phase handler here too */</font></div><div><font face="monospace, monospace"> last_ph = &ph[cur_ph->next - 2];</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace"> dd("ph cur: %d, ph next: %d", (int) r->phase_handler,</font></div><div><font face="monospace, monospace"> (int) (cur_ph->next - 2));</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">#if 0</font></div><div><font face="monospace, monospace"> if (cur_ph == last_ph) {</font></div><div><font face="monospace, monospace"> dd("XXX our handler is already the last access phase handler");</font></div><div><font face="monospace, monospace"> }</font></div><div><font face="monospace, monospace">#endif</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace"> if (cur_ph < last_ph) {</font></div><div><font face="monospace, monospace"> dd("swaping the contents of cur_ph and last_ph...");</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace"> tmp = *cur_ph;</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace"> memmove(cur_ph, cur_ph + 1,</font></div><div><font face="monospace, monospace"> (last_ph - cur_ph) * sizeof (ngx_http_phase_handler_t));</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace"> *last_ph = tmp;</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace"> r->phase_handler--; /* redo the current ph */</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace"> return NGX_DECLINED;</font></div><div><font face="monospace, monospace"> }</font></div><div><font face="monospace, monospace"> }</font></div><br><div>Актуален ли данный подход? Это хак, недокументированная возможность или широкоизвестная в узких кругах функциональность?</div></div><div class="gmail_extra"><br><div class="gmail_quote">22 февраля 2018 г., 18:08 пользователь Maxim Dounin <span dir="ltr"><<a href="mailto:mdounin@mdounin.ru" target="_blank">mdounin@mdounin.ru</a>></span> написал:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hello!<br>
<span class=""><br>
On Thu, Feb 22, 2018 at 03:10:04PM +0200, Igor Savenko wrote:<br>
<br>
> Добрый день! Есть ли способ указать, что данный хендлер (в моем случае<br>
> ModSecurity handler в access-phase) должен вызываться последним Или после<br>
> определенного хендлера? Или, как воркэраунд, в данном модуле проверить<br>
> определенное условие, и если оно не выставлено, выдать NGX_DECLINED, чтобы<br>
> потом этот модуль в акцесс-фазе был вызван вновь, после того, как остальные<br>
> хендлеры уже отработали?<br>
<br>
</span>Порядок вызова модулей в фазе определяется при сборке - сначала<br>
вызываются обработчики тех модулей, которые идут в списке модулей<br>
последними (и соответственно добавили свой обработчик в фазу<br>
последними). Соответственно в access-фазе сторонние модули в<br>
общем случае будут вызываться раньше встроенных, а взаимный<br>
порядок сторонних модулей определяется порядком опций --add-module.<br>
<br>
Чуть больше контроля есть при динамической загрузке - с помощью<br>
переменной ngx_module_order можно задать произвольную позицию,<br>
куда следует загружать модуль.<br>
<br>
Но вообще, если порядок вдруг важен - стоит подумать о том,<br>
правильно ли выбрана фаза. Если хочется позвать обработчик<br>
последним - то, возможно, вам нужна другая фаза.<br>
<span class=""><br>
> Влияет ли на этот фукнционал состояние директивы satisfy ?<br>
<br>
</span>Директива satisfy определяет, будет ли требоватся разрешение на<br>
выполнение от всех модулей access-фазы (all) или хотя бы от одного<br>
(any). В случае "satisfy all" все модули фазы вызываются<br>
последовательно, если хотя бы один из них вернёт ошибку -<br>
пользователю будет возвращена ошибка. В случае "satisfy any" все<br>
модули фазы вызываются последовательно, пока хотя бы один из них<br>
не разрешит выполнение запроса. После этого обработка запроса<br>
переходит к следующей фазе, остальные модули фазы не вызываются.<br>
<br>
Вышеописанное следует учитывать при создании модулей для<br>
access-фазы - в случае "satisfy any" они могут не быть вызваны<br>
вовсе (если какой-то другой модуль разрешил выполнение запроса), и<br>
сами не должны возвращать NGX_OK, если не хотят явно разрешить<br>
доступ клиенту, минуя проверки других модулей.<br>
<span class="HOEnZb"><font color="#888888"><br>
--<br>
Maxim Dounin<br>
<a href="http://mdounin.ru/" rel="noreferrer" target="_blank">http://mdounin.ru/</a><br>
______________________________<wbr>_________________<br>
nginx-ru mailing list<br>
<a href="mailto:nginx-ru@nginx.org">nginx-ru@nginx.org</a><br>
<a href="http://mailman.nginx.org/mailman/listinfo/nginx-ru" rel="noreferrer" target="_blank">http://mailman.nginx.org/<wbr>mailman/listinfo/nginx-ru</a></font></span></blockquote></div><br></div>