Table of Contents:
This module provides the Apache/mod_perl user a mechanism for storing
persistent user data in a global hash, which is independent of its real
storage mechanism. Currently you can choose from these storage mechanisms Apache::Session::DBI
, Apache::Session::Win32
,
Apache::Session::File
, Apache::Session::IPC
. Read the man page of the mechanism you want to use for a complete
reference.
What Apache::Session
does is provide persistence to a data structure. The data structure has an
ID number, and you can retrieve it by using the ID number. In the case of
Apache, you would store the ID number in a cookie or the URL to associate
it with one browser, but the method of dealing with the ID is completely up
to you. The flow of things is generally:
Tie a session to Apache::Session. Get the ID number. Store the ID number in a cookie. End of Request 1.
(time passes)
Get the cookie. Restore your hash using the ID number in the cookie. Use whatever data you put in the hash. End of Request 2.
Using Apache::Session
is easy: simply tie a hash to the session object, stick any data structure
into the hash, and the data you put in automatically persists until the
next invocation. Here is a quick example which uses cookies to track the
user's session.
# Pull in the require packages use Apache::Session::DBI; use Apache; use strict; # Read in the cookie if this is an old session my $r = Apache->request; my $cookie = $r->header_in('Cookie'); $cookie =~ s/SESSION_ID=(\w*)/$1/; # Create a session object based on the cookie we got from the # browser, or a new session if we got no cookie my %session; tie %session, 'Apache::Session::DBI', $cookie, {DataSource => 'dbi:mysql:sessions', UserName => $db_user, Password => $db_pass }; # Might be a new session, so lets give them their cookie back my $session_cookie = "SESSION_ID=$session{_session_id};"; $r->header_out("Set-Cookie" => $session_cookie);
After setting this up, you can stick anything you want into
%session
(except file handles), and it will still be there
when the user invokes the next page.
It is possible to write an Apache authen handler using
Apache::Session
. You can put your authentication token into the session. When a user
invokes a page, you open their session, check to see if they have a valid
token, and approve or deny their authorization based on that.
As for IIS, let's compare. IIS's sessions are only valid on the same web
server as the one that issued the session.
Apache::Session
's session objects can be shared amongst a farm of many machines running
different operating systems, including even Win32. IIS stores session
information in RAM. Apache::Session
stores sessions in databases, file systems, or RAM. IIS's sessions are only
good for storing scalars or arrays. Apache::Session
's sessions allow you to store arbitrarily complex objects. IIS sets up the
session and automatically tracks it for you. With
Apache::Session
, you setup and track the session yourself. IIS is proprietary. Apache::Session
is open-source.
Apache::Session::DBI
can issue 400+ session requests per second on light Celeron 300A running
Linux. IIS?
An alternative to Apache::Session
is Apache::ASP, which has session tracking abilities. HTML::Embperl hooks
into Apache::Session
for you.
See mod_perl and relational Databases
This package contains modules for manipulating client request data via the Apache API with Perl and C. Functionality includes:
- parsing of application/x-www-form-urlencoded data
- parsing of multipart/form-data
- parsing of HTTP Cookies
The Perl modules are simply a thin xs layer on top of libapreq, making them
a lighter and faster alternative to CGI.pm and CGI::Cookie. See the Apache::Request
and Apache::Cookie
documentation for more details and eg/perl/ for examples.
Apache::Request
and the libapreq are tied tight to the Apache API, which there is no access
to in a process running under mod_cgi.
See Apache::PerlRun - a closer look.
Have you ever served a huge HTML file (e.g. a file bloated with JavaScript code) and wandered how could you send it compressed, thus drammatically cutting down the download times. After all java applets can be compressed into a jar and benefit from a faster download times. Why cannot we do the same with a plain ASCII (HTML,JS and etc), it is a known fact that ASCII text can be compressed by a factor of 10.
Apache::GzipChain
comes to help you with this task. If a client (browser) understands gzip
encoding this module compresses the output and sends it downstream. A
client decompresses the data upon receive and renders the HTML as if it was
a plain HTML fetch.
For example to compress all html files on the fly, do:
<Files *.html> SetHandler perl-script PerlHandler Apache::OutputChain Apache::GzipChain Apache::PassFile </Files>
Remember that it will work only if the browser claims to accept compressed
input, thru Accept-Encoding
header. Apache::GzipChain
keeps a list of user-agents, thus it also looks at User-Agent
header, for known to accept compressed output browsers.
For example if you want to return compressed files which should pass in addition through Embperl module, you would write:
<Location /test> SetHandler perl-script PerlHandler Apache::OutputChain Apache::GzipChain Apache::EmbperlChain Apache::PassFile </Location>
Hint: Watch an access_log
file to see how many bytes were actually send, compare with a regular
configuration send.
(See perldoc Apache::GzipChain
).
With that module, you can configure @INC
and have modules reloaded for a given Location
, e.g. say two versions of Apache::Status
are being hacked on in the same server, this fixup handler will simply
delete $INC{ $filename }
, unshift the prefered PerlINC
path into
@INC
, and reload the file with require()
:
PerlModule Apache::PerlVINC
<Location /dougm-status> SetHandler perl-script PerlHandler Apache::Status PerlINC /home/dougm/dev/modperl/lib PerlVersionINC On PerlFixupHandler Apache::PerlVINC PerlRequire Apache/Status.pm </Location>
<Location /other-status> SetHandler perl-script PerlHandler Apache::Status PerlINC /home/other/current/modperl/lib PerlVersionINC On PerlFixupHandler Apache::PerlVINC PerlRequire Apache/Status.pm </Location>
To address possible issues of namespace clashes during reload, the handler could call $r->child_terminate() so the next server to load the different versions will have a fresh namespace. (not a good idea in a high load environment, of course.)
If it is still absent from CPAN get it at: http://perl.apache.org/~dougm/Apache-PerlVINC-0.01.tar.gz
It works just like Apache::Registry
, but does not test the x bit, only compiles the file once, and does not chdir()
into the script parent directory.
Configuration:
PerlModule Apache::RegistryBB <Location /perl> SetHandler perl-script PerlHandler ApacheRegistryBB->handler </Location>
When Apache's builtin syslog support is used, the stderr stream is
redirected to /dev/null
. This means Perl warnings, any messages from die()
, croak()
, etc., will also end up in the black hole. The HookStderr directive will hook the stderr stream to a file of your choice, the default
is shown in this example:
PerlModule Apache::LogSTDERR HookStderr logs/stderr_log
|
||
Written by Stas Bekman.
Last Modified at 08/17/1999 |
![]() |
Use of the Camel for Perl is a trademark of O'Reilly & Associates, and is used by permission. |