57 lines
2.1 KiB
C
57 lines
2.1 KiB
C
# HG changeset patch
|
|
# User Yichun Zhang <agentzh@gmail.com>
|
|
# 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);
|