BIG requests/responses to POST and post_handler return value

Antoine BONAVITA antoine_bonavita at yahoo.com
Tue Feb 22 12:34:51 MSK 2011


Hello,

I'm trying to write my first module, so bear with me if my question feel silly.
The situation is fairly simple:
- My module accepts GET, POST and HEAD methods.
- My module can return big chunks of data for GET and POST.
- When I'm processing the GET everything is OK.
- When I'm processing a POST which does not trigger saving the body to a temp 
file, everything is OK.
- When I'm processing a POST which triggers saving the body to a temp file, my 
client only gets the first 65536 bytes (confirmed by both a wireshark capture 
and the nginx logs).

Now, I understand nginx is happy when handling GET and "small POST" because 
everything happens in the content handler which returns appropriately 
NGX_AGAIN/NGX_OK/NGX_DONE. I would be happy to do the same with the 
post_handler. Unfortunately the signature of the post_handler (as defined by 
ngx_http_read_client_request_body) is:
typedef void (*ngx_http_client_body_handler_pt)(ngx_http_request_t *r);
and therefore I cannot return NGX_AGAIN (which would be natural).

I'll try to get some "bare-bone" code together to reproduce this but high-level 
it looks like:
ngx_int_t ngx_http_xxx_handler(ngx_http_request_t *r) {
      if (NGX_HTTP_GET == r->method) {
        return ngx_http_xxx_do_get(r);
    } else if (NGX_HTTP_POST == r->method) {
        return ngx_http_xxx_do_post(r);
    }
}

ngx_int_t ngx_http_xxx_do_post(ngx_http_request_t *r) {
   [...]
    rc = ngx_http_read_client_request_body(r, ngx_http_xxx_body_received);

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

    if (rc == NGX_AGAIN) {
        /* It will not call me again, but call the body_received. */
        return NGX_AGAIN;
    }
    if (NGX_OK == rc) {
        ngx_log_debug(NGX_LOG_DEBUG_HTTP, log, 0,
                      "Client request body already read");
        return rc;
    }
    return NGX_HTTP_INTERNAL_SERVER_ERROR;
}

void ngx_http_xxx_body_received(ngx_http_request_t *r)
{
    [...]
    ngx_http_xxx_do_get(r);
}

ngx_int_t ngx_http_xxx_do_get(ngx_http_request_t *r) {
   [...]
    /* Prepare BIG header and response */
    [...]
    rc = ngx_http_send_header(r);
    if (rc != NGX_OK) {
        ngx_log_error(NGX_LOG_ALERT, log, 0,
                              "pb sending header");
        return NGX_HTTP_INTERNAL_SERVER_ERROR;
    }

    return ngx_http_output_filter(r, out_chain);
}

At this point, any help is very much appreciated.

All this is against 0.8.53 but I don't see any difference in 0.9.5 that could 
impact my problem.

Antoine.



      



More information about the nginx-devel mailing list