# HG changeset patch # User Igor Sysoev # Date 1186484007 0 # Node ID fdea12ffb24a2d0d6007159bf07a1903a2639b59 # Parent 2cc9b6651f759824c24757ff9e2d1251d52a7d6d discard request body before going to keep-alive state and use lingering timeouts diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c --- a/src/http/ngx_http_request.c +++ b/src/http/ngx_http_request.c @@ -1921,8 +1921,16 @@ ngx_http_set_keepalive(ngx_http_request_ c = r->connection; rev = c->read; + clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "set http keepalive handler"); + if (r->discard_body) { + r->lingering_time = ngx_time() + (time_t) (clcf->lingering_time / 1000); + ngx_add_timer(rev, clcf->lingering_timeout); + return; + } + c->log->action = "closing request"; hc = r->http_connection; @@ -1966,8 +1974,6 @@ ngx_http_set_keepalive(ngx_http_request_ } } - clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); - ngx_http_request_done(r, 0); c->data = hc; diff --git a/src/http/ngx_http_request_body.c b/src/http/ngx_http_request_body.c --- a/src/http/ngx_http_request_body.c +++ b/src/http/ngx_http_request_body.c @@ -442,12 +442,12 @@ ngx_http_discard_request_body(ngx_http_r ngx_del_timer(rev); } - r->discard_body = 1; - if (r->headers_in.content_length_n <= 0) { return NGX_OK; } + r->discard_body = 1; + size = r->header_in->last - r->header_in->pos; if (size) { @@ -467,26 +467,75 @@ ngx_http_discard_request_body(ngx_http_r return NGX_HTTP_INTERNAL_SERVER_ERROR; } - return ngx_http_read_discarded_request_body(r); + (void) ngx_http_read_discarded_request_body(r); + + return NGX_OK; } static void ngx_http_read_discarded_request_body_handler(ngx_http_request_t *r) { - ngx_int_t rc; + ngx_int_t rc; + ngx_msec_t timer; + ngx_event_t *rev; + ngx_connection_t *c; + ngx_http_core_loc_conf_t *clcf; + + c = r->connection; + rev = c->read; + + if (rev->timedout) { + c->timedout = 1; + c->error = 1; + ngx_http_finalize_request(r, 0); + return; + } + + if (r->lingering_time) { + timer = r->lingering_time - ngx_time(); + + if (timer <= 0) { + r->discard_body = 0; + ngx_http_finalize_request(r, 0); + return; + } + + } else { + timer = 0; + } rc = ngx_http_read_discarded_request_body(r); - if (rc == NGX_AGAIN) { - if (ngx_handle_read_event(r->connection->read, 0) == NGX_ERROR) { - ngx_http_finalize_request(r, rc); - return; + if (rc == NGX_OK) { + + r->discard_body = 0; + + if (r->done) { + ngx_http_finalize_request(r, 0); } + + return; } - if (rc != NGX_OK) { + /* rc == NGX_AGAIN */ + + if (ngx_handle_read_event(rev, 0) == NGX_ERROR) { ngx_http_finalize_request(r, rc); + return; + } + + if (timer) { + + clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); + + timer *= 1000; + + if (timer > clcf->lingering_timeout) { + timer = clcf->lingering_timeout; + } + + ngx_add_timer(rev, timer); } } @@ -514,14 +563,7 @@ ngx_http_read_discarded_request_body(ngx n = r->connection->recv(r->connection, buffer, size); if (n == NGX_ERROR) { - r->connection->error = 1; - - /* - * if a client request body is discarded then we already set - * some HTTP response code for client and we can ignore the error - */ - return NGX_OK; } @@ -533,5 +575,5 @@ ngx_http_read_discarded_request_body(ngx } while (r->connection->read->ready); - return NGX_OK; + return NGX_AGAIN; }