On Fri, Mar 01, 2002 at 03:12:27PM -0600, William A. Rowe, Jr. wrote:
> I believe the attached .patch file should resolve our issues with the
> subrequest
> negotiation. Essentially, we want the sub request to build a new filter
> chain if
> we plan on using the subrequest as a 'fast internal redirect'.
>
> This patch does just that, when we fast redirect, we replace the original
> request
> filters with the new request filters. In preparing the request, we go back
> to our
> favorite r->connection filters to start, when we are making the subrequest
> with
> a NULL next_filter.
>
> But the patch is broken. Free beer at ApacheCon 2002 to the first hacker
> who
> untangles the misbehavior that fouls up this patch. Make that hard stuff if
> you
> discover it's a simple bug in my patch :)
>
> One hint. I think our whole "Either Connection or Request" idea of filters
> is
> borked. It really seems that "Either Connection or Protocol or Body" is a
> much
> better model - this bug seems to prove that once again. I think we really
> wanted
> to grab r->http_input_filters and r->protocol_output_filters when we set up
> the
> subreq of next_filter==NULL. But there doesn't appear to be such a thing.
Yup, you're right. We need to add protocol-specific filters that
can be arbitrarily reset. Hint: this is just what reset_filters
does, but its static. Notice that we do this when we are about
to serve an HTTP error - the same concept of a subreq applies to
the error condition.
To prove that, this patch works for me. So, what I think we should
do is add a protocol hook that says, "add all of your required
filters if this is your protocol." How does that sound? -- justin
Index: server/request.c
===================================================================
RCS file: /home/cvs/httpd-2.0/server/request.c,v
retrieving revision 1.99
diff -u -r1.99 request.c
--- server/request.c 15 Feb 2002 07:43:20 -0000 1.99
+++ server/request.c 1 Mar 2002 22:26:32 -0000
@@ -1492,15 +1492,20 @@
/* start with the same set of output filters */
if (next_filter) {
+ /* no input filters for a subrequest */
rnew->output_filters = next_filter;
+ 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
+ * to this subrequest - or this request will never be invoked.
+ */
+ rnew->input_filters = r->input_filters;
rnew->output_filters = r->output_filters;
+ ap_add_output_filter("CONTENT_LENGTH", NULL, rnew, rnew->connection);
+ ap_add_output_filter("HTTP_HEADER", NULL, rnew, rnew->connection);
}
- ap_add_output_filter_handle(ap_subreq_core_filter_handle,
- NULL, rnew, rnew->connection);
-
- /* no input filters for a subrequest */
ap_set_sub_req_protocol(rnew, r);
Index: modules/http/http_request.c
===================================================================
RCS file: /home/cvs/httpd-2.0/modules/http/http_request.c,v
retrieving revision 1.125
diff -u -r1.125 http_request.c
--- modules/http/http_request.c 25 Jan 2002 01:11:46 -0000 1.125
+++ modules/http/http_request.c 1 Mar 2002 22:26:33 -0000
@@ -441,6 +441,8 @@
r->err_headers_out);
r->subprocess_env = apr_table_overlay(r->pool, rr->subprocess_env,
r->subprocess_env);
+ r->output_filters = rr->output_filters;
+ r->input_filters = rr->input_filters;
}
AP_DECLARE(void) ap_internal_redirect(const char *new_uri, request_rec *r)