joes 2003/10/01 09:47:31
Modified: env mod_apreq.c
env/t request.t
Added: env/c-modules/apreq_redirect_test mod_apreq_redirect_test.c
Log:
<<EOT
Update mod_apreq filter to handle internal redirects.
Also add new tests to ensure prefetch data isn't lost across a redirect.
EOT
Revision Changes Path
1.27 +23 -11 httpd-apreq-2/env/mod_apreq.c
Index: mod_apreq.c
===================================================================
RCS file: /home/cvs/httpd-apreq-2/env/mod_apreq.c,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -r1.26 -r1.27
--- mod_apreq.c 17 Jul 2003 02:59:33 -0000 1.26
+++ mod_apreq.c 1 Oct 2003 16:47:31 -0000 1.27
@@ -189,7 +189,7 @@
return cfg->f;
for (f = r->input_filters;
- f != NULL && f->frec->ftype == AP_FTYPE_CONTENT_SET;
+ f != r->proto_input_filters;
f = f->next)
{
if (strcmp(f->frec->name, filter_name) == 0)
@@ -279,33 +279,45 @@
if (f->ctx) {
ctx = f->ctx;
- /* if "f" is still at the top of the filter chain, we're ok. Why?*/
- if (r->input_filters == f)
- return APR_SUCCESS;
-
/* We may have already prefetched some data.
- * Since "f" is no longer at the top of the filter chain,
+ * If "f" is no longer at the top of the filter chain,
* we need to add a new apreq filter to the top and start over.
+ * XXX: How safe would the following (unimplemented) optimization
+ * be on redirects????: Leave the filter intact if
+ * it's still at the end of the input filter chain (this would
+ * imply that no other input filters were added after libapreq
+ * started parsing).
*/
if (!APR_BRIGADE_EMPTY(ctx->spool)) {
apreq_request_t *req = apreq_env_request(r, NULL);
struct env_config *cfg = get_cfg(r);
- apreq_log(APREQ_DEBUG 0, r, "adding new apreq filter");
- /* must dump the current parser because
+ /* Adding "f" to the protocol filter chain ensures the
+ * spooled data is preserved across internal redirects.
+ */
+
+ r->proto_input_filters = f;
+
+ /* We MUST dump the current parser (and filter) because
* its existing state is now incorrect.
* NOTE:
* req->parser != NULL && req->body != NULL, since
* apreq_parse_request was called at least once already.
*
*/
-
+
+ apreq_log(APREQ_DEBUG 0, r, "dropping stale apreq filter");
req->parser = NULL;
req->body = NULL;
ctx->status = APR_SUCCESS;
- cfg->f = ap_add_input_filter(filter_name, NULL, r,
r->connection);
- apreq_filter_relocate(cfg->f);
+ cfg->f = NULL;
+ }
+ else {
+ /* No data was parsed/prefetched, so it's safe to move the filter
+ * up to the top of the chain.
+ */
+ apreq_filter_relocate(f);
}
}
else {
1.1
httpd-apreq-2/env/c-modules/apreq_redirect_test/mod_apreq_redirect_test.c
Index: mod_apreq_redirect_test.c
===================================================================
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
#if CONFIG_FOR_HTTPD_TEST
<Location /apreq_redirect_test>
TestAccess location
SetHandler apreq_redirect_test
</Location>
#endif
#define APACHE_HTTPD_TEST_HANDLER apreq_redirect_test_handler
#include "apache_httpd_test.h"
#include "apreq_params.h"
#include "apreq_env.h"
#include "httpd.h"
static int dump_table(void *ctx, const char *key, const char *value)
{
request_rec *r = ctx;
apreq_log(APREQ_DEBUG 0, r, "%s => %s", key, value);
ap_rprintf(r, "\t%s => %s\n", key, value);
return 1;
}
static int apreq_redirect_test_handler(request_rec *r)
{
apr_bucket_brigade *bb;
apreq_request_t *req;
const apreq_param_t *loc;
apr_status_t s;
int saw_eos = 0;
if (strcmp(r->handler, "apreq_redirect_test") != 0)
return DECLINED;
req = apreq_request(r, NULL);
loc = apreq_param(req, "location");
if (!loc)
return DECLINED;
ap_internal_redirect(loc->v.data, r);
return OK;
}
APACHE_HTTPD_TEST_MODULE(apreq_redirect_test);
1.5 +5 -1 httpd-apreq-2/env/t/request.t
Index: request.t
===================================================================
RCS file: /home/cvs/httpd-apreq-2/env/t/request.t,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- request.t 15 Jul 2003 16:15:50 -0000 1.4
+++ request.t 1 Oct 2003 16:47:31 -0000 1.5
@@ -5,7 +5,7 @@
use Apache::TestUtil;
use Apache::TestRequest qw(GET_BODY UPLOAD_BODY POST_BODY GET_RC);
-plan tests => 6;
+plan tests => 8;
foreach my $location ('/apreq_request_test', '/apreq_access_test') {
@@ -31,3 +31,7 @@
\ttest => 6
\tmore => $filler
EOT
+
+ok t_cmp(403, GET_RC("/apreq_redirect_test"), "missing redirect location");
+ok t_cmp("ARGS:\n\ttest => 8\n",
+
GET_BODY("/apreq_redirect_test?location=/apreq_request_test%3Ftest=8"),
"redirect");