You are viewing a plain text version of this content. The canonical link for it is here.
Posted to modperl@perl.apache.org by Philippe Troin <ph...@fifi.org> on 2002/01/30 04:29:10 UTC
[BUG] mod_perl confused about method calls when using internal_redirect
I've found that mod_perl can get confused when dealing with method
calls during a redirect_internal phase:
1. page /1 uses method calls, and works when accessed as /1
2. an other page /R uses internal_redirect to go to /1, and mod_perl
fails with an undefined subroutine error.
This has been seen on:
apache 1.3.9-14, perl 5.004.05-1.1, and mod_perl 1.25-3 (Debian "potato")
and on:
apache 1.3.22-2.1, perl 5.6.1-6, and mod_perl 1.26-1 (Debian "woody"/testing)
How to reproduce:
Use this startup.pl file:
======================================================================
# Common
package Common;
use Apache::Constants qw(:common);
sub handler($$)
{
my $self = shift;
my $req = shift;
$req->content_type('text/plain');
$req->send_http_header();
$req->print($self->doit());
return OK;
}
sub doit
{
return "COMMON";
}
# Common::Impl1
package Common::Impl1;
@ISA=qw(Common);
sub doit
{
return "IMPL1\n";
}
# Common::Impl2;
package Common::Impl2;
@ISA=qw(Common);
sub doit
{
return "IMPL2\n";
}
# Redir
package Redir;
use Apache::Constants qw(:common);
sub handler
{
my $req = shift;
$req->internal_redirect("/1");
return OK;
}
1;
======================================================================
PerlRequire the above, and use the following apache configuration:
======================================================================
<Location /0>
Order allow,deny
Allow from all
SetHandler perl-script
PerlHandler Common
</Location>
<Location /1>
Order allow,deny
Allow from all
SetHandler perl-script
PerlHandler Common::Impl1
</Location>
<Location /2>
Order allow,deny
Allow from all
SetHandler perl-script
PerlHandler Common::Impl2
</Location>
<Location /R>
Order allow,deny
Allow from all
SetHandler perl-script
PerlHandler Redir
</Location>
PerlRequire startup.pl
======================================================================
Then, directing a web browser to /0 prints COMMON, to /1 prints IMPL1,
to /2 prints IMPL2, as expectected.
Similarly, when pointing to /R (which redirects internally to /1),
IMPL1 should appear.
However, I get a 500 Internal server error and this in the logs:
[error] Undefined subroutine &Common::Impl1::handler called at
startup.pl line 49.
I've tried to debug the problem, and the problem lies inside
perl_handler_ismethod() in src/modules/perl/mod_perl.c: it returns
different values when called from inside the internal_redirect than
called without internal_redirect.
Inside perl_handler_ismethod():
if(!sub) return 0;
sv = newSVpv(sub,0);
if(!(cv = sv_2cv(sv, &stash, &gv, FALSE))) {
GV *gvp = gv_fetchmethod(pclass, sub);
if (gvp) cv = GvCV(gvp);
sv_2cv() returns different values when called from inside an
internal_redirect than called without
internal_redirect. Unfortunately, I could not grok sv_2cv(). It's not
even documented in the perl docs.
Phil.