stas 2003/01/23 23:39:29
Modified: . Changes
src/modules/perl modperl_filter.c modperl_filter.h
xs/Apache/Filter Apache__Filter.h
xs/maps apache_functions.map modperl_functions.map
xs/tables/current/ModPerl FunctionTable.pm
Added: t/filter both_str_con_add.t both_str_rec_add.t
t/filter/TestFilter both_str_con_add.pm both_str_rec_add.pm
Log:
- s/filter_add_t/modperl_filter_add_t/ since it's now exposed (needed in
Apache::Filter)
- implement $r->add_input_filter and $r->add_output_filter
$c->add_input_filter and $c->add_output_filter
- tests (connection and request)
Revision Changes Path
1.114 +4 -0 modperl-2.0/Changes
Index: Changes
===================================================================
RCS file: /home/cvs/modperl-2.0/Changes,v
retrieving revision 1.113
retrieving revision 1.114
diff -u -r1.113 -r1.114
--- Changes 24 Jan 2003 05:09:40 -0000 1.113
+++ Changes 24 Jan 2003 07:39:28 -0000 1.114
@@ -10,6 +10,10 @@
=item 1.99_09-dev
+Implement $r->add_input_filter and $r->add_output_filter
+ $c->add_input_filter and $c->add_output_filter
+and add tests [Stas]
+
Skip the handler package::func resolving error, only when the error
message matches "Can't locate .*? in @INC", rather than just "Can't
locate", since there are many other errors that start with that
1.1 modperl-2.0/t/filter/both_str_con_add.t
Index: both_str_con_add.t
===================================================================
use strict;
use warnings FATAL => 'all';
use Test;
use Apache::TestUtil;
use Apache::TestRequest ();
my @test_strings = qw(MODPERL 2.0 RULES);
plan tests => 1 + @test_strings;
my $module = "TestFilter::both_str_con_add";
my $socket = Apache::TestRequest::vhost_socket($module);
ok $socket;
for my $str (@test_strings) {
print $socket "$str\n";
chomp(my $reply = <$socket>);
$str = lc $str;
$str =~ s/modperl/mod_perl/;
ok t_cmp($str, $reply);
}
1.1 modperl-2.0/t/filter/both_str_rec_add.t
Index: both_str_rec_add.t
===================================================================
use strict;
use warnings FATAL => 'all';
use Apache::Test;
use Apache::TestRequest;
use Apache::TestUtil;
plan tests => 1;
my $data = join ' ', 'A'..'Z', 0..9;
my $expected = lc $data; # that's what the input filter does
$expected =~ s/\s+//g; # that's what the output filter does
my $location = '/TestFilter::both_str_rec_add';
my $response = POST_BODY $location, content => $data;
ok t_cmp($expected, $response, "lc input and reverse output filters");
1.1 modperl-2.0/t/filter/TestFilter/both_str_con_add.pm
Index: both_str_con_add.pm
===================================================================
package TestFilter::both_str_con_add;
# insert an input filter which lowers the case of the data
# insert an output filter which adjusts s/modperl/mod_perl/
use strict;
use warnings FATAL => 'all';
use Apache::Connection ();
use APR::Bucket ();
use APR::Brigade ();
use APR::Util ();
use APR::Const -compile => qw(SUCCESS EOF);
use Apache::Const -compile => qw(OK MODE_GETLINE);
use Apache::Const -compile => qw(OK);
sub pre_connection {
my Apache::Connection $c = shift;
$c->add_input_filter(\&in_filter);
$c->add_output_filter(\&out_filter);
return Apache::OK;
}
sub in_filter {
my($filter, $bb, $mode, $block, $readbytes) = @_;
while ($filter->read($mode, $block, $readbytes, my $buffer, 1024)) {
$filter->print(lc $buffer);
}
# test that $filter->ctx works here
$filter->ctx(1);
Apache::OK;
}
sub out_filter {
my $filter = shift;
while ($filter->read(my $buffer, 1024)) {
$buffer =~ s/modperl/mod_perl/;
$filter->print($buffer);
}
Apache::OK;
}
sub handler {
my Apache::Connection $c = shift;
my $bb = APR::Brigade->new($c->pool, $c->bucket_alloc);
for (;;) {
my $rv = $c->input_filters->get_brigade($bb,
Apache::MODE_GETLINE);
if ($rv != APR::SUCCESS or $bb->empty) {
my $error = APR::strerror($rv);
unless ($rv == APR::EOF) {
warn "[echo_filter] get_brigade: $error\n";
}
$bb->destroy;
last;
}
my $b = APR::Bucket::flush_create($c->bucket_alloc);
$bb->insert_tail($b);
$c->output_filters->pass_brigade($bb);
}
Apache::OK;
}
1;
__END__
<NoAutoConfig>
<VirtualHost TestFilter::both_str_con_add>
PerlPreConnectionHandler TestFilter::both_str_con_add::pre_connection
PerlProcessConnectionHandler TestFilter::both_str_con_add
</VirtualHost>
</NoAutoConfig>
1.1 modperl-2.0/t/filter/TestFilter/both_str_rec_add.pm
Index: both_str_rec_add.pm
===================================================================
package TestFilter::both_str_rec_add;
# insert an input filter which lowers the case of the data
# insert an output filter which strips spaces
use strict;
use warnings FATAL => 'all';
use Apache::Filter ();
use Apache::Const -compile => qw(OK M_POST);
sub header_parser {
my $r = shift;
# test adding by coderef
$r->add_input_filter(\&in_filter);
# test adding by sub's name
$r->add_output_filter("out_filter");
return Apache::DECLINED;
}
sub in_filter {
my($filter, $bb, $mode, $block, $readbytes) = @_;
while ($filter->read($mode, $block, $readbytes, my $buffer, 1024)) {
$filter->print(lc $buffer);
}
Apache::OK;
}
sub out_filter {
my $filter = shift;
while ($filter->read(my $buffer, 1024)) {
$buffer =~ s/\s+//g;
$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>
<Location /TestFilter::both_str_rec_add>
SetHandler modperl
PerlHeaderParserHandler TestFilter::both_str_rec_add::header_parser
PerlResponseHandler TestFilter::both_str_rec_add
</Location>
</NoAutoConfig>
1.46 +28 -4 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.45
retrieving revision 1.46
diff -u -r1.45 -r1.46
--- modperl_filter.c 23 Jan 2003 00:31:28 -0000 1.45
+++ modperl_filter.c 24 Jan 2003 07:39:29 -0000 1.46
@@ -586,13 +586,11 @@
}
}
-typedef ap_filter_t * MP_FUNC_T(filter_add_t) (const char *, void *,
- request_rec *, conn_rec *);
static int modperl_filter_add_connection(conn_rec *c,
int idx,
const char *name,
- filter_add_t addfunc,
+ modperl_filter_add_t addfunc,
const char *type)
{
modperl_config_dir_t *dcfg =
@@ -632,7 +630,7 @@
static int modperl_filter_add_request(request_rec *r,
int idx,
const char *name,
- filter_add_t addfunc,
+ modperl_filter_add_t addfunc,
const char *type,
ap_filter_t *filters)
{
@@ -729,6 +727,32 @@
"InputFilter",
r->connection->input_filters);
}
+
+void modperl_filter_runtime_add(pTHX_ request_rec *r, conn_rec *c, int idx,
+ const char *name,
+ modperl_filter_add_t addfunc,
+ SV *callback, const char *type)
+{
+ apr_pool_t *pool = r ? r->pool : c->pool;
+ char *handler_name;
+
+ if ((handler_name = modperl_mgv_name_from_sv(aTHX_ pool, callback))) {
+ modperl_filter_ctx_t *ctx =
+ (modperl_filter_ctx_t *)apr_pcalloc(pool, sizeof(*ctx));
+ ctx->handler = modperl_handler_new(pool,
+ apr_pstrdup(pool, handler_name));
+ addfunc(name, (void*)ctx, r, c);
+
+ MP_TRACE_h(MP_FUNC, "%s handler %s configured (connection)\n",
+ type, name);
+
+ return;
+ }
+
+ Perl_croak(aTHX_ "unable to resolve handler 0x%lx\n",
+ (unsigned long)callback);
+}
+
void modperl_brigade_dump(apr_bucket_brigade *bb, FILE *fp)
{
1.18 +9 -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.17
retrieving revision 1.18
diff -u -r1.17 -r1.18
--- modperl_filter.h 17 Jan 2003 03:08:31 -0000 1.17
+++ modperl_filter.h 24 Jan 2003 07:39:29 -0000 1.18
@@ -10,6 +10,10 @@
#define MP_FILTER_CONNECTION_HANDLER 0x01
#define MP_FILTER_REQUEST_HANDLER 0x02
+typedef ap_filter_t * MP_FUNC_T(modperl_filter_add_t) (const char *, void *,
+ request_rec *,
+ conn_rec *);
+
/* simple buffer api */
MP_INLINE apr_status_t modperl_wbucket_pass(modperl_wbucket_t *b,
const char *buf, apr_size_t len);
@@ -81,6 +85,11 @@
modperl_filter_t *filter,
const char *buf,
apr_size_t *len);
+
+void modperl_filter_runtime_add(pTHX_ request_rec *r, conn_rec *c, int idx,
+ const char *name,
+ modperl_filter_add_t addfunc,
+ SV *callback, const char *type);
#endif /* MODPERL_FILTER_H */
1.23 +56 -6 modperl-2.0/xs/Apache/Filter/Apache__Filter.h
Index: Apache__Filter.h
===================================================================
RCS file: /home/cvs/modperl-2.0/xs/Apache/Filter/Apache__Filter.h,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -r1.22 -r1.23
--- Apache__Filter.h 15 Jan 2003 06:11:08 -0000 1.22
+++ Apache__Filter.h 24 Jan 2003 07:39:29 -0000 1.23
@@ -1,9 +1,3 @@
-#define mpxs_Apache__RequestRec_add_output_filter(r, name, ctx) \
-ap_add_output_filter(name, ctx, r, NULL)
-
-#define mpxs_Apache__RequestRec_add_input_filter(r, name, ctx) \
-ap_add_input_filter(name, ctx, r, NULL)
-
#define mp_xs_sv2_modperl_filter(sv) \
((SvROK(sv) && (SvTYPE(SvRV(sv)) == SVt_PVMG)) \
|| (Perl_croak(aTHX_ "argument is not a blessed reference"),0) ? \
@@ -145,4 +139,60 @@
modperl_filter_t *modperl_filter;
mpxs_usage_va_1(modperl_filter, "$filter->seen_eos()");
return modperl_filter->seen_eos ? &PL_sv_yes : &PL_sv_no;
+}
+
+static MP_INLINE
+void mpxs_Apache__RequestRec_add_input_filter(pTHX_ request_rec *r,
+ SV *callback)
+{
+
+ modperl_filter_runtime_add(aTHX_ r,
+ r->connection,
+ MP_INPUT_FILTER_HANDLER,
+ MP_FILTER_REQUEST_INPUT_NAME,
+ ap_add_input_filter,
+ callback,
+ "InputFilter");
+}
+
+static MP_INLINE
+void mpxs_Apache__RequestRec_add_output_filter(pTHX_ request_rec *r,
+ SV *callback)
+{
+
+ modperl_filter_runtime_add(aTHX_ r,
+ r->connection,
+ MP_OUTPUT_FILTER_HANDLER,
+ MP_FILTER_REQUEST_OUTPUT_NAME,
+ ap_add_output_filter,
+ callback,
+ "OutputFilter");
+}
+
+static MP_INLINE
+void mpxs_Apache__Connection_add_input_filter(pTHX_ conn_rec *c,
+ SV *callback)
+{
+
+ modperl_filter_runtime_add(aTHX_ NULL,
+ c,
+ MP_INPUT_FILTER_HANDLER,
+ MP_FILTER_CONNECTION_INPUT_NAME,
+ ap_add_input_filter,
+ callback,
+ "InputFilter");
+}
+
+static MP_INLINE
+void mpxs_Apache__Connection_add_output_filter(pTHX_ conn_rec *c,
+ SV *callback)
+{
+
+ modperl_filter_runtime_add(aTHX_ NULL,
+ c,
+ MP_OUTPUT_FILTER_HANDLER,
+ MP_FILTER_CONNECTION_OUTPUT_NAME,
+ ap_add_output_filter,
+ callback,
+ "OutputFilter");
}
1.61 +0 -6 modperl-2.0/xs/maps/apache_functions.map
Index: apache_functions.map
===================================================================
RCS file: /home/cvs/modperl-2.0/xs/maps/apache_functions.map,v
retrieving revision 1.60
retrieving revision 1.61
diff -u -r1.60 -r1.61
--- apache_functions.map 1 Jan 2003 23:22:19 -0000 1.60
+++ apache_functions.map 24 Jan 2003 07:39:29 -0000 1.61
@@ -211,12 +211,6 @@
ap_walk_config
>ap_process_config_tree
-MODULE=Apache::Filter PACKAGE=Apache::RequestRec
-ap_filter_t *:DEFINE_add_output_filter | | \
- request_rec *:r, const char *:name, void *:ctx
-ap_filter_t *:DEFINE_add_input_filter | | \
- request_rec *:r, const char *:name, void *:ctx
-
PACKAGE=guess
~ap_add_output_filter
~ap_add_input_filter
1.51 +8 -0 modperl-2.0/xs/maps/modperl_functions.map
Index: modperl_functions.map
===================================================================
RCS file: /home/cvs/modperl-2.0/xs/maps/modperl_functions.map,v
retrieving revision 1.50
retrieving revision 1.51
diff -u -r1.50 -r1.51
--- modperl_functions.map 22 Jan 2003 06:12:43 -0000 1.50
+++ modperl_functions.map 24 Jan 2003 07:39:29 -0000 1.51
@@ -83,6 +83,14 @@
SV *:DEFINE_TIEHANDLE | | SV *:stashsv, SV *:sv=Nullsv
int:DEFINE_PRINT | | ...
+MODULE=Apache::Filter PACKAGE=Apache::RequestRec
+ mpxs_Apache__RequestRec_add_input_filter
+ mpxs_Apache__RequestRec_add_output_filter
+
+MODULE=Apache::Filter PACKAGE=Apache::Connection
+ mpxs_Apache__Connection_add_input_filter
+ mpxs_Apache__Connection_add_output_filter
+
MODULE=Apache::Log PACKAGE=Apache::Log BOOT=1
DEFINE_error | MPXS_Apache__Log_dispatch | ...
1.100 +110 -0 modperl-2.0/xs/tables/current/ModPerl/FunctionTable.pm
Index: FunctionTable.pm
===================================================================
RCS file: /home/cvs/modperl-2.0/xs/tables/current/ModPerl/FunctionTable.pm,v
retrieving revision 1.99
retrieving revision 1.100
diff -u -r1.99 -r1.100
--- FunctionTable.pm 23 Jan 2003 00:31:28 -0000 1.99
+++ FunctionTable.pm 24 Jan 2003 07:39:29 -0000 1.100
@@ -282,6 +282,116 @@
]
},
{
+ 'return_type' => 'void',
+ 'name' => 'modperl_filter_runtime_add',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'c'
+ },
+ {
+ 'type' => 'int',
+ 'name' => 'idx'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'name'
+ },
+ {
+ 'type' => 'modperl_filter_add_t',
+ 'name' => 'addfunc'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'callback'
+ },
+ {
+ 'type' => 'const char *',
+ 'name' => 'type'
+ },
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_Apache__RequestRec_add_input_filter',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'callback'
+ },
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_Apache__RequestRec_add_output_filter',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'perl'
+ },
+ {
+ 'type' => 'request_rec *',
+ 'name' => 'r'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'callback'
+ },
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_Apache__Connection_add_input_filter',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'perl'
+ },
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'c'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'callback'
+ },
+ ]
+ },
+ {
+ 'return_type' => 'void',
+ 'name' => 'mpxs_Apache__Connection_add_output_filter',
+ 'args' => [
+ {
+ 'type' => 'PerlInterpreter *',
+ 'name' => 'perl'
+ },
+ {
+ 'type' => 'conn_rec *',
+ 'name' => 'c'
+ },
+ {
+ 'type' => 'SV *',
+ 'name' => 'callback'
+ },
+ ]
+ },
+ {
'return_type' => 'int',
'name' => 'modperl_cgi_header_parse',
'attr' => [