Electric Type

Multimedia

About Us

News

Help

Intro to Mod_Perl

Page 7 — Extending Apache's Functionality

Apache::Registry made CGI requests run faster by calling the handler subroutine for each request in that location. Let's extend this concept by creating our own handler that does something completely different.

Say we want to append a small chunk of content to each document, like those banners and pop-ups that many free Web hosting companies use. In this example, we'll drop in some text after the BODY tag.

First let's tell Apache to attach our text to every HTML file. In your "access.conf" file, add something like this:

<Files index.html>
SetHandler perl-script
PerlHandler Apache::Add_Header
</Files>
We've now told Apache to send the request to the Add_Header module whenever a request comes in for a file called index.html. If you want to do this for all HTML files, set it to . Be careful, since that can cause things to break if you're using frames.

To complete the request, mod_perl needs to reference this module:

package Apache::Add_Header;

use Apache ();


sub handler {
        my $r = shift;  # @_[0] contains a reference to
                        # the current request handler

        my ($file) = $r->filename; # Full pathname to file

        if (open(FILE,$file)) {
                my ($body_start) = 0;

                $r->send_http_header;
                $r->status(200);
                while (<FILE>) {
                        my ($line) = $_;

                        if ($line =~ /([^>]*<)([^ >]+)([^>]+>)(.*)/) {
                                my ($before_tag) = $1;
                                my ($tag_identifier) = $2;
                                my ($rest_of_tag) = $3;
                                my ($rest_of_line) = $4;

                                if ($tag_identifier =~ /body/i) {
                                 # Complete body tag was found.
                                        $r->print($before_tag);
                                        $r->print($tag_identifier);
                                        $r->print($rest_of_tag);
                                        &message($r);
                                        $r->print($rest_of_line);
                                } else {
                                        $r->print($line);
                                }
                        } elsif ($line =~ /([^>]*<)([^ >]+)([^>]+)/) {
                                my ($before_tag) = $1;
                                my ($tag_identifier) = $2;
                                my ($rest_of_tag) = $3;

                                if ($tag_identifier =~ /body/i) {
                           # got a body tag that wraps multiple
                           # lines
                                        $body_start=1;
                                }
                                $r->print($line);
                        } elsif (($body_start == 1) &&
                                        ($line =~ /([^>]*>)(.*)/)) {
                                my ($rest_of_tag) = $1;
                                my ($rest_of_line) = $2;

                                $r->print($rest_of_tag);
                                &message($r);
                                $r->print($rest_of_line);
                                $body_start=0;
                        } else {
                                $r->print($line);
                        }
                }
        } else {
                $r->send_http_header;
                $r->status(403);
        }
        return $r->status;
}

sub message {
        my ($r) = shift;
        $r->print("<center>Thanks for using this service!</center><p>\n");
}
1;
Give this module the filename Add_Header.pm, and save it in the Apache directory in Perl's search path. If you're running Unix, this directory is usually /usr/lib/perl5/site_perl/Apache.

Let's take a look at how this script is interacting with Apache. The first line - package Apache::Add_Header; - must correspond to the correct location in the file system. If the file name and the package name don't match, Perl won't compile the script properly. Next, import the routines that tell it how to interact with Apache. This module is named Apache.pm, and it's part of the mod_perl installation. It ties your input and output to Apache, and it also gives you information about the current connection. To learn more about this module, check out the documentation, accessible by running perldoc Apache from the command line.

Each request then calls the handler subroutine, which passes a reference to the request object. This object contains all the information and routines necessary to build and service a request. In this example, the first thing we needed to do was send a status header to the client. Note that you must use the interface provided by Apache.pm to send information to the client. You can't simply use the print statement provided by Perl because the STDIN and STDOUT streams aren't tied to your script like they are with a CGI script. To send text to the client, we use the print function in the request object, $r->print("text").

Lastly, remember to return a status code to Apache. Note that it is possible to return a different status code to the client than the one sent to Apache.

The request that Apache sends your subroutine may not be the original request. For example, let's assume the client originally requested the file /this_file_does_not/exist and Apache had been configured with an ErrorDocument 404/mod-perl/my-script directive. The request that is passed to your mod_perl module will be the one referencing the /mod-perl/my-script request, not /this_file_does_not/exist. Luckily, Apache keeps a record of each request, and every request object lets you return a blessed reference to the next, last, main, and initial requests.

Let's see it all at work.

next page»


Dynamic HTML  

Frames  

HTML Basics  

Stylesheets  

Tables  

XML  

Javascript  

Database Connections  

Intro To Perl  

HTML 4.0  

User Blogs

Screen Shots

Latest Updates

Contact Us

Valid HTML 4.01!
Valid CSS!

Breadcrumb

© ElectricType
Maintained by My-Hosts.com
Site map | Copyright | Disclaimer
Privacy policy | Acceptable Use Policy
Legal information.