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.
diff --git a/src/http/modules/ngx_http_addition_filter_module.c b/src/http/modules/ngx_http_addition_filter_module.c
index 2fad0e5..e546f0d 100644
--- 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_clear_accept_ranges(r);
     ngx_http_weak_etag(r);
 
+    r->preserve_body = 1;
+
     return ngx_http_next_header_filter(r);
 }
 
diff --git a/src/http/modules/ngx_http_slice_filter_module.c b/src/http/modules/ngx_http_slice_filter_module.c
index 7b9de27..c1edbca 100644
--- a/src/http/modules/ngx_http_slice_filter_module.c
+++ b/src/http/modules/ngx_http_slice_filter_module.c
@@ -190,6 +190,8 @@
         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
diff --git a/src/http/modules/ngx_http_ssi_filter_module.c b/src/http/modules/ngx_http_ssi_filter_module.c
index b92ad4c..b09ce20 100644
--- 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_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);
diff --git a/src/http/ngx_http_request.h b/src/http/ngx_http_request.h
index f7f3e97..421004a 100644
--- a/src/http/ngx_http_request.h
+++ b/src/http/ngx_http_request.h
@@ -537,6 +537,7 @@
     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;
diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c
index cca417d..fb32092 100644
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -1077,6 +1077,10 @@
         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 @@
         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;
     }