ngx_http_read_client_request_body() causing random timeouts

Srebrenko Šehić ssehic at gmail.com
Tue May 31 12:08:13 MSD 2011


Hi,

I've been trying to identify what is causing timeouts towards the
client when a POST request is sent to nginx. I have a custom module
that reads the POST payload and runs in ACCESS phase. It's based on
nginx-form-input module from agentz.

Normally, the modules works OK, but it sometimes times out and nginx
logs the following:

2011/05/31 09:31:16 [alert] 25731#0: *1 zero size buf in output t:1
r:0 f:0 0000000204DFD000 0000000204DFD000-0000000204DFD000
0000000000000000 0-0 while sending request to upstream, client:
192.168.0.27, server: 192.168.0.27, request: "POST /slurp_md5.php
HTTP/1.1", upstream: "http://192.168.0.9:80/slurp_md5.php", host:
"192.168.0.27"

I've noticed that this only happens with keep-alive connections.

Can anybody shed some light on this? I've looked at other modules and
nginx core, but can't seem to figure what could be causing this.

Thanks. Code for the sample module is enclosed below. nginx is vanilla
1.0.3 (with perl module compiled).

Cheers,
Srebrenko

---- module source code ----

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

static ngx_int_t ngx_http_dummy_post_read_init(ngx_conf_t *cf);
static ngx_int_t ngx_http_dummy_post_read_access_handler(ngx_http_request_t *r);

typedef struct {
    ngx_flag_t    done:1;
    ngx_flag_t    waiting_more_body:1;
} ngx_http_dummy_post_read_ctx_t;

static ngx_http_module_t  ngx_http_dummy_post_read_module_ctx = {
    NULL,                                  /* preconfiguration */
    ngx_http_dummy_post_read_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_post_read_module = {
    NGX_MODULE_V1,
    &ngx_http_dummy_post_read_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 */
    NGX_MODULE_V1_PADDING
};

void
ngx_http_dummy_post_read_payload_handler(ngx_http_request_t *r)
{
    ngx_http_dummy_post_read_ctx_t     *ctx;

    r->read_event_handler = ngx_http_request_empty_handler;

    ctx = ngx_http_get_module_ctx(r, ngx_http_dummy_post_read_module);

    ctx->done = 1;

    r->main->count--;

    if (ctx->waiting_more_body) {
        ctx->waiting_more_body = 0;

        ngx_http_core_run_phases(r);
    }
}

static ngx_int_t
ngx_http_dummy_post_read_access_handler(ngx_http_request_t *r)
{
    ngx_int_t                          rc;
    ngx_http_dummy_post_read_ctx_t *ctx;

    ctx = ngx_http_get_module_ctx(r, ngx_http_dummy_post_read_module);

    if (ctx != NULL) {

        if (ctx->done) {
            return NGX_DECLINED;
        }

        return NGX_DONE;
    }

    if (r->method != NGX_HTTP_POST) {
        return NGX_DECLINED;
    }

    ctx = ngx_palloc(r->pool, sizeof(ngx_http_dummy_post_read_ctx_t));

    if (ctx == NULL) {
        ngx_http_finalize_request(r, NGX_ERROR);
        return NGX_ERROR;
    }

    ngx_http_set_ctx(r, ctx, ngx_http_dummy_post_read_module);

    rc = ngx_http_read_client_request_body(r,
ngx_http_dummy_post_read_payload_handler);

    if (rc == NGX_ERROR || rc >= NGX_HTTP_SPECIAL_RESPONSE) {
        return rc;
    }

    if (rc == NGX_AGAIN) {
        ctx->waiting_more_body = 1;

        return NGX_DONE;
    }

    return NGX_DECLINED;
}

static ngx_int_t
ngx_http_dummy_post_read_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_post_read_access_handler;

    return NGX_OK;
}



More information about the nginx-devel mailing list