# HG changeset patch # User Yichun Zhang # Date 1424037188 28800 # Sun Feb 15 13:53:08 2015 -0800 # Node ID aa15033f24da93a2c7c971d5a95ae44ce21754a6 # Parent f3f25ad09deee27485050a75732e5f46ab1b18b3 Upstream: fixed $upstream_response_time for filter_finalize + error_page. ngx_http_upstream_finalize_request() is always called twice when an output filter module calls ngx_http_filter_finalize_request() *and* a custom error page is configured by the error_page directive. This is because 1. ngx_http_filter_finalize_request() triggers calling ngx_http_terminate_request => calling ngx_http_upstream_cleanup => calling ngx_http_upstream_finalize_request 2. ngx_http_internal_redirect() returns NGX_DONE ==> ngx_http_special_response_handler() returns NGX_DONE ==> ngx_http_filter_finalize_request() returns NGX_ERROR ==> ngx_http_send_header() returns NGX_ERROR ==> ngx_http_upstream_send_response() calls ngx_http_upstream_finalize_request() again in the same ngx_http_upstream_send_response() call as 1). This might result in corrupted $upstream_response_time values (close to the absolute timestamp value) when u->state->response_sec happens to be non-zero. This patch ensures that the $upstream_response_time value is only calculated upon the first ngx_http_upstream_finalize_request() invocation. diff -r f3f25ad09dee -r aa15033f24da src/http/ngx_http_upstream.c --- a/src/http/ngx_http_upstream.c Wed Feb 11 20:18:55 2015 +0300 +++ b/src/http/ngx_http_upstream.c Sun Feb 15 13:53:08 2015 -0800 @@ -3744,10 +3744,14 @@ ngx_http_upstream_finalize_request(ngx_h ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "finalize http upstream request: %i", rc); - if (u->cleanup) { - *u->cleanup = NULL; - u->cleanup = NULL; - } + if (u->cleanup == NULL) { + /* the request was already finalized */ + ngx_http_finalize_request(r, NGX_DONE); + return; + } + + *u->cleanup = NULL; + u->cleanup = NULL; if (u->resolved && u->resolved->ctx) { ngx_resolve_name_done(u->resolved->ctx);