ngx_http_read_client_request_body() and ACCESS_PHASE handler

agentzh agentzh at gmail.com
Fri Apr 23 12:54:40 MSD 2010


On Thu, Apr 22, 2010 at 10:19 PM, Srebrenko Šehić <ssehic at gmail.com> wrote:
> static ngx_int_t
> ngx_http_dummy_access_handler(ngx_http_request_t *r)
> {
>    if (r->method != NGX_HTTP_POST) {
>        return NGX_OK;
>    }
>
>    return ngx_http_read_client_request_body(r, ngx_http_dummy_payload_handler);
> }

When your rewrite/access handler returns NGX_AGAIN or NGX_DONE, your
handler will get called again and again (mostly triggered by writable
event and other hooks). (See ngx_http_core_module.c:1059.)

When you handler returns NGX_OK, it means skipping all the handlers in
the current rewrite/access phase, and giving the control to the first
handler in the next phase. Normally we just return NGX_DONE here to
let nginx's phase engine run the next handler in the current phase (if
any).

I think you should call ngx_http_read_client_request_body in your
handler *only once*. If it gets called a second time, it will simply
returns NGX_OK. (See ngx_http_request_body.c:43.)

To be more specific, we need a request ctx struct to track the current
state (e.g., ctx->ready). In the "post_read" callback fed into the
ngx_http_read_client_request_body function call, you can set your
ctx->ready state and call ngx_http_core_run_phases eagerly, so that
your rewrite/access handler can return NGX_DECLINED to give control
back to the next handler in the current phase.

You see, the return values of these two functions have completely
different meanings. So simply returning the return value of
ngx_http_read_client_request_body from within an access handler does
not make any sense :)

Behind the scene, on the event model level, the core run phases
function is triggered by the r->write_event_handler while the read
client body thingy is triggered by r->read_event_handler. They're not
conflicting, I think.

We're currently working on a module named ngx_form_input that calls
ngx_http_read_client_request_body in a rewrite phase handler ;) We're
passing all of our existing tests at the moment :)

Hope this helps,
-agentzh



More information about the nginx-devel mailing list