You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by jo...@apache.org on 2010/06/08 23:17:48 UTC
svn commit: r952828 - in /httpd/httpd/trunk: CHANGES
modules/http/http_request.c
Author: jorton
Date: Tue Jun 8 21:17:48 2010
New Revision: 952828
URL: http://svn.apache.org/viewvc?rev=952828&view=rev
Log:
* 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
Modified:
httpd/httpd/trunk/CHANGES
httpd/httpd/trunk/modules/http/http_request.c
Modified: httpd/httpd/trunk/CHANGES
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/CHANGES?rev=952828&r1=952827&r2=952828&view=diff
==============================================================================
--- httpd/httpd/trunk/CHANGES [utf-8] (original)
+++ httpd/httpd/trunk/CHANGES [utf-8] Tue Jun 8 21:17:48 2010
@@ -28,6 +28,10 @@ Changes with Apache 2.3.6
processing is completed, avoiding orphaned callback pointers.
[Brett Gervasoni <brettg senseofsecurity.com>, Jeff Trawick]
+ *) core: Adjust the output filter chain correctly in an internal
+ redirect from a subrequest, preserving filters from the main
+ request as necessary. PR 17629. [Joe Orton]
+
*) mod_cache: Explicitly allow cache implementations to cache a 206 Partial
Response if they so choose to do so. Previously an attempt to cache a 206
was arbitrarily allowed if the response contained an Expires or
Modified: httpd/httpd/trunk/modules/http/http_request.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http/http_request.c?rev=952828&r1=952827&r2=952828&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http/http_request.c (original)
+++ httpd/httpd/trunk/modules/http/http_request.c Tue Jun 8 21:17:48 2010
@@ -460,16 +460,46 @@ static request_rec *internal_internal_re
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);