Reading body during the REWRITE phase ?
Maxim Dounin
mdounin at mdounin.ru
Fri Jan 15 15:53:04 UTC 2016
Hello!
On Fri, Jan 15, 2016 at 03:01:06PM +0100, Thibault Koechlin wrote:
> Hi,
>
> I have a module (naxsi) that reads the body during the REWRITE phase, in
> the exact same way that ngx_form_input does :
> https://github.com/calio/form-input-nginx-module.
>
> When used with auth_request (or maybe other modules, but that's the
> first time I encounter this issue within a few years of usage), there is
> no request made to the upstream if the request is made using POST/PUT
> and the body is bigger than client_body_buffer_size.
>
> For the simplicity of the example, we'll assume I'm talking about
> ngx_form_input (behaviour is the same, except code is way shorter).
>
> The user reporting me the bug opened a ticket :
> https://trac.nginx.org/nginx/ticket/801. It is possible to replace naxsi
> with ngx_for_input and obtain the same results.
>
> From Maxim's reply, it seems I failed to properly restore request
> handlers after reading body.
>
> What would be (if there is any) the proper way to read body within
> REWRITE phase ? Is there any example/existing module that does such so I
> can understand what am I doing wrong ? (In the past, I always thought
> ngx_form_input was the reference one).
No modules in nginx itself attempt to read body before it knows
it'll handle the request. So I don't think there are examples of
doing this correctly.
The problem as seen from debug logs is that reading body will
reset request handlers, including r->write_event_handler, which is
used to continue processing of request phases. That is, as a
minimum you'll have to do something like:
r->write_event_handler = ngx_http_core_run_phases;
ngx_http_core_run_phases(r);
when you restart processing of phases after the request body is
read. As of now your code seems to call ngx_http_core_run_phases()
without restoring the r->write_event_handler.
Similar code can be seen in ngx_http_finalize_request() when
processing of phases is restared after a content handler returned
NGX_DECLINED, see src/http/ngx_http_request.c:
if (rc == NGX_DECLINED) {
r->content_handler = NULL;
r->write_event_handler = ngx_http_core_run_phases;
ngx_http_core_run_phases(r);
return;
}
Hope this helps.
--
Maxim Dounin
http://nginx.org/
More information about the nginx-devel
mailing list