summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorSergey Kandaurov <pluknet@nginx.com>2017-10-10 01:04:54 +0300
committerSergey Kandaurov <pluknet@nginx.com>2017-10-10 01:04:54 +0300
commit661e40864f404b91ee38b3326e4e0e65f29417ec (patch)
tree34ef618f47da843c2d3d7dd4a80a55c7e4dfdfb1
parent0737e6d841d87e734dfb980a59094c26621bb80d (diff)
downloadnginx-661e40864f404b91ee38b3326e4e0e65f29417ec.tar.gz
nginx-661e40864f404b91ee38b3326e4e0e65f29417ec.tar.bz2
Upstream: fixed error handling of stale and revalidated cache send.
The NGX_DONE value returned from ngx_http_upstream_cache_send() indicates that upstream was already finalized in ngx_http_upstream_process_headers(). It was treated as a generic error which resulted in duplicate finalization. Handled NGX_HTTP_UPSTREAM_INVALID_HEADER from ngx_http_upstream_cache_send(). Previously, it could return within ngx_http_upstream_finalize_request(), and since it's below NGX_HTTP_SPECIAL_RESPONSE, a client connection could stuck.
-rw-r--r--src/http/ngx_http_upstream.c42
1 files changed, 36 insertions, 6 deletions
diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c
index 1f6a8fe0c..2ea521b07 100644
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -2404,9 +2404,20 @@ ngx_http_upstream_test_next(ngx_http_request_t *r, ngx_http_upstream_t *u)
rc = u->reinit_request(r);
- if (rc == NGX_OK) {
- u->cache_status = NGX_HTTP_CACHE_STALE;
- rc = ngx_http_upstream_cache_send(r, u);
+ if (rc != NGX_OK) {
+ ngx_http_upstream_finalize_request(r, u, rc);
+ return NGX_OK;
+ }
+
+ u->cache_status = NGX_HTTP_CACHE_STALE;
+ rc = ngx_http_upstream_cache_send(r, u);
+
+ if (rc == NGX_DONE) {
+ return NGX_OK;
+ }
+
+ if (rc == NGX_HTTP_UPSTREAM_INVALID_HEADER) {
+ rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
}
ngx_http_upstream_finalize_request(r, u, rc);
@@ -2444,6 +2455,14 @@ ngx_http_upstream_test_next(ngx_http_request_t *r, ngx_http_upstream_t *u)
u->cache_status = NGX_HTTP_CACHE_REVALIDATED;
rc = ngx_http_upstream_cache_send(r, u);
+ if (rc == NGX_DONE) {
+ return NGX_OK;
+ }
+
+ if (rc == NGX_HTTP_UPSTREAM_INVALID_HEADER) {
+ rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
+ }
+
if (valid == 0) {
valid = r->cache->valid_sec;
updating = r->cache->updating_sec;
@@ -4150,9 +4169,20 @@ ngx_http_upstream_next(ngx_http_request_t *r, ngx_http_upstream_t *u,
rc = u->reinit_request(r);
- if (rc == NGX_OK) {
- u->cache_status = NGX_HTTP_CACHE_STALE;
- rc = ngx_http_upstream_cache_send(r, u);
+ if (rc != NGX_OK) {
+ ngx_http_upstream_finalize_request(r, u, rc);
+ return;
+ }
+
+ u->cache_status = NGX_HTTP_CACHE_STALE;
+ rc = ngx_http_upstream_cache_send(r, u);
+
+ if (rc == NGX_DONE) {
+ return;
+ }
+
+ if (rc == NGX_HTTP_UPSTREAM_INVALID_HEADER) {
+ rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
}
ngx_http_upstream_finalize_request(r, u, rc);