You are viewing a plain text version of this content. The canonical link for it is here.
Posted to modperl@perl.apache.org by Stas Bekman <sb...@stason.org> on 2000/04/14 19:44:27 UTC
[RFC] Transitioning from Apache::Registry to Apache handlers
Someone has asked how to move from registry scripts to perl handlers, this
is my attempt to show in details the process. Comments are welcome.
=head1 Transitioning from Apache::Registry to Apache handlers
Even if you are a CGI script die-hard at some point you might want to
move a few or all your scripts to Apache Perl handlers. Actually this
is an easy task, since we saw already what C<Apache::Registry> does to
our scripts so they will appear as Perl handlers to Apache.
Now when you are no longer need a backward mod_cgi compatibility you
can benefit from the Perl libraries working only under
mod_perl. We will see why in a moment.
Let's see an example. We will start with a mod_cgi compatible CGI
script running under C<Apache::Registry>, transpose it into a Perl
content handler and then convert it to use C<Apache::Request> and
C<Apache::Cookie>.
=head2 Starting with mod_cgi Compatible Script
This is the original script's code we are going to work with:
cookie_script.pl
----------------
use strict;
use CGI;
use CGI::Cookie;
use vars qw($q $switch $status $sessionID);
init();
print_header();
print_status();
### <-- subroutines --> ###
# the init code
###########
sub init{
$q = new CGI;
$switch = $q->param("switch") ? 1 : 0;
# try to retrieve the session ID
# fetch existing cookies
my %cookies = CGI::Cookie->fetch;
$sessionID = exists $cookies{'sessionID'}
? $cookies{'sessionID'}->value : '';
# 0 = not running, 1 = running
$status = $sessionID ? 1 : 0;
# switch status if asked to
$status = ($status+1) % 2 if $switch;
if ($status){
# preserve sessionID if exists or create a new one
$sessionID ||= generate_sessionID() if $status;
} else {
# delete the sessionID
$sessionID = '';
}
} # end of sub init
#################
sub print_header{
# prepare a cooke
my $c = CGI::Cookie->new
(-name => 'sessionID',
-value => $sessionID,
-expires => '+1h');
print $q->header
(-type => 'text/html',
-cookie => $c);
} # end of sub print_header
# print the current Session status and a form to toggle the status
#################
sub print_status{
print qq{<HTML><HEAD><TITLE>Cookie</TITLE></HEAD><BODY>};
# print status
print "<B>Status:</B> ",
$status
? "Session is running with ID: $sessionID"
: "No session is running";
# change status form
my $button_label = $status ? "Stop" : "Start";
print qq{<HR>
<FORM>
<INPUT TYPE=SUBMIT NAME=switch VALUE=" $button_label ">
</FORM>
};
print qq{</BODY></HTML>};
} # end of sub print_status
# A dummy ID generator
# Replace with a real session ID generator
########################
sub generate_sessionID {
return scalar localtime;
} # end of sub generate_sessionID
The code is very simple. It creates a session if you've pressed the
I<'Start'> button or deletes it if the I<'Stop'> button has been
pressed. The session is stored and retrieved using the cookies
technique.
Note that we have split the obviously simple and short code into a
three logical units, by putting the code into three subroutines.
init() to initialize global variable and parse incoming data,
print_header() to print the HTTP headers including the cookie header
and finally print_status() to generate the output. Later we will see
that this logical separation will allow us an easy conversion to Perl
content handler code.
We have used global variables for a few variables since we didn't want
to pass them from function to function. In a big project you should be
very restrictive about what variables should be allowed to be global
if any at all. In any case, the init() subroutine makes sure all these
variables are re-initialized for each code reinvocation.
Note that we have used a very simple generate_sessionID() function
that return a date string (i.e. S<Wed Apr 12 15:02:23 2000>) as a
session ID. You want to replace this one with code which generates a
unique session every time it was called. And it should be secure,
i.e. users will not be able to forge one and do nasty things.
=head2 Converting into Perl Content Handler
Now let's convert this script into a content handler. There are two
parts to be done; the first one is to configure Apache to run this new
code as a Perl handler, the second one is to modify the code itself.
First we add the following snippet to I<httpd.conf>:
PerlModule Test::Cookie
<Location /test/cookie>
SetHandler perl-script
PerlHandler Test::Cookie
</Location>
After we restart the server, when there is a request whose URI starts
with I</test/cookie>, Apache will execute C<Test::Cookie::handler()>
subroutine as a content handler. We made sure to preload the
C<Test::Cookie> module at the server start-up, with the C<PerlModule>
directive.
Now we are going to modify the script itself. We copy the content to
the file I<Cookie.pm> and place it into one of the directories listed
in C<@INC>. For example if I</home/httpd/perl> is a part of C<@INC>
and since we want to call this package C<Test::Cookie>, we can put
I</Cookie.pm> into the I</home/httpd/perl/Test/> directory.
So this is a new code. Notice that all the subroutines were left
unmodified from the original script, therefore we choose not to repeat
them here to make the differences clear.
Test/Cookie.pm
--------------
package Test::Cookie;
use Apache::Constants qw(:common);
use strict;
use CGI;
use CGI::Cookie;
use vars qw($q $switch $status $sessionID);
sub handler{
my $r = shift;
Apache->request($r);
init();
print_header();
print_status();
return OK;
}
### <-- subroutines --> ###
# all subroutines as before
1;
As you see there are two lines added to the beginning of the code:
package Test::Cookie;
use Apache::Constants qw(:common);
The first one declares the package name and the second one imports a
commonly used in Perl handlers status return code symbols.
use strict;
use CGI;
use CGI::Cookie;
use vars qw($q $switch $status $sessionID);
This code is left unchanged just as before.
sub handler{
my $r = shift;
Apache->request($r);
init();
print_header();
print_status();
return OK;
}
Each content handler (and any handler as well) should be started with
a subroutine by default called handler(). This subroutine is called
when a request's URI starts with I</test/cookie> per our
configuration. Of course you can choose a different name, like
execute() but than you should explicitly use it in the configuration
directives in the following way:
PerlModule Test::Cookie
<Location /test/cookie>
SetHandler perl-script
PerlHandler Test::Cookie::execute
</Location>
But we will use the default one.
The handler() subroutine is just like any other subroutinem, but
generally it has the following structure:
sub handler{
my $r = shift;
# the code
return STATUS;
}
First we get the request object by shifting it from C<@_> and
assigning it to the C<$r> variable.
Second we write the code that does the processing of the request.
Third we return the status of the execution. There are many possible
statuses, the most used are C<OK> and C<DECLINED>, which tells the
server whether they have completed a request phase the handler was
assigned to do or not, and there is a need to call another handler to
complete the processing. C<Apache::Constants> imports these two and
other commonly used status codes.
So in our example all we had to do is to wrap the three calls:
init();
print_header();
print_status();
inside:
sub handler{
my $r = shift;
Apache->request($r);
return OK;
}
There is one line we didn't discuss it:
Apache->request($r);
Since we use <CGI.pm>, it relies on the fact that C<$r> was set in the
C<Apache> module. C<Apache::Registry> did that behind the scenes, and
since we don't use C<Apache::Registry> here we have to do that
ourselves.
The only last thing we should do is to add C<1;> at the end of the
module, just like with any Perl module, so C<PerlModule> will not fail
when it tries to load C<Test::Cookie>.
So if we summarise, we took the original script's code and added the
following eight lines:
package Test::Cookie;
use Apache::Constants qw(:common);
sub handler{
my $r = shift;
Apache->request($r);
return OK;
}
1;
and now we have a full fledged Perl Content Handler.
=head2 Converting to use Apache Perl Modules
So now when we have a ready PerlHandler let's convert it to use the
Apache Perl modules, break the backward compatibility, but gain a
better performance since we are going to use Perl modules whose
internals are written in C, therefore we should get a significant
improve in the speed. The sections L<"Benchmarking Apache::Registry
and Perl Content Handler"|performance/Benchmarking_Apache_Registry_an>
and L<"Benchmarking CGI.pm and
Apache::Request"|performance/Benchmarking_CGI_pm_and_Apache_> compare
the three approaches.
What we are going to do is to replace C<CGI.pm> and C<CGI::Cookie>
with C<Apache::Request> and C<Apache::Cookie> respectively. The two
modules are written in C with XS interface to Perl, which makes your
code much faster if it utilizes any of these modules a lot.
C<Apache::Request> uses an API similar to the one C<CGI> uses, the
same goes for C<Apache::Cookie> and C<CGI::Cookie>. This allows an
easy porting process. Basically we just replace:
use CGI;
$q = new CGI;
with:
use Apache::Request ();
my $q = Apache::Request->new($r);
and
use CGI::Cookie ();
my $cookie = CGI::Cookie->new(...)
with
use Apache::Cookie ();
my $cookie = Apache::Cookie->new($r, ...);
This is the new code for C<Test::Cookie2>:
Test/Cookie2.pm
--------------
package Test::Cookie2;
use Apache::Constants qw(:common);
use strict;
use Apache::Request;
use Apache::Cookie ();
use vars qw($r $q $switch $status $sessionID);
sub handler{
$r = shift;
init();
print_header();
print_status();
return OK;
}
### <-- subroutines --> ###
# the init code
###########
sub init{
$q = Apache::Request->new($r);
$switch = $q->param("switch") ? 1 : 0;
# fetch existing cookies
my %cookies = Apache::Cookie->fetch;
# try to retrieve the session ID
$sessionID = exists $cookies{'sessionID'}
? $cookies{'sessionID'}->value : '';
# 0 = not running, 1 = running
$status = $sessionID ? 1 : 0;
# switch status if asked to
$status = ($status+1) % 2 if $switch;
if ($status){
# preserve sessionID if exists or create a new one
$sessionID ||= generate_sessionID() if $status;
} else {
# delete the sessionID
$sessionID = '';
}
} # end of sub init
#################
sub print_header{
# prepare a cooke
my $c = Apache::Cookie->new
($r,
-name => 'sessionID',
-value => $sessionID,
-expires => '+1h');
# Add a Set-Cookie header to the outgoing headers table
$c->bake;
$r->send_http_header('text/html');
} # end of sub print_header
# print the current Session status and a form to toggle the status
#################
sub print_status{
print qq{<HTML><HEAD><TITLE>Cookie</TITLE></HEAD><BODY>};
# print status
print "<B>Status:</B> ",
$status
? "Session is running with ID: $sessionID"
: "No session is running";
# change status form
my $button_label = $status ? "Stop" : "Start";
print qq{<HR>
<FORM>
<INPUT TYPE=SUBMIT NAME=switch VALUE=" $button_label ">
</FORM>
};
print qq{</BODY></HTML>};
} # end of sub print_status
# replace with a real session ID generator
########################
sub generate_sessionID {
return scalar localtime;
}
1;
The only other changes are in the print_header() function, where
instead of, passing the cookie code to the C<CGI>'s header() that
returns a proper HTTP header:
print $q->header
(-type => 'text/html',
-cookie => $c);
we do it in two stages.
$c->bake;
Adds a C<Set-Cookie> header to the outgoing headers table, and:
$r->send_http_header('text/html');
sends out the header itself. We have also eliminated:
Apache->request($r);
since we don't rely on C<CGI.pm> any more and in our case we don't
need it.
The rest of the code is unchanged.
Of course we add the following snippet to I<httpd.conf>:
PerlModule Test::Cookie2
<Location /test/cookie2>
SetHandler perl-script
PerlHandler Test::Cookie2
</Location>
So now the magic URI that will trigger the above code execution will
be the one starting with I</test/cookie2> and at this time we save the
code at I</home/httpd/perl/Test/Cookie2.pm> since we have called this
package as C<Test::Cookie2>.
=head2 Conclusion
If your took care to write the original plain CGI script's code in a
clean and modular way, you can see that the transition is a very
simple one and doesn't take a lot of effort and almost no code was
modified.
______________________________________________________________________
Stas Bekman | JAm_pH -- Just Another mod_perl Hacker
http://stason.org/ | mod_perl Guide http://perl.apache.org/guide
mailto:stas@stason.org | http://perl.org http://stason.org/TULARC/
http://singlesheaven.com| http://perlmonth.com http://sourcegarden.org
----------------------------------------------------------------------
RE: [RFC] Transitioning from Apache::Registry to Apache handlers
Posted by Matt Sergeant <ma...@sergeant.org>.
On Mon, 17 Apr 2000, Vivek Khera wrote:
> >>>>> "MS" == Matt Sergeant <ma...@sergeant.org> writes:
>
> >> adding handlers as easy as adding Registry scripts. I guess it is
> >> sort of an ultra-light-weight Registry, in some sense.
>
> MS> I've got something pretty similar. Let me know if you want some code.
>
> Sure; it is always good to see other ideas...
>
> Which handler phase did you tie into? I'm thinking just to go along
> the lines of Apache::Registry and use the content phase.
PerlFixupHandler. That way I eliminate stat() calls. At the end of the
fixup handler I push an ordinary PerlHandler onto the stack, which deals
with the main content delivery. But I suppose you could have the Fixup
handler determine what phase to use, via a call to a method in the module
you've used.
Anyway, here's the relevant bit of code, typed in and untested because
it's part of something much larger, so it might not quite work, but
hopefully you'll get the idea:
package Whatever;
sub fixup {
my $r = shift;
my $loc = $r->location;
my $handler = $r->uri;
if ($loc) {
$loc =~ s/\.\*$//; # remove wildcards
$loc =~ s/^\^//; # remove anchor at start
$prefix = $loc;
$handler =~ s/^\Q$loc\E//; # strip location from uri
}
else {
# handler starts from / (sensible?)
$handler =~ s/^\///;
}
$handler =~ s/\//::/g; # change / to ::
$handler =~ s/(.*)::/$1\->/; # change last :: to ->
my $module = $handler;
$module =~ s/\->.*$//;
eval {
require $module;
import $module;
}
if ($@) {
return 404;
}
no strict 'refs';
my $handler = $module->which_handler || 'PerlHandler';
$r->push_handlers( $handler, \&{$handler} );#
return OK;
}
Stick it as a PerlFixupHandler in a <Location> or <LocationMatch>
directive.
--
<Matt/>
Fastnet Software Ltd. High Performance Web Specialists
Providing mod_perl, XML, Sybase and Oracle solutions
Email for training and consultancy availability.
http://sergeant.org http://xml.sergeant.org
RE: [RFC] Transitioning from Apache::Registry to Apache handlers
Posted by Vivek Khera <kh...@kciLink.com>.
>>>>> "MS" == Matt Sergeant <ma...@sergeant.org> writes:
>> adding handlers as easy as adding Registry scripts. I guess it is
>> sort of an ultra-light-weight Registry, in some sense.
MS> I've got something pretty similar. Let me know if you want some code.
Sure; it is always good to see other ideas...
Which handler phase did you tie into? I'm thinking just to go along
the lines of Apache::Registry and use the content phase.
RE: [RFC] Transitioning from Apache::Registry to Apache handlers
Posted by Doug MacEachern <do...@covalent.net>.
On Mon, 17 Apr 2000, Vivek Khera wrote:
> >>>>> "SB" == Stas Bekman <sb...@stason.org> writes:
>
> SB> Of course, anyone has a sample <Perl> section handy? I'm still an
> SB> C<Apache::Registry> fan, to be changed soon :)
>
> I don't see what <Perl> sections have to do with using or not
> Apache::Registry instead of handlers...
>
> But, I've been toying with the idea of writing an Apache::Dispatch
> module that would take all URL's of the form something like
>
> http://localhost/perl/My/Module/handlerfunc
>
> and dispatch the call to My::Module::handlerfunc()
that would be really cool, so long as you can limit which namespaces can
be called by the dispatcher. e.g. i wouldn't want the dispatcher to run
http://localhost/perl/CORE/dump :)
RE: [RFC] Transitioning from Apache::Registry to Apache handlers
Posted by Stas Bekman <sb...@stason.org>.
On Mon, 17 Apr 2000, Vivek Khera wrote:
> >>>>> "SB" == Stas Bekman <sb...@stason.org> writes:
>
> SB> Of course, anyone has a sample <Perl> section handy? I'm still an
> SB> C<Apache::Registry> fan, to be changed soon :)
>
> I don't see what <Perl> sections have to do with using or not
> Apache::Registry instead of handlers...
Because when you have hundreds of different <Location>'s to configure (and
there is a lot of repetition), it's easier with Perl. Isn't it? At least
that's what people said on the list.
> But, I've been toying with the idea of writing an Apache::Dispatch
> module that would take all URL's of the form something like
>
> http://localhost/perl/My/Module/handlerfunc
>
> and dispatch the call to My::Module::handlerfunc()
>
> Assuming that My::Module was already loaded, otherwise it would
> generate a run-time error (or maybe we'd do a "require" -- dunno yet).
> The URL trigger /perl/ would be configurable, of course.
>
> Does anyone have something like this already? It would certainly make
> adding handlers as easy as adding Registry scripts. I guess it is
> sort of an ultra-light-weight Registry, in some sense.
Cool!
______________________________________________________________________
Stas Bekman | JAm_pH -- Just Another mod_perl Hacker
http://stason.org/ | mod_perl Guide http://perl.apache.org/guide
mailto:stas@stason.org | http://perl.org http://stason.org/TULARC/
http://singlesheaven.com| http://perlmonth.com http://sourcegarden.org
----------------------------------------------------------------------
Re: [RFC] Transitioning from Apache::Registry to Apache handlers
Posted by Vivek Khera <kh...@kciLink.com>.
>>>>> "DT" == Drew Taylor <dt...@vialogix.com> writes:
DT> are beginning the transition to Apache handlers. One other thing that I
DT> would love is a module to do checkboxes/pull-down list generation ALA
DT> CGI.pm. I might rip off some code and create a module myself. I think it
Have a look at CGI::Form. I think it needs CGI::Base and/or
CGI::Request.
These are dated modules, and have not been maintained in a long time
as far as I can see, but they were intended as a more object-oriented
CGI API than CGI.pm.
Re: [RFC] Transitioning from Apache::Registry to Apache handlers
Posted by Drew Taylor <dt...@vialogix.com>.
Matt Sergeant wrote:
>
> On Mon, 17 Apr 2000, Vivek Khera wrote:
>
> > But, I've been toying with the idea of writing an Apache::Dispatch
> > module that would take all URL's of the form something like
> >
> > http://localhost/perl/My/Module/handlerfunc
> >
> > and dispatch the call to My::Module::handlerfunc()
> >
> > Assuming that My::Module was already loaded, otherwise it would
> > generate a run-time error (or maybe we'd do a "require" -- dunno yet).
> > The URL trigger /perl/ would be configurable, of course.
> >
> > Does anyone have something like this already? It would certainly make
> > adding handlers as easy as adding Registry scripts. I guess it is
> > sort of an ultra-light-weight Registry, in some sense.
>
> I've got something pretty similar. Let me know if you want some code.
Since I believe I'm the one that started this thread, I'd love to see
some code to enable handlers on the fly. In my case I only have perhaps
a half-dozen handlers, but multiply this times a lot of virtual hosts
and it then becomes a great boon.
IMHO, I think this would be a very useful module to people like me who
are beginning the transition to Apache handlers. One other thing that I
would love is a module to do checkboxes/pull-down list generation ALA
CGI.pm. I might rip off some code and create a module myself. I think it
would be a good first project (or maybe not - who knows until I try?)
--
Drew Taylor
Vialogix Communications, Inc.
501 N. College Street
Charlotte, NC 28202
704 370 0550
http://www.vialogix.com/
RE: [RFC] Transitioning from Apache::Registry to Apache handlers
Posted by Matt Sergeant <ma...@sergeant.org>.
On Mon, 17 Apr 2000, Vivek Khera wrote:
> But, I've been toying with the idea of writing an Apache::Dispatch
> module that would take all URL's of the form something like
>
> http://localhost/perl/My/Module/handlerfunc
>
> and dispatch the call to My::Module::handlerfunc()
>
> Assuming that My::Module was already loaded, otherwise it would
> generate a run-time error (or maybe we'd do a "require" -- dunno yet).
> The URL trigger /perl/ would be configurable, of course.
>
> Does anyone have something like this already? It would certainly make
> adding handlers as easy as adding Registry scripts. I guess it is
> sort of an ultra-light-weight Registry, in some sense.
I've got something pretty similar. Let me know if you want some code.
--
<Matt/>
Fastnet Software Ltd. High Performance Web Specialists
Providing mod_perl, XML, Sybase and Oracle solutions
Email for training and consultancy availability.
http://sergeant.org http://xml.sergeant.org
RE: [RFC] Transitioning from Apache::Registry to Apache handlers
Posted by Vivek Khera <kh...@kciLink.com>.
>>>>> "SB" == Stas Bekman <sb...@stason.org> writes:
SB> Of course, anyone has a sample <Perl> section handy? I'm still an
SB> C<Apache::Registry> fan, to be changed soon :)
I don't see what <Perl> sections have to do with using or not
Apache::Registry instead of handlers...
But, I've been toying with the idea of writing an Apache::Dispatch
module that would take all URL's of the form something like
http://localhost/perl/My/Module/handlerfunc
and dispatch the call to My::Module::handlerfunc()
Assuming that My::Module was already loaded, otherwise it would
generate a run-time error (or maybe we'd do a "require" -- dunno yet).
The URL trigger /perl/ would be configurable, of course.
Does anyone have something like this already? It would certainly make
adding handlers as easy as adding Registry scripts. I guess it is
sort of an ultra-light-weight Registry, in some sense.
--
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Vivek Khera, Ph.D. Khera Communications, Inc.
Internet: khera@kciLink.com Rockville, MD +1-301-545-6996
PGP & MIME spoken here http://www.kciLink.com/home/khera/
RE: [RFC] Transitioning from Apache::Registry to Apache handlers
Posted by Stas Bekman <sb...@stason.org>.
On Fri, 14 Apr 2000, Chris Nokleberg wrote:
>
> > Someone has asked how to move from registry scripts to perl handlers, this
> > is my attempt to show in details the process. Comments are welcome.
>
> In my mind, one of the biggest problems in transitioning from
> Apache::Registry is the added server configuration complexity. Would it be
> possible to add a section on the best way to simplify or eliminate the need
> to modify the conf file for each new handler? <Perl> sections, etc.?
Of course, anyone has a sample <Perl> section handy? I'm still an
C<Apache::Registry> fan, to be changed soon :)
______________________________________________________________________
Stas Bekman | JAm_pH -- Just Another mod_perl Hacker
http://stason.org/ | mod_perl Guide http://perl.apache.org/guide
mailto:stas@stason.org | http://perl.org http://stason.org/TULARC/
http://singlesheaven.com| http://perlmonth.com http://sourcegarden.org
----------------------------------------------------------------------
RE: [RFC] Transitioning from Apache::Registry to Apache handlers
Posted by Chris Nokleberg <ch...@sportsrocket.com>.
> Someone has asked how to move from registry scripts to perl handlers, this
> is my attempt to show in details the process. Comments are welcome.
In my mind, one of the biggest problems in transitioning from
Apache::Registry is the added server configuration complexity. Would it be
possible to add a section on the best way to simplify or eliminate the need
to modify the conf file for each new handler? <Perl> sections, etc.?
Thanks,
Chris
----------------------------------------------------------------------
Chris Nokleberg + Internet Sports Network, Inc.
chris@sportsrocket.com + http://www.SportsRocket.com/
Re: [RFC] Transitioning from Apache::Registry to Apache handlers
Posted by Doug MacEachern <do...@covalent.net>.
On 20 Apr 2000, Randal L. Schwartz wrote:
> >>>>> "Doug" == Doug MacEachern <do...@covalent.net> writes:
>
> Doug> why all the globals?? symbol table lookups are much slower than
> Doug> lexicals.
>
> If I recall, the word lately is that they're much closer than they were.
i take it back, the symbol table lookups for globals are done at compile
time, 5.x has always done that, i think. by the looks of:
perl -MO=Terse -e 'my $lex = 1; our $ogv = 1; $gv = 1'
they still behave the same at runtime, though what happens during compile
time might be different.
> But lexicals are still "cleaner", if I recall.
indeed.
Re: [RFC] Transitioning from Apache::Registry to Apache handlers
Posted by "Randal L. Schwartz" <me...@stonehenge.com>.
>>>>> "Doug" == Doug MacEachern <do...@covalent.net> writes:
Doug> why all the globals?? symbol table lookups are much slower than
Doug> lexicals.
If I recall, the word lately is that they're much closer than they were.
But lexicals are still "cleaner", if I recall.
--
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
<me...@stonehenge.com> <URL:http://www.stonehenge.com/merlyn/>
Perl/Unix/security consulting, Technical writing, Comedy, etc. etc.
See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!
Re: [RFC] Transitioning from Apache::Registry to Apache handlers
Posted by Doug MacEachern <do...@covalent.net>.
> So this (attached) section is to be deleted now as a non-relevant?
i suppose.
Re: [RFC] Transitioning from Apache::Registry to Apache handlers
Posted by Stas Bekman <sb...@stason.org>.
On Thu, 20 Apr 2000, Doug MacEachern wrote:
> On Fri, 14 Apr 2000, Stas Bekman wrote:
>
> > use vars qw($q $switch $status $sessionID);
>
> why all the globals?? symbol table lookups are much slower than lexicals.
> please don't promote globals, pass lexicals to the subroutines.
Yeah, I'll fix that. Just wanted to make the example less messy :)
> > sub handler{
> > my $r = shift;
> > Apache->request($r);
>
> you actually don't need to do that anymore as of 1.22
Oh, that's why -- I've tried without it and worked!
So this (attached) section is to be deleted now as a non-relevant?
=head1 Accessing the Request Object in non-Perl*Handler Modules
C<Perl*Handler>s can obtain a reference to the request object when it
is passed to them via C<@_>. For example:
sub handler {
my $r = shift;
# ... some code
return OK;
}
In C<Apache::Registry> scripts (and friends), the request object
is available through the C<Apache-E<gt>request($r)> method. For example:
my $r = Apache->request;
print $r->uri;
In order to make the above work, C<Apache::Registry> internally passes
the original object to C<Apache-E<gt>request($r)> (transparantly to
the its users). It does:
sub handler {
my $r = shift;
Apache->request($r);
# ... lots of voodoo code :)
return OK;
}
Some modules, like C<CGI.pm>, rely on the fact that
C<Apache-E<gt>request()> will retrieve the request object. So when you
use these modules with a script running under C<Apache::Registry> (and
friends) everything is fine. However if you write your own
C<Perl*Handler> you should explicitly write C<Apache-E<gt>request($r)>
to make these modules work, just like in the above code snippet.
______________________________________________________________________
Stas Bekman | JAm_pH -- Just Another mod_perl Hacker
http://stason.org/ | mod_perl Guide http://perl.apache.org/guide
mailto:stas@stason.org | http://perl.org http://stason.org/TULARC/
http://singlesheaven.com| http://perlmonth.com http://sourcegarden.org
----------------------------------------------------------------------
Re: [RFC] Transitioning from Apache::Registry to Apache handlers
Posted by Doug MacEachern <do...@covalent.net>.
On Fri, 14 Apr 2000, Stas Bekman wrote:
> use vars qw($q $switch $status $sessionID);
why all the globals?? symbol table lookups are much slower than lexicals.
please don't promote globals, pass lexicals to the subroutines.
> sub handler{
> my $r = shift;
> Apache->request($r);
you actually don't need to do that anymore as of 1.22