Getting
Your Message Across with Apache
Carlos Ramirez
Have you ever posted an important message that went unnoticed
on your Web site? Or put a critical shutdown announcement on your
home page that was never visited? Unfortunately, this is a common
occurrence that many Web administrators face. All too often admins
post important system status information affecting the computing
environment, yet Web users will still be oblivious to why the server
is down. It turns out that the majority of users do not access Web
sites through the main home page. Instead, they access sections
of a Web site through their bookmarks, or other external links.
Despite efforts to train Web users to frequently visit our home
page for pertinent news items they forget to do so. In this article,
I present an Apache module that I created to tackle this specific
problem. It provides a way to push your important messages to your
user community so that anyone accessing any Web page on your server
will get the message.
The Solution
The module is called Apache::Motd. As the name implies,
this module works on Apache Web servers and is based on the "Message
Of The Day" (or motd) utility found on UNIX systems. This module
equips a Web server with the same functionality provided by motd.
Once the module is installed, the administrator can configure the
Web server to display the message of the day to every user accessing
any Web page on the server. It momentarily intercepts the initial
request and displays the contents of the motd file, then the user
is redirected to the originally requested document. The initial
request also sets a cookie so that subsequent visits are not directed
to the message of the day. Several parameters allow administrators
to customize this process, such as the contents of the message of
the day, the length of time the message is displayed before it redirects
the user, and cookie expiration. Before describing these options
in more detail, I will give a brief overview of mod_perl
and how it can be used to customize the stages of individual HTTP
transactions.
Understanding mod_perl and the Apache HTTP Phases
A mod_perl-enabled Apache Web server presents many new
and interesting ways for an administrator to configure a Web server.
It also allows customization for each individual HTTP request by
providing a Perl interface to Apache's internal functions.
This extraordinary feature enables you to alter or override how
Apache handles a specific request even down to a specific HTTP phase
within a request. There are of course many other remarkable features,
like the powerful performance boost that CGI scripts gain through
mod_perl or code caching available through the fully functional
embedded Perl interpreter in the server. However, I will only focus
on the features that relate to Apache::Motd, specifically
customization of HTTP phase requests. If you want to learn more
about mod_perl, there are two excellent resources available,
the "eagle" book, Writing Apache Modules with Perl
and C from O'Reilly & Associates and the online mod_perl
guide available in the Apache/Perl Intergration Project Web site
("the official mod_perl site").
Although I will not go into detail or describe each individual
phase, it is important to know which phases occur during an HTTP
transaction. Every HTTP request goes through a series of eight phases
-- all of which can be overridden or altered using a mod_perl
handler (or module). The phases occur in the following order: post-read-request,
URI translation, header parsing, access control, authentication,
authorization, mime-type checking, and fixups. In addition, there
is a logging phase that can take place within any of eight phases
mentioned. As you can see, mod_perl offers many ways to extend
the functionality of the Web server at various steps of each request.
Now that I've given a general idea of how mod_perl and
Apache are related and which phases are involved in an HTTP request,
I will explain how and when Apache::Motd comes into play.
How Apache::Motd Works
This module is called during the "Header Parser" phase
of an HTTP transaction. Although this implies that the module will
be processing or manipulating incoming headers, this is not the
case. I selected this phase simply because this is the earliest
phase in which a mod_perl handler can occur within <Directory>,
<Location>, or <Files> configuration directives or within
.htaccess files. By allowing this module to work within these
directives, you can implement different messages for individual
sections of your Web site. See Figure 1.
All mod_perl handlers are invoked through the common subroutine
called handler(). So in this case, when the Header Parser
phase is activated, Apache looks for Apache::Motd::handler
subroutine. The actual perl handler code is quite simple (see Listing
1). It follows the general outlined procedure:
1. Save the path of the original requested document (or URI) to
the variable: $uri.
2. Verify that the motd file defined in the httpd.conf
exists and continue processing, otherwise stop processing and begin
next phase of the HTTP transaction.
3. Check if the motd cookie has already been set (i.e., has the
user seen the motd?). If cookieName is set then continue
processing, otherwise, send request to next phase.
4. Create cookie and set cookie value including the expiration
date.
5. Open motd file, substitute $uri and $redirect_time
and display the contents of the motd.
The process above is executed when SupportCookieLess is
set to 0. When it is set to 1, an additional step is added to the
process to check whether the client can accept cookies by performing
an external redirect. But in either case, the execution time of
this process is unnoticeable by the user, due to the embedded Perl
interpreter and the code caching features offered by mod_perl.
Installing Apache::Motd
Before you can install Apache::Motd, you must have the
following software on your system:
- Apache Web Server v1.3.x (http://www.apache.org/dist/)
- mod_perl 1.2x (http://perl.apache.org/dist/)
- Apache::Cookie (http://search.cpan.org/search?dist=libapreq)
Once you've satisfied the above requirements, you can download
Apache::Motd from CPAN.org (http://cpan.valueclick.com/authors/id/C/CR/CRAMIREZ/)
or from Sys Admin's Web site:
http://www.sysadminmag.com/code/
The installation process takes only a few simple steps:
$ gzip -dc Apache-Motd-0.03.tar.gz | tar xvf -
$ cd Apache-Motd-0.03
$ perl Makefile.PL
$ make
$ make install
Configuring Apache::Motd
The following is a list of Apache::Motd configuration parameters.
All parameters are optional. However, please note that if the MessageFile
is not found in the specified directory, requests will not be directed
to the motd. This feature allows you to rename or delete this file
from the specified location to disable the motd without having to
edit the httpd.conf entry or restart the Web server.
MessageFile /path/to/motd_file -- The filesystem path
to the motd file. (See Figure 3 for a sample motd file.)
RedirectInSecs N (default: 10 seconds) -- This sets
the wait time (in seconds) before the visitor is redirected to the
initially requested URI.
CookieName cookie_name (default: seenMOTD) --
Set the name of the cookie name.
ExpireCookie 1 day (default: 1 day) -- Set the expiration
time for the cookie.
SupportCookieLess (1|0) (default: 1) -- This parameter
is set by default to handle clients that do not support cookies
or that have cookies turned off. This option performs an external
redirect for the initial request to check whether cookies are turned
on. If cookies are rejected, visitors are automatically redirected
to their original request, bypassing the motd.
The Message File Format
The text file should at least include the following tag variables.
These tags provide necessary information to allow redirection to
the original request and the time (in seconds) before the redirection
takes place. See Figure 3.
- VAR_URI -- This tag will be replaced with the URL:
http://$SERVER.$uri
Example: <a href="<VAR_URI>">click here to proceed</a>
The above example provides a link to the original requested document,
so that a user can click and bypass the redirect time.
- VAR_REDIRECT -- This tag will be replaced with the
value set in RedirectInSecs, which can be used in the meta
tag for redirection. See Figure 3 for a sample motd file.
Things to note about the sample message:
- The meta tag entry must be included in the motd file
to ensure that the user is redirected to the original requested
document. Otherwise, redirection will not occur.
- Providing a link where a user can click to bypass redirect
time can be a useful and courteous gesture for fast readers.
Apache::Motd allows you to set up different motd messages
for different sections of your Web site. Figure 1 demonstrates various
configurations that may be included in your httpd.conf file.
In configuration Setup 1, there are two separate sections that
will activate the "Message of the Day". Users accessing
Web pages from /path/to/customers will be presented with
their own message contained in /path/to/customers/motd. While
Web pages accessed from /path/to/sales_department will be
presented with their own message contained in /path/to/sales_department/motd.
In both instances, users will be directed to the original requested
documents after 10 seconds (default).
In configuration Setup 2 (Figure 2), any Web page accessed on
the Web server will be presented with the motd located in $SERVER_ROOT/conf/motd.
A cookie named sitewideMOTD will be sent to the browser, will redirect
users to their originally requested document in 15 seconds, and
will expire the cookie in a week. In this configuration, users are
only presented with the specified motd once a week.
Beyond Motd
Although Apache::Motd was originally intended to propagate
important messages to our Web community, I have found other interesting
uses for it. For instance, you can add a "Terms of Usage"
screen to an existing Web application, without having to modify
any existing code. This can easily be implemented simply by adding
the following to your httpd.conf file:
<Location /myguestbook>
PerlHeaderParserHandler Apache::Motd
PerlSetVar MessageFile /path/to/TermsOfUsage
PerlSetVar CookieName guestbookTermsOfUsage
</Location>
In this case, you would not include the meta tag entry in your "Terms
Of Usage" page so that the user is required to click on the link
to continue. All you would need to include would be your Terms of
Usage statement and a link using the VAR_URI tag that reads:
"I agree". For example:
<a href="<VAR_URI>">I Agree</a>
Limitations
One known limitation is related to the use of cookies. The use
of cookies provides a means of maintaining state, in our case, it
provides a way to determine if a visitor has encountered the motd.
Unfortunately, some users choose not to accept cookies by setting
their browsers to reject cookies. For those cases, you just have
to rely on other forms of communication to reach those users, since
the current implementation of Apache::Motd cannot track whether
these users have seen the motd. However, future enhancements are
currently being developed so that cookie-less Web users will not
escape the motd. So stay tuned.
Carlos Ramirez graduated from Cal State Fullerton with a degree
in Physics. Since then he has worked as a UNIX systems administrator
and Web developer. His primary interests are Web server management,
Web application development, Internet/Intranet architecture and
programming in Perl. He can be reached at: carlos@quantumfx.com.
|