changeset 7070:f583559aadc7

Upstream: keep request body file from removal if requested. The new request flag "preserve_body" indicates that the request body file should not be removed by the upstream module because it may be used later by a subrequest. The flag is set by the SSI (ticket #585), addition and slice modules. Additionally, it is also set by the upstream module when a background cache update subrequest is started to prevent the request body file removal after an internal redirect. Only the main request is now allowed to remove the file.
author Roman Arutyunyan <arut@nginx.com>
date Wed, 19 Jul 2017 20:38:17 +0300
parents 863b862534d7
children cce6936ed2f4
files src/http/modules/ngx_http_addition_filter_module.c src/http/modules/ngx_http_slice_filter_module.c src/http/modules/ngx_http_ssi_filter_module.c src/http/ngx_http_request.h src/http/ngx_http_upstream.c
diffstat 5 files changed, 14 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/src/http/modules/ngx_http_addition_filter_module.c
+++ b/src/http/modules/ngx_http_addition_filter_module.c
@@ -123,6 +123,8 @@ ngx_http_addition_header_filter(ngx_http
     ngx_http_clear_accept_ranges(r);
     ngx_http_weak_etag(r);
 
+    r->preserve_body = 1;
+
     return ngx_http_next_header_filter(r);
 }
 
--- a/src/http/modules/ngx_http_slice_filter_module.c
+++ b/src/http/modules/ngx_http_slice_filter_module.c
@@ -190,6 +190,8 @@ ngx_http_slice_header_filter(ngx_http_re
         return rc;
     }
 
+    r->preserve_body = 1;
+
     if (r->headers_out.status == NGX_HTTP_PARTIAL_CONTENT) {
         if (ctx->start + (off_t) slcf->size <= r->headers_out.content_offset) {
             ctx->start = slcf->size
--- a/src/http/modules/ngx_http_ssi_filter_module.c
+++ b/src/http/modules/ngx_http_ssi_filter_module.c
@@ -370,6 +370,8 @@ ngx_http_ssi_header_filter(ngx_http_requ
         ngx_http_clear_content_length(r);
         ngx_http_clear_accept_ranges(r);
 
+        r->preserve_body = 1;
+
         if (!slcf->last_modified) {
             ngx_http_clear_last_modified(r);
             ngx_http_clear_etag(r);
--- a/src/http/ngx_http_request.h
+++ b/src/http/ngx_http_request.h
@@ -537,6 +537,7 @@ struct ngx_http_request_s {
     unsigned                          main_filter_need_in_memory:1;
     unsigned                          filter_need_in_memory:1;
     unsigned                          filter_need_temporary:1;
+    unsigned                          preserve_body:1;
     unsigned                          allow_ranges:1;
     unsigned                          subrequest_ranges:1;
     unsigned                          single_range:1;
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -1077,6 +1077,10 @@ ngx_http_upstream_cache_background_updat
         return NGX_OK;
     }
 
+    if (r == r->main) {
+        r->preserve_body = 1;
+    }
+
     if (ngx_http_subrequest(r, &r->uri, &r->args, &sr, NULL,
                             NGX_HTTP_SUBREQUEST_CLONE
                             |NGX_HTTP_SUBREQUEST_BACKGROUND)
@@ -2857,7 +2861,9 @@ ngx_http_upstream_send_response(ngx_http
         u->pipe->downstream_error = 1;
     }
 
-    if (r->request_body && r->request_body->temp_file) {
+    if (r->request_body && r->request_body->temp_file
+        && r == r->main && !r->preserve_body)
+    {
         ngx_pool_run_cleanup_file(r->pool, r->request_body->temp_file->file.fd);
         r->request_body->temp_file->file.fd = NGX_INVALID_FILE;
     }