| home / programming / perl / mod_perl / chap6 / 3 | [previous] [next] |
|
|
Now that we have a complete PerlHandler,
let's convert it to use the mod_perl API and mod_perl-specific modules. First,
this may give us better performance where the internals of the API are implemented
in C. Second, this unleashes the full power of Apache provided by the mod_perl
API, which is only partially available in the mod_cgi-compatible modules.
We are going to replace CGI.pm and
CGI::Cookie with their mod_perl-specific equivalents:
Apache::Request and Apache::Cookie,
respectively. These two modules are written in C with the XS
interface to Perl, so code that uses these modules heavily runs much faster.
Apache::Request has an API similar
to CGI's, and Apache::Cookie
has an API similar to CGI::Cookie's. This makes
porting straightforward. Essentially, we just replace:
use CGI;$q = new CGI;
with:
use Apache::Request ( );$q = Apache::Request->new($r);
And we replace:
use CGI::Cookie ( );my $cookie = CGI::Cookie->new(...)
with:
use Apache::Cookie ( );my $cookie = Apache::Cookie->new($r, ...);
Example 6-20 is the new code for Book::Cookie2.
Example 6-20: Book/Cookie2.pm
package Book::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;}sub init {$q = Apache::Request->new($r);$switch = $q->param("switch") ? 1 : 0;my %cookies = Apache::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 if $switch;if ($status) {# preserve sessionID if it exists or create a new one$sessionID ||= generate_sessionID( ) if $status;} else {# delete the sessionID$sessionID = '';}}sub print_header {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');}# print the current Session status and a form to toggle the statussub print_status {print qq{<html><head><title>Cookie</title></head><body>};print "<B>Status:</B> ",$status? "Session is running with ID: $sessionID": "No session is running";# change status formmy $button_label = $status ? "Stop" : "Start";print qq{<hr><form><input type=submit name=switch value=" $button_label "></form>};print qq{</body></html>};}# replace with a real session ID generatorsub generate_sessionID {return scalar localtime;}1;
The only other changes are in the print_header(
) function. Instead of passing the cookie code to CGI's
header( ) function to return a proper HTTP header,
like this:
print $q->header(-type => 'text/html',-cookie => $c);
we do it in two stages. First, the following line adds a Set-Cookie
header to the outgoing headers table:
$c->bake;
Then this line sets the Content-Type
header to text/html and sends out the whole HTTP header:
$r->send_http_header('text/html');
The rest of the code is unchanged.
The last thing we need to do is add the following snippet to httpd.conf:
PerlModule Book::Cookie2<Location /test/cookie2>SetHandler perl-scriptPerlHandler Book::Cookie2</Location>
Now the magic URI that will trigger the above code execution will
be one starting with /test/cookie2. We save the code
in the file /home/httpd/perl/Book/Cookie2.pm, since
we have called this package Book::Cookie2.
As you've seen, converting well-written CGI code into mod_perl handler code is straightforward. Taking advantage of mod_perl-specific features and modules is also generally simple. Very little code needs to be changed to convert a script.
Note that to make the demonstration simple to follow, we haven't changed the style of the original package. But by all means consider doing that when porting real code: use lexicals instead of globals, apply mod_perl API functions where applicable, etc.
| home / programming / perl / mod_perl / chap6 / 3 | [previous] [next] |
Created: March 27, 2003
Revised: July 23, 2003
URL: http://webreference.com/programming/perl/mod_perl/chap6/3