ngx_http_read_client_request_body() and ACCESS_PHASE handler

Srebrenko Šehić ssehic at
Thu Apr 22 18:19:19 MSD 2010

Hi list,

I am trying to get a module working that can read a POST payload from
the client, have a look at it, and pass it on (unchanged) to the

Below is the a sample code I wrote for testing purposes. The code
works as desired for very small POST payloads and with Firefox only.
It doesn't work (even for small payloads) in any other major browser I
tried. The reason for that is that FF sends the POST payload in the
same TCP packet as the HTTP headers - while other browser apparently
send at least 2 packets.

Return code from call to ngx_http_read_client_request_body() is
NGX_AGAIN for non-FF browsers.

What am I doing wrong here?

/usr/local/sbin/nginx -V
nginx version: nginx/0.8.35
TLS SNI support enabled
configure arguments: --prefix=/etc/nginx
--conf-path=/etc/nginx/nginx.conf --sbin-path=/usr/local/sbin/nginx
--pid-path=/var/run/ --lock-path=/var/nginx/tmp/nginx.lock
--error-log-path=/var/log/nginx/error.log --user=_nginx --group=_nginx
--with-http_ssl_module --with-http_stub_status_module --with-debug
--with-ipv6 --with-http_perl_module --with-http_sub_module

#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_http.h>

static ngx_int_t ngx_http_dummy_init(ngx_conf_t *cf);

static ngx_http_module_t  ngx_http_dummy_module_ctx = {
    NULL,                                  /* preconfiguration */
    ngx_http_dummy_init,           /* postconfiguration */
    NULL,                                  /* create main configuration */
    NULL,                                  /* init main configuration */
    NULL,                                  /* create server configuration */
    NULL,                                  /* merge server configuration */
    NULL,                                  /* create location configuration */
    NULL                                   /* merge location configuration */

ngx_module_t  ngx_http_dummy_module = {
    &ngx_http_dummy_module_ctx,            /* module context */
    NULL,                                  /* module directives */
    NGX_HTTP_MODULE,                       /* module type */
    NULL,                                  /* init master */
    NULL,                                  /* init module */
    NULL,                                  /* init process */
    NULL,                                  /* init thread */
    NULL,                                  /* exit thread */
    NULL,                                  /* exit process */
    NULL,                                  /* exit master */

static ngx_int_t ngx_http_dummy_access_handler(ngx_http_request_t *r);

ngx_http_dummy_payload_handler(ngx_http_request_t *r)
    ngx_http_finalize_request(r, NGX_DONE);

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);

static ngx_int_t
ngx_http_dummy_init(ngx_conf_t *cf)
    ngx_http_handler_pt        *h;
    ngx_http_core_main_conf_t  *cmcf;

    cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);

    h = ngx_array_push(&cmcf->phases[NGX_HTTP_ACCESS_PHASE].handlers);
    if (h == NULL) {
        return NGX_ERROR;

    *h = ngx_http_dummy_access_handler;

    return NGX_OK;

More information about the nginx-devel mailing list