diff options
Diffstat (limited to '')
| -rw-r--r-- | src/http/ngx_http_request.c | 53 | ||||
| -rw-r--r-- | src/http/ngx_http_request.h | 1 | ||||
| -rw-r--r-- | src/http/ngx_http_write_filter.c | 12 |
3 files changed, 50 insertions, 16 deletions
diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c index 0f30a3177..814e582e8 100644 --- a/src/http/ngx_http_request.c +++ b/src/http/ngx_http_request.c @@ -1050,13 +1050,15 @@ static void ngx_http_set_write_handler(ngx_http_request_t *r) wev = r->connection->write; wev->event_handler = ngx_http_writer; - if (wev->delayed && wev->ready) { + if (wev->ready && r->delayed) { return; } clcf = ngx_http_get_module_loc_conf(r->main ? r->main : r, ngx_http_core_module); - ngx_add_timer(wev, clcf->send_timeout); + if (!r->delayed) { + ngx_add_timer(wev, clcf->send_timeout); + } wev->available = clcf->send_lowat; if (ngx_handle_write_event(wev, NGX_LOWAT_EVENT) == NGX_ERROR) { @@ -1080,15 +1082,36 @@ void ngx_http_writer(ngx_event_t *wev) c = wev->data; r = c->data; -#if 0 /* TODO: THINK */ - if (wev->delayed) { - return; - } -#endif - if (wev->timedout) { - ngx_http_client_error(r, 0, NGX_HTTP_REQUEST_TIME_OUT); - return; + if (!r->delayed) { + ngx_http_client_error(r, 0, NGX_HTTP_REQUEST_TIME_OUT); + return; + } + + wev->timedout = 0; + r->delayed = 0; + + if (!wev->ready) { + clcf = ngx_http_get_module_loc_conf(r->main ? r->main : r, + ngx_http_core_module); + ngx_add_timer(wev, clcf->send_timeout); + + wev->available = clcf->send_lowat; + + if (ngx_handle_write_event(wev, NGX_LOWAT_EVENT) == NGX_ERROR) { + ngx_http_close_request(r, 0); + ngx_http_close_connection(r->connection); + } + + return; + } + + } else { + if (r->delayed) { + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, wev->log, 0, + "http writer delayed"); + return; + } } rc = ngx_http_output_filter(r, NULL); @@ -1097,13 +1120,15 @@ void ngx_http_writer(ngx_event_t *wev) "http writer output filter: %d", rc); if (rc == NGX_AGAIN) { - if (!wev->ready) { - clcf = ngx_http_get_module_loc_conf(r->main ? r->main : r, - ngx_http_core_module); + clcf = ngx_http_get_module_loc_conf(r->main ? r->main : r, + ngx_http_core_module); + if (!wev->ready && !r->delayed) { ngx_add_timer(wev, clcf->send_timeout); } - if (ngx_handle_level_write_event(wev) == NGX_ERROR) { + wev->available = clcf->send_lowat; + + if (ngx_handle_write_event(wev, NGX_LOWAT_EVENT) == NGX_ERROR) { ngx_http_close_request(r, 0); ngx_http_close_connection(r->connection); } diff --git a/src/http/ngx_http_request.h b/src/http/ngx_http_request.h index 52e110af7..7054d92e5 100644 --- a/src/http/ngx_http_request.h +++ b/src/http/ngx_http_request.h @@ -284,6 +284,7 @@ struct ngx_http_request_s { /* can we use sendfile ? */ unsigned sendfile:1; + unsigned delayed:1; unsigned chunked:1; unsigned header_only:1; unsigned keepalive:1; diff --git a/src/http/ngx_http_write_filter.c b/src/http/ngx_http_write_filter.c index b0e47371b..bdef48b1b 100644 --- a/src/http/ngx_http_write_filter.c +++ b/src/http/ngx_http_write_filter.c @@ -69,7 +69,7 @@ ngx_module_t ngx_http_write_filter_module = { ngx_int_t ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in) { int last; - off_t size, flush; + off_t size, flush, sent; ngx_chain_t *cl, *ln, **ll, *chain; ngx_http_write_filter_ctx_t *ctx; ngx_http_write_filter_conf_t *conf; @@ -138,7 +138,7 @@ ngx_int_t ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in) return NGX_OK; } - if (r->connection->write->delayed) { + if (r->delayed) { return NGX_AGAIN; } @@ -150,11 +150,19 @@ ngx_int_t ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in) return NGX_OK; } + sent = r->connection->sent; + chain = ngx_write_chain(r->connection, ctx->out); ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "http write filter %X", chain); +#if 1 + sent = r->connection->sent - sent; + r->delayed = 1; + ngx_add_timer(r->connection->write, sent * 1000 / (4 * 1024)); +#endif + if (chain == NGX_CHAIN_ERROR) { return NGX_ERROR; } |
