]> granicus.if.org Git - apache/commitdiff
avoid adding multiple subrequest filters when there are nested subrequests.
authorEric Covener <covener@apache.org>
Thu, 27 Aug 2015 22:55:52 +0000 (22:55 +0000)
committerEric Covener <covener@apache.org>
Thu, 27 Aug 2015 22:55:52 +0000 (22:55 +0000)
Multiple copies of the filter were not stripped properly
during ap_fast_internal_redirect() which left the EOS buckets
stripped out of the brigade. This results in the end-chunk never
going out on the wire for a chunked response.

observed with mainreq -> directoryindex -> FallbackResource

PR58292

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1698239 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
modules/http/http_request.c
server/request.c

diff --git a/CHANGES b/CHANGES
index 0420ab900cd234d85bf87082601261ebc86cd86e..af36d7e4cdb4ac4addb29a167de149374f757352 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,9 @@
                                                          -*- coding: utf-8 -*-
 Changes with Apache 2.5.0
 
+  *) mod_dir: Responses that go through "FallbackResource" might appear to
+     hang due to unterminated chunked encoding. PR58292. [Eric Covener]
+
   *) mod_socache_memcache: Add the 'MemcacheConnTTL' directive to control how 
      long to keep idle connections with the memcache server(s).
      Change default value from 600 usec (!) to 15 sec. PR 58091
index 70bf2937c08dbd6cdbb346c50267ce25d5ab6146..03567f48923e624fc5c386289838a381479b0db5 100644 (file)
@@ -613,8 +613,16 @@ AP_DECLARE(void) ap_internal_fast_redirect(request_rec *rr, request_rec *r)
     update_r_in_filters(r->output_filters, rr, r);
 
     if (r->main) {
-        ap_add_output_filter_handle(ap_subreq_core_filter_handle,
-                                    NULL, r, r->connection);
+        ap_filter_t *next = r->output_filters;
+        while (next && (next != r->proto_output_filters)) {
+            if (next->frec == ap_subreq_core_filter_handle) {
+                break;
+            }
+        }
+        if (!next || next == r->proto_output_filters) {
+            ap_add_output_filter_handle(ap_subreq_core_filter_handle,
+                                        NULL, r, r->connection);
+        }
     }
     else {
         /*
index fa84c1ab3252975ce00d0edb22ab6bdcb09114d7..e86bb892b455b49c18adb0140edb876c7b89452b 100644 (file)
@@ -1964,6 +1964,8 @@ static request_rec *make_sub_request(const request_rec *r,
 
     /* start with the same set of output filters */
     if (next_filter) {
+        ap_filter_t *scan = next_filter;
+
         /* while there are no input filters for a subrequest, we will
          * try to insert some, so if we don't have valid data, the code
          * will seg fault.
@@ -1972,8 +1974,15 @@ static request_rec *make_sub_request(const request_rec *r,
         rnew->proto_input_filters = r->proto_input_filters;
         rnew->output_filters = next_filter;
         rnew->proto_output_filters = r->proto_output_filters;
-        ap_add_output_filter_handle(ap_subreq_core_filter_handle,
-                                    NULL, rnew, rnew->connection);
+        while (scan && (scan != r->proto_output_filters)) {
+            if (scan->frec == ap_subreq_core_filter_handle) {
+                break;
+            }
+        }
+        if (!scan || scan == r->proto_output_filters) {
+            ap_add_output_filter_handle(ap_subreq_core_filter_handle,
+                    NULL, rnew, rnew->connection);
+        }
     }
     else {
         /* If NULL - we are expecting to be internal_fast_redirect'ed