|
Intro to Mod_Perl
Page 5
Using Mod_perl to Speed Up Your CGIs
Mod_perl is often used to speed up your CGI scripts. Normally each time you
run a CGI script, the CGI runs as a distinct process. But mod_perl embeds a copy of the Perl interpreter inside Apache, so the data is already right there and ready to go. This cuts down on the number of processes needed for a given request and frees up your processor to run other things - thus making everything faster. However, this speed comes with a catch: You must write your scripts very carefully.
Usually you can get away with sloppy programming with your CGI scripts,
because a CGI program only lasts for the duration of an HTTP request. But
with mod_perl, your Perl scripts stay in memory, so you need to properly
define your variables and make sure to close any files you open. The best
way to demonstrate this is with an example, so let's take a look at two
simple CGI scripts.
This CGI script looks to see how many names in a file called "DATA.TXT"
contain the text string represented by the CGI value "search."
#!/usr/bin/perl
use CGI qw(:standard);
my $query = new CGI;
print $query->header;
print "<html>\n";
print "<head><title>CGI Results</title></head>\n";
print "<body bgcolor=\"#FFFFFF\">\n";
if ($query->param("search")) {
$search = $query->param("search");
open(DATA,"DATA.TXT") || print "Open Error: $!\n";
while (<DATA>) {
if (/${search}/i) {
$customers++;
}
}
print "We have $customers customers ";
print "whose names contain \"$search\"<p>\n";
} else {
print "<form method=GET action=",$ENV{"SCRIPT_NAME"},">\n";
print "<input name=search size=10 value=\"r\">\n";
print "<input type=submit>\n";
print "</form>\n";
}
print "</body></html>\n";
Next drop the following data into a file called "DATA.TXT":
robert
john
james
jonathan
jim
sally
sue
frank
bob
sandy
If you now search for the letter R, the CGI script will tell you that
two customers have the letter R in their name. Unfortunately, this script
has two errors that will cause it to break under mod_perl. First, the file
DATA.TXT is never closed, so each request leaves an open process, which can do any number of bad things (send your processor into a loop, overflow a memory buffer and crash your server, etc.). To correct this, just add the line close(DATA); to the script.
The second problem with the script is that it never properly defines the
variable customers. By default, it becomes a global variable. This
works fine as a regular CGI script, since values are destroyed once a CGI
script exits. Under mod_perl, however, the value of customer will be
added to the previous value for every subsequent request. The first time through we'll get two, the second time we'll get four, then six, eight, and
so on. This can easily be solved by declaring the variable locally. Here's
the script all cleaned up and ready to run under mod_perl:
#!/usr/bin/perl
use CGI qw(:standard);
my $query = new CGI;
print $query->header;
print "<html>\n";
print "<head><title>CGI Results</title></head>\n";
print "<body bgcolor=\"#FFFFFF\">\n";
if ($query->param("search")) {
my $search = $query->param("search");
my $customers;
open(DATA,"DATA.TXT") || print "Open Error: $!\n";
while (<DATA>) {
if (/${search}/i) {
$customers++;
}
}
close(DATA);
print "We have $customers customers ";
print "whose name contains \"$search\"<p>\n";
} else {
print "<form method=GET action=",$ENV{"SCRIPT_NAME"},">\n";
print "<input name=search size=10 value=\"r\">\n";
print "<input type=submit>\n";
print "</form>\n";
}
print "</body></html>\n";
OK, now that you've made sure all your CGI scripts are airtight, let's
teach Apache how to parse them with mod_perl.
next page»
|
|
|