You are viewing a plain text version of this content. The canonical link for it is here.
Posted to apreq-cvs@httpd.apache.org by jo...@apache.org on 2004/08/08 20:42:06 UTC
cvs commit: httpd-apreq-2/src apreq_params.c apreq_version.h
joes 2004/08/08 11:42:06
Modified: env mod_apreq.c
env/t request.t
glue/perl/docs Table.pod
glue/perl/xsbuilder apreq_xs_tables.h
glue/perl/xsbuilder/Apache/Cookie Apache__Cookie.h
glue/perl/xsbuilder/Apache/Request Apache__Request.h
src apreq_params.c apreq_version.h
Log:
Move context-stealing code from apreq_filter into apreq_filter_make_context. For it to work optimally on subrequests, we need to go back to setting req->parser as late as possible. More debugging logs added to ensure the tests exercise the context stealing code, and two new tests added to env/t/request.t (which may have line-ending problems on win32?) to fully exercise the context-stealing code. Unrelated to any of the above, this patch also drops USE_ITHREADS conditional from apreq_xs_tables.h, since
that logic is already in ppport.h.
Revision Changes Path
1.59 +70 -61 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.58
retrieving revision 1.59
diff -u -r1.58 -r1.59
--- mod_apreq.c 3 Aug 2004 05:06:04 -0000 1.58
+++ mod_apreq.c 8 Aug 2004 18:42:05 -0000 1.59
@@ -157,7 +157,7 @@
#define APREQ_MODULE_NAME "APACHE2"
-#define APREQ_MODULE_MAGIC_NUMBER 20040802
+#define APREQ_MODULE_MAGIC_NUMBER 20040808
static void apache2_log(const char *file, int line, int level,
apr_status_t status, void *env, const char *fmt,
@@ -291,9 +291,72 @@
static void apreq_filter_make_context(ap_filter_t *f)
{
request_rec *r = f->r;
- apr_bucket_alloc_t *alloc = apr_bucket_alloc_create(r->pool);
- struct filter_ctx *ctx = apr_palloc(r->pool, sizeof *ctx);
struct env_config *cfg = get_cfg(r);
+ apreq_request_t *req = cfg->req;
+ struct filter_ctx *ctx;
+ apr_bucket_alloc_t *alloc;
+
+ if (f == r->input_filters
+ && r->proto_input_filters == f->next
+ && strcasecmp(f->next->frec->name, filter_name) == 0)
+ {
+ /* Try to steal the context and parse data of the
+ upstream apreq filter. */
+ ctx = f->next->ctx;
+
+ switch (ctx->status) {
+ case APR_SUCCESS:
+ case APR_INCOMPLETE:
+ break;
+ default:
+ /* bad filter state, don't steal anything */
+ apreq_log(APREQ_DEBUG ctx->status, r, "cannot steal context: bad filter status");
+ goto make_new_context;
+ }
+
+ if (ctx->r != r) {
+ /* r is a new request (subrequest or internal redirect) */
+ apreq_request_t *old_req;
+
+ if (req != NULL) {
+ if (req->parser != NULL) {
+ /* new parser on this request: cannot steal context */
+ apreq_log(APREQ_DEBUG ctx->status, r, "cannot steal context: new parser detected");
+ goto make_new_context;
+ }
+ }
+ else {
+ req = apreq_request(r, NULL);
+ }
+
+ /* steal the parser output */
+ apreq_log(APREQ_DEBUG 0, r, "stealing parser output");
+ old_req = apreq_request(ctx->r, NULL);
+ req->parser = old_req->parser;
+ req->body = old_req->body;
+ req->body_status = old_req->body_status;
+ ctx->r = r;
+ }
+
+ /* steal the filter context */
+ apreq_log(APREQ_DEBUG 0, r, "stealing filter context");
+ f->ctx = f->next->ctx;
+ r->proto_input_filters = f;
+ ap_remove_input_filter(f->next);
+ return;
+ }
+
+ make_new_context:
+ if (req != NULL && f == r->input_filters) {
+ if (req->body_status != APR_EINIT) {
+ req->body = NULL;
+ req->parser = NULL;
+ req->body_status = APR_EINIT;
+ }
+ }
+
+ alloc = apr_bucket_alloc_create(r->pool);
+ ctx = apr_palloc(r->pool, sizeof *ctx);
f->ctx = ctx;
ctx->r = r;
@@ -456,9 +519,10 @@
/* else this is a protocol filter which may still be active.
* if it is, we must deregister it now.
*/
- if (cfg->f == f)
+ if (cfg->f == f) {
+ apreq_log(APREQ_DEBUG 0, r, "disabling stale protocol filter");
cfg->f = NULL;
-
+ }
return APR_SUCCESS;
}
@@ -486,64 +550,9 @@
cfg = get_cfg(r);
req = cfg->req;
- if (f->ctx == NULL) {
- if (f == r->input_filters
- && r->proto_input_filters == f->next
- && strcmp(f->next->frec->name, filter_name) == 0)
- {
- /* Try to steal the context and parse data of the
- upstream apreq filter. */
- ctx = f->next->ctx;
-
- switch (ctx->status) {
- case APR_SUCCESS:
- case APR_INCOMPLETE:
- break;
- default:
- /* bad filter state, don't steal anything */
- goto make_new_context;
- }
-
- if (ctx->r != r) {
- /* r is a new request (subrequest or internal redirect) */
- apreq_request_t *old_req;
-
- if (req != NULL) {
- if (req->parser != NULL)
- /* new parser on this request: cannot steal context */
- goto make_new_context;
- }
- else {
- req = apreq_request(r, NULL);
- }
-
- /* steal the parser output */
- old_req = apreq_request(ctx->r, NULL);
- req->parser = old_req->parser;
- req->body = old_req->body;
- req->body_status = old_req->body_status;
- ctx->r = r;
- }
-
- /* steal the filter context */
- f->ctx = f->next->ctx;
- r->proto_input_filters = f;
- ap_remove_input_filter(f->next);
- goto context_initialized;
- }
-
- make_new_context:
+ if (f->ctx == NULL)
apreq_filter_make_context(f);
- if (req != NULL && f == r->input_filters) {
- if (req->body_status != APR_EINIT) {
- req->body = NULL;
- req->parser = NULL;
- req->body_status = APR_EINIT;
- }
- }
- }
- context_initialized:
ctx = f->ctx;
if (cfg->f != f)
1.14 +25 -2 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.13
retrieving revision 1.14
diff -u -r1.13 -r1.14
--- request.t 6 Aug 2004 15:26:46 -0000 1.13
+++ request.t 8 Aug 2004 18:42:06 -0000 1.14
@@ -6,7 +6,7 @@
use Apache::TestRequest qw(GET_BODY UPLOAD_BODY POST_BODY GET_RC);
require File::Copy;
-my $num_tests = 16;
+my $num_tests = 18;
$num_tests *= 2 if Apache::Test::have_ssl();
plan tests => $num_tests, have_lwp;
my $scheme = "http";
@@ -59,7 +59,6 @@
EOT
}
-
# internal redirect to plain text files (which are non-apreq requests)
my $index_html = do {local (@ARGV,$/) = "t/htdocs/index.html"; <> };
@@ -102,6 +101,30 @@
\ttest => output filter POST
EOT
"output filter POST");
+
+# internal redirect to html files which are filtered as above
+
+$body = GET_BODY("/apreq_redirect_test?test=redirect_index_html_GET&location=/index.html?foo=bar");
+$body =~ s{\r}{}g;
+ok t_cmp($body, $index_html . <<EOT, "redirect /index.html (GET)");
+
+--APREQ OUTPUT FILTER--
+ARGS:
+\tfoo => bar
+EOT
+$body = POST_BODY("/apreq_redirect_test?test=redirect_index_html_POST",
+ content => "quux=$filler;location=/index.html?foo=quux;foo=$filler");
+$body =~ s{\r}{}g;
+ok t_cmp($body, $index_html . <<EOT, "redirect /index.txt (POST)");
+
+--APREQ OUTPUT FILTER--
+ARGS:
+\tfoo => quux
+BODY:
+\tquux => $filler
+\tlocation => /index.html?foo=quux
+\tfoo => $filler
+EOT
if (Apache::Test::have_ssl() and $scheme ne 'https') {
$scheme = 'https';
1.8 +6 -0 httpd-apreq-2/glue/perl/docs/Table.pod
Index: Table.pod
===================================================================
RCS file: /home/cvs/httpd-apreq-2/glue/perl/docs/Table.pod,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- Table.pod 31 Jul 2004 23:56:40 -0000 1.7
+++ Table.pod 8 Aug 2004 18:42:06 -0000 1.8
@@ -44,6 +44,8 @@
and C<overlap> methods from APR::Table are not implemented.
+
+
=head1 Apache::Request::Table
These tables arise as parameter tables generated by the C<args>, C<body>, and
@@ -65,6 +67,7 @@
+
=head1 Apache::Upload::Table
These tables arise from the C<Apache::Request::upload> method (which is
@@ -85,6 +88,7 @@
+
=head1 Apache::Cookie::Table
These tables arise from the C<cookies> method of Apache::Cookie::Jar, and
@@ -102,6 +106,8 @@
ok $cookie->isa("Apache::Cookie");
=for example_testing
+
+
=head1 SEE ALSO
1.36 +0 -2 httpd-apreq-2/glue/perl/xsbuilder/apreq_xs_tables.h
Index: apreq_xs_tables.h
===================================================================
RCS file: /home/cvs/httpd-apreq-2/glue/perl/xsbuilder/apreq_xs_tables.h,v
retrieving revision 1.35
retrieving revision 1.36
diff -u -r1.35 -r1.36
--- apreq_xs_tables.h 5 Aug 2004 21:01:14 -0000 1.35
+++ apreq_xs_tables.h 8 Aug 2004 18:42:06 -0000 1.36
@@ -182,9 +182,7 @@
const char *val)
{
struct apreq_xs_do_arg *d = (struct apreq_xs_do_arg *)data;
-#ifdef USE_ITHREADS
dTHXa(d->perl);
-#endif
dSP;
SV *sv = newSVpv(key,0);
1.35 +2 -1 httpd-apreq-2/glue/perl/xsbuilder/Apache/Cookie/Apache__Cookie.h
Index: Apache__Cookie.h
===================================================================
RCS file: /home/cvs/httpd-apreq-2/glue/perl/xsbuilder/Apache/Cookie/Apache__Cookie.h,v
retrieving revision 1.34
retrieving revision 1.35
diff -u -r1.34 -r1.35
--- Apache__Cookie.h 3 Aug 2004 18:07:58 -0000 1.34
+++ Apache__Cookie.h 8 Aug 2004 18:42:06 -0000 1.35
@@ -46,7 +46,8 @@
jar = apreq_jar(env, data);
sv = apreq_xs_2sv(jar, SvPV_nolen(ST(0)), SvRV(ST(1)));
- SvTAINTED_on(SvRV(sv));
+ if (items == 2 || SvTAINTED(ST(2)))
+ SvTAINTED_on(SvRV(sv));
ST(0) = sv_2mortal(sv);
XSRETURN(1);
}
1.56 +9 -1 httpd-apreq-2/glue/perl/xsbuilder/Apache/Request/Apache__Request.h
Index: Apache__Request.h
===================================================================
RCS file: /home/cvs/httpd-apreq-2/glue/perl/xsbuilder/Apache/Request/Apache__Request.h,v
retrieving revision 1.55
retrieving revision 1.56
diff -u -r1.55 -r1.56
--- Apache__Request.h 5 Aug 2004 18:11:46 -0000 1.55
+++ Apache__Request.h 8 Aug 2004 18:42:06 -0000 1.56
@@ -107,7 +107,8 @@
/*FIXME: mg_mg->ptr */
sv = apreq_xs_2sv(req, SvPV_nolen(ST(0)), SvRV(ST(1)));
- SvTAINTED_on(SvRV(sv));
+ if (items == 2 || SvTAINTED(ST(2)))
+ SvTAINTED_on(SvRV(sv));
ST(0) = sv_2mortal(sv);
XSRETURN(1);
}
@@ -378,6 +379,13 @@
#ifdef USE_ITHREADS
ctx->perl = aTHX;
#endif
+ if (req->parser == NULL)
+ req->parser = apreq_parser(req->env, NULL);
+ if (req->parser == NULL)
+ Perl_croak(aTHX_ "Apache::Request::config: cannot install "
+ "UPLOAD_HOOK: no parser available for enctype=%s",
+ apreq_enctype(req->env));
+
upload_hook = apreq_make_hook(pool, apreq_xs_upload_hook,
NULL, ctx);
apreq_add_hook(req->parser, upload_hook);
1.47 +2 -2 httpd-apreq-2/src/apreq_params.c
Index: apreq_params.c
===================================================================
RCS file: /home/cvs/httpd-apreq-2/src/apreq_params.c,v
retrieving revision 1.46
retrieving revision 1.47
diff -u -r1.46 -r1.47
--- apreq_params.c 4 Aug 2004 17:40:54 -0000 1.46
+++ apreq_params.c 8 Aug 2004 18:42:06 -0000 1.47
@@ -63,7 +63,7 @@
req->env = env;
req->args = apr_table_make(p, APREQ_NELTS);
req->body = NULL;
- req->parser = apreq_parser(env, NULL);
+ req->parser = NULL;
/* XXX get/set race condition here wrt apreq_env_request? */
old_req = apreq_env_request(env, req);
@@ -83,7 +83,7 @@
req->env = env;
req->args = apr_table_make(p, APREQ_NELTS);
req->body = NULL;
- req->parser = apreq_parser(env, NULL);
+ req->parser = NULL;
}
1.24 +1 -1 httpd-apreq-2/src/apreq_version.h
Index: apreq_version.h
===================================================================
RCS file: /home/cvs/httpd-apreq-2/src/apreq_version.h,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -r1.23 -r1.24
--- apreq_version.h 31 Jul 2004 23:56:40 -0000 1.23
+++ apreq_version.h 8 Aug 2004 18:42:06 -0000 1.24
@@ -61,7 +61,7 @@
#define APREQ_MINOR_VERSION 0
/** patch level */
-#define APREQ_PATCH_VERSION 19
+#define APREQ_PATCH_VERSION 20
/**
* This symbol is defined for internal, "development" copies of libapreq.