summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Covener <covener@apache.org>2015-08-28 00:55:52 +0200
committerEric Covener <covener@apache.org>2015-08-28 00:55:52 +0200
commitf7a34707da4f9924cdf50fd73223d0cfb4dc9603 (patch)
treed624c76ba0c14659123d46f9ce56f3bbae6f0f1f
parentgiving ap_array_index a start parameter, adding ap_array_contains (diff)
downloadapache2-f7a34707da4f9924cdf50fd73223d0cfb4dc9603.tar.xz
apache2-f7a34707da4f9924cdf50fd73223d0cfb4dc9603.zip
avoid adding multiple subrequest filters when there are nested subrequests.
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
-rw-r--r--CHANGES3
-rw-r--r--modules/http/http_request.c12
-rw-r--r--server/request.c13
3 files changed, 24 insertions, 4 deletions
diff --git a/CHANGES b/CHANGES
index 0420ab900c..af36d7e4cd 100644
--- 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
diff --git a/modules/http/http_request.c b/modules/http/http_request.c
index 70bf2937c0..03567f4892 100644
--- a/modules/http/http_request.c
+++ b/modules/http/http_request.c
@@ -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 {
/*
diff --git a/server/request.c b/server/request.c
index fa84c1ab32..e86bb892b4 100644
--- a/server/request.c
+++ b/server/request.c
@@ -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