stas 2003/04/02 22:23:54
Modified: src/modules/perl mod_perl.c modperl_cmd.c modperl_cmd.h
modperl_filter.h modperl_filter.c
. Changes
Added: t/htdocs/includes clear.shtml
t/filter out_str_req_mix.t
t/filter/TestFilter out_str_req_mix.pm
Log:
new directives PerlSetInputFilter and PerlSetOutputFilter, which are
the same as SetInputFilter and SetOutputFilter respectively, but allow
to insert non-mod_perl filters before, between or after mod_perl
filters. + tests
Revision Changes Path
1.163 +6 -1 modperl-2.0/src/modules/perl/mod_perl.c
Index: mod_perl.c
===================================================================
RCS file: /home/cvs/modperl-2.0/src/modules/perl/mod_perl.c,v
retrieving revision 1.162
retrieving revision 1.163
diff -u -r1.162 -r1.163
--- mod_perl.c 25 Mar 2003 07:52:22 -0000 1.162
+++ mod_perl.c 3 Apr 2003 06:23:52 -0000 1.163
@@ -699,7 +699,12 @@
MP_CMD_SRV_TAKE1("PerlPassEnv", pass_env, "PerlPassEnv"),
MP_CMD_SRV_RAW_ARGS_ON_READ("<Perl", perl, "Perl Code"),
MP_CMD_SRV_RAW_ARGS("Perl", perldo, "Perl Code"),
-
+
+ MP_CMD_DIR_TAKE1("PerlSetInputFilter", set_input_filter,
+ "filter[;filter]"),
+ MP_CMD_DIR_TAKE1("PerlSetOutputFilter", set_output_filter,
+ "filter[;filter]"),
+
MP_CMD_DIR_RAW_ARGS_ON_READ("=pod", pod, "Start of POD"),
MP_CMD_DIR_RAW_ARGS_ON_READ("=back", pod, "End of =over"),
MP_CMD_DIR_RAW_ARGS_ON_READ("=cut", pod_cut, "End of POD"),
1.44 +76 -0 modperl-2.0/src/modules/perl/modperl_cmd.c
Index: modperl_cmd.c
===================================================================
RCS file: /home/cvs/modperl-2.0/src/modules/perl/modperl_cmd.c,v
retrieving revision 1.43
retrieving revision 1.44
diff -u -r1.43 -r1.44
--- modperl_cmd.c 25 Mar 2003 22:58:49 -0000 1.43
+++ modperl_cmd.c 3 Apr 2003 06:23:52 -0000 1.44
@@ -30,6 +30,27 @@
return NULL;
}
+char *modperl_cmd_push_httpd_filter_handlers(MpAV **handlers,
+ const char *name,
+ apr_pool_t *p)
+{
+ modperl_handler_t *h = modperl_handler_new(p, name);
+
+ /* we don't want this special handler to be parsed */
+ MpHandlerPARSED_On(h);
+ h->attrs = MP_FILTER_HTTPD_HANDLER;
+
+ if (!*handlers) {
+ *handlers = modperl_handler_array_new(p);
+ MP_TRACE_d(MP_FUNC, "created handler stack\n");
+ }
+
+ modperl_handler_array_push(*handlers, h);
+ MP_TRACE_d(MP_FUNC, "pushed httpd filter handler: %s\n", h->name);
+
+ return NULL;
+}
+
#define MP_CMD_SRV_TRACE \
MP_TRACE_d(MP_FUNC, "%s %s\n", parms->cmd->name, arg)
@@ -475,6 +496,61 @@
return modperl_module_add(p, s, arg);
}
+
+/* propogate filters insertion ala SetInputFilter */
+MP_CMD_SRV_DECLARE(set_input_filter)
+{
+ MP_dSCFG(parms->server);
+ modperl_config_dir_t *dcfg = (modperl_config_dir_t *)mconfig;
+ char *filter;
+
+ if (!MpSrvENABLE(scfg)) {
+ return apr_pstrcat(parms->pool,
+ "Perl is disabled for server ",
+ parms->server->server_hostname, NULL);
+ }
+ if (!MpSrvINPUT_FILTER(scfg)) {
+ return apr_pstrcat(parms->pool,
+ "PerlSetInputFilter is disabled for server ",
+ parms->server->server_hostname, NULL);
+ }
+
+ while (*arg && (filter = ap_getword(parms->pool, &arg, ';'))) {
+ modperl_cmd_push_httpd_filter_handlers(
+ &(dcfg->handlers_per_dir[MP_INPUT_FILTER_HANDLER]),
+ filter, parms->pool);
+ }
+
+ return NULL;
+}
+
+/* propogate filters insertion ala SetOutputFilter */
+MP_CMD_SRV_DECLARE(set_output_filter)
+{
+ MP_dSCFG(parms->server);
+ modperl_config_dir_t *dcfg = (modperl_config_dir_t *)mconfig;
+ char *filter;
+
+ if (!MpSrvENABLE(scfg)) {
+ return apr_pstrcat(parms->pool,
+ "Perl is disabled for server ",
+ parms->server->server_hostname, NULL);
+ }
+ if (!MpSrvINPUT_FILTER(scfg)) {
+ return apr_pstrcat(parms->pool,
+ "PerlSetOutputFilter is disabled for server ",
+ parms->server->server_hostname, NULL);
+ }
+
+ while (*arg && (filter = ap_getword(parms->pool, &arg, ';'))) {
+ modperl_cmd_push_httpd_filter_handlers(
+ &(dcfg->handlers_per_dir[MP_OUTPUT_FILTER_HANDLER]),
+ filter, parms->pool);
+ }
+
+ return NULL;
+}
+
#ifdef MP_COMPAT_1X
1.21 +6 -0 modperl-2.0/src/modules/perl/modperl_cmd.h
Index: modperl_cmd.h
===================================================================
RCS file: /home/cvs/modperl-2.0/src/modules/perl/modperl_cmd.h,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -r1.20 -r1.21
--- modperl_cmd.h 7 Oct 2002 02:35:18 -0000 1.20
+++ modperl_cmd.h 3 Apr 2003 06:23:53 -0000 1.21
@@ -4,6 +4,10 @@
char *modperl_cmd_push_handlers(MpAV **handlers, const char *name,
apr_pool_t *p);
+char *modperl_cmd_push_httpd_filter_handlers(MpAV **handlers,
+ const char *name,
+ apr_pool_t *p);
+
#define MP_CMD_SRV_DECLARE(item) \
const char *modperl_cmd_##item(cmd_parms *parms, void *mconfig, \
const char *arg)
@@ -32,6 +36,8 @@
MP_CMD_SRV_DECLARE(pod_cut);
MP_CMD_SRV_DECLARE(END);
MP_CMD_SRV_DECLARE(load_module);
+MP_CMD_SRV_DECLARE(set_input_filter);
+MP_CMD_SRV_DECLARE(set_output_filter);
#ifdef MP_COMPAT_1X
1.22 +1 -0 modperl-2.0/src/modules/perl/modperl_filter.h
Index: modperl_filter.h
===================================================================
RCS file: /home/cvs/modperl-2.0/src/modules/perl/modperl_filter.h,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -r1.21 -r1.22
--- modperl_filter.h 3 Mar 2003 03:39:06 -0000 1.21
+++ modperl_filter.h 3 Apr 2003 06:23:53 -0000 1.22
@@ -9,6 +9,7 @@
#define MP_FILTER_CONNECTION_HANDLER 0x01
#define MP_FILTER_REQUEST_HANDLER 0x02
+#define MP_FILTER_HTTPD_HANDLER 0x04
typedef ap_filter_t * MP_FUNC_T(modperl_filter_add_t) (const char *, void *,
request_rec *,
1.58 +18 -1 modperl-2.0/src/modules/perl/modperl_filter.c
Index: modperl_filter.c
===================================================================
RCS file: /home/cvs/modperl-2.0/src/modules/perl/modperl_filter.c,v
retrieving revision 1.57
retrieving revision 1.58
diff -u -r1.57 -r1.58
--- modperl_filter.c 3 Apr 2003 06:21:43 -0000 1.57
+++ modperl_filter.c 3 Apr 2003 06:23:53 -0000 1.58
@@ -707,6 +707,14 @@
for (i=0; i<av->nelts; i++) {
modperl_filter_ctx_t *ctx;
+ if ((handlers[i]->attrs & MP_FILTER_HTTPD_HANDLER)) {
+ addfunc(handlers[i]->name, NULL, NULL, c);
+ MP_TRACE_f(MP_FUNC,
+ "a non-mod_perl %s handler %s configured (connection)\n",
+ type, handlers[i]->name);
+ continue;
+ }
+
if (!(handlers[i]->attrs & MP_FILTER_CONNECTION_HANDLER)) {
MP_TRACE_f(MP_FUNC,
"%s is not a FilterConnection handler\n",
@@ -747,8 +755,17 @@
for (i=0; i<av->nelts; i++) {
modperl_filter_ctx_t *ctx;
int registered = 0;
- ap_filter_t *f = filters;
+ ap_filter_t *f;
+
+ if ((handlers[i]->attrs & MP_FILTER_HTTPD_HANDLER)) {
+ addfunc(handlers[i]->name, NULL, r, r->connection);
+ MP_TRACE_f(MP_FUNC,
+ "a non-mod_perl %s handler %s configured (%s)\n",
+ type, handlers[i]->name, r->uri);
+ continue;
+ }
+ f = filters;
while (f) {
const char *fname = f->frec->name;
1.1 modperl-2.0/t/htdocs/includes/clear.shtml
Index: clear.shtml
===================================================================
This is a REMOVEclear text
1.1 modperl-2.0/t/filter/out_str_req_mix.t
Index: out_str_req_mix.t
===================================================================
use strict;
use warnings FATAL => 'all';
use Apache::Test;
use Apache::TestRequest;
use Apache::TestUtil;
plan tests => 1, ['include'];
my $location = '/TestFilter::out_str_req_mix';
my $content = '<!--#include virtual="/includes/REMOVEclear.shtml" -->';
my $body = 'This is a clear text';
my $expected = 'This is a clear text';
my $received = POST_BODY $location, content => $content;
ok t_cmp($expected, $received,
"mixing output httpd and mod_perl filters, while preserving order");
1.1 modperl-2.0/t/filter/TestFilter/out_str_req_mix.pm
Index: out_str_req_mix.pm
===================================================================
package TestFilter::out_str_req_mix;
# in this test we verify that we can preserve the mixed order of
# modperl and non-modperl filters using the PerlSetOutputFilter
# directive, instead of SetOutputFilter for non-modperl filters.
#
# response handler prints a mangled SSI directive:
# <!--#include virtual="/includes/REMOVEclear.shtml" -->
# (which it receives via POST from the client)
#
# adjust() filter is configured to be called first and it removes the
# string 'REMOVE' from the response handler's output, so that SSI will
# find the fixed resource specification:
# <!--#include virtual="/includes/clear.shtml" -->
#
# the INCLUDES filter, which is configured to be next on the stack
# (mod_include) processes the directive and returns the contents of
# file "/includes/clear.shtml", which is:
# This is a REMOVEclear text
#
# finally the second mod_perl filter (which happens to be the same
# adjust() filter, but to all purposes it's a separate filter)
# configured to run after the INCLUDES filter fixes the data sent by
# the INCLUDES filter to be:
# This is a clear text
#
# and this is what the client is expecting to receive
#
# WARNING: notice that the adjust() filter assumes that it'll receive
# the word REMOVE in a single bucket, which is good enough for the
# test because we control all the used filters and normally Apache
# core filters won't split short data into several buckets. However
# filter developers shouldn't make any assumptions, since any data can
# be split by any of the upstream filters.
use strict;
use warnings FATAL => 'all';
use Apache::Filter ();
use Apache::Const -compile => qw(OK M_POST);
sub adjust {
my $filter = shift;
warn "add_prefix called\n";
while ($filter->read(my $buffer, 1024)){
$buffer =~ s/REMOVE//;
$filter->print($buffer);
}
Apache::OK;
}
sub handler {
my $r = shift;
$r->content_type('text/plain');
if ($r->method_number == Apache::M_POST) {
$r->print(ModPerl::Test::read_post($r));
}
return Apache::OK;
}
1;
__DATA__
<NoAutoConfig>
PerlModule TestFilter::out_str_req_mix
<Location /TestFilter::out_str_req_mix>
Options +Includes
PerlOutputFilterHandler TestFilter::out_str_req_mix::adjust
PerlSetOutputFilter INCLUDES
PerlOutputFilterHandler TestFilter::out_str_req_mix::adjust
SetHandler modperl
PerlResponseHandler TestFilter::out_str_req_mix
</Location>
</NoAutoConfig>
1.162 +7 -0 modperl-2.0/Changes
Index: Changes
===================================================================
RCS file: /home/cvs/modperl-2.0/Changes,v
retrieving revision 1.161
retrieving revision 1.162
diff -u -r1.161 -r1.162
--- Changes 1 Apr 2003 05:20:51 -0000 1.161
+++ Changes 3 Apr 2003 06:23:53 -0000 1.162
@@ -10,6 +10,13 @@
=item 1.99_09-dev
+new directives PerlSetInputFilter and PerlSetOutputFilter, which are
+the same as SetInputFilter and SetOutputFilter respectively, but allow
+to insert non-mod_perl filters before, between or after mod_perl
+filters. + tests [Stas]
+
+improved filters debug tracing [Stas]
+
implement $filter->remove (filter self-removal) + tests [Stas]
remove the second-guessing code that was trying to guess the package