diff options
author | Joe Orton <jorton@apache.org> | 2010-06-08 23:17:48 +0200 |
---|---|---|
committer | Joe Orton <jorton@apache.org> | 2010-06-08 23:17:48 +0200 |
commit | e446077b99758a271ec8ba8bffdcb671b20d8714 (patch) | |
tree | cb2dec6c604adfa4bfe550cb9e39829bd97d1f24 /modules/http | |
parent | mod_cache: Explicitly allow cache implementations to cache a 206 Partial (diff) | |
download | apache2-e446077b99758a271ec8ba8bffdcb671b20d8714.tar.xz apache2-e446077b99758a271ec8ba8bffdcb671b20d8714.zip |
* modules/http/http_request.c (internal_internal_redirect): For a
subrequest, preserve any filters in the output filter chain which
were not specific to the subrequest across the redirect (where
f->r does not point to the subreq's request_rec).
PR: 17629
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@952828 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'modules/http')
-rw-r--r-- | modules/http/http_request.c | 44 |
1 files changed, 37 insertions, 7 deletions
diff --git a/modules/http/http_request.c b/modules/http/http_request.c index d2f8ba44fe..f17983303e 100644 --- a/modules/http/http_request.c +++ b/modules/http/http_request.c @@ -460,16 +460,46 @@ static request_rec *internal_internal_redirect(const char *new_uri, new->proto_output_filters = r->proto_output_filters; new->proto_input_filters = r->proto_input_filters; - new->output_filters = new->proto_output_filters; new->input_filters = new->proto_input_filters; if (new->main) { - /* Add back the subrequest filter, which we lost when - * we set output_filters to include only the protocol - * output filters from the original request. - */ - ap_add_output_filter_handle(ap_subreq_core_filter_handle, - NULL, new, new->connection); + ap_filter_t *f, *nextf; + + /* If this is a subrequest, the filter chain may contain a + * mixture of filters specific to the old request (r), and + * some inherited from r->main. Here, inherit that filter + * chain, and remove all those which are specific to the old + * request; ensuring the subreq filter is left in place. */ + new->output_filters = r->output_filters; + + f = new->output_filters; + do { + nextf = f->next; + + if (f->r == r && f->frec != ap_subreq_core_filter_handle) { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, + "dropping filter '%s' in internal redirect from %s to %s", + f->frec->name, r->unparsed_uri, new_uri); + + /* To remove the filter, first set f->r to the *new* + * request_rec, so that ->output_filters on 'new' is + * changed (if necessary) when removing the filter. */ + f->r = new; + ap_remove_output_filter(f); + } + + f = nextf; + + /* Stop at the protocol filters. If a protocol filter has + * been newly installed for this resource, better leave it + * in place, though it's probably a misconfiguration or + * filter bug to get into this state. */ + } while (f && f != new->proto_output_filters); + } + else { + /* If this is not a subrequest, clear out all + * resource-specific filters. */ + new->output_filters = new->proto_output_filters; } update_r_in_filters(new->input_filters, r, new); |