Apache-ASP
view release on metacpan or search on metacpan
$rv = 0; # Off always becomes 0
}
$rv;
}
*Config = *config;
sub config {
my($self, $key, $value, $default) = @_;
my $dir_config = $self->{dir_config};
if(defined $value) {
$dir_config->set($key, $value);
} elsif(defined $key) {
my $rv = $dir_config->get($key);
if(defined($rv)) {
if(lc($rv) eq 'off') {
$rv = 0; # Off always becomes 0
}
} else {
# use default value if none is returned
if(defined($default)) {
$rv = $default;
}
}
$rv;
} else {
$dir_config;
}
}
1;
__END__
=pod
=encoding ISO8859-1
=head1 NAME
Apache::ASP - Active Server Pages for Apache with mod_perl
=head1 SYNOPSIS
SetHandler perl-script
PerlModule Apache::ASP
PerlHandler Apache::ASP
PerlSetVar Global /tmp/asp
=head1 DESCRIPTION
Apache::ASP provides an Active Server Pages port to the
Apache Web Server with Perl scripting only, and enables developing
of dynamic web applications
with session management and embedded Perl code. There are also
many powerful extensions, including XML taglibs, XSLT rendering,
and new events not originally part of the ASP API!
=begin html
<table class="noescape" border="0"><tr><td>
<b>Apache::ASP's features include:</b>
<font face=verdana,helvetica,arial size=-1>
<ul>
<li> Scripting SYNTAX is Natural and Powerful
<li> Rich OBJECTS Developer API
<li> Web Application EVENTS Model
<li> Modular SSI Decomposition, Code Sharing
<li> User SESSIONS, CIFS & NFS Cluster Ready
<li> XML/XSLT Rendering & Custom Tag Technology
<li> CGI Compatibility
<li> PERLSCRIPT Compatibility
<li> Great Open Source SUPPORT
</ul>
</font>
</table>
=end html
This module works under the Apache Web Server
with the mod_perl module enabled. See http://www.apache.org and
http://perl.apache.org for further information.
This is a portable solution, similar to ActiveState's PerlScript
for NT/IIS ASP. Work has been done and will continue to make ports
to and from this implementation as smooth as possible.
For Apache::ASP downloading and installation, please read
the INSTALL section. For installation troubleshooting
check the FAQ and the SUPPORT sections.
For database access, ActiveX, scripting languages, and other
miscellaneous issues please read the FAQ section.
=head1 WEBSITE
The Apache::ASP web site is at http://www.apache-asp.org/
which you can also find in the ./site directory of
the source distribution.
=head1 INSTALL
The installation process for Apache::ASP is geared towards those
with experience with Perl, Apache, and unix systems. For those
without this experience, please understand that the learning curve
can be significant. But what you have at the end will be a web site
running on superior open source software.
If installing onto a Windows operating system, please see the section
titled Win32 Install.
=head2 Need Help
Often, installing the mod_perl part of the Apache server
can be the hardest part. If this is the case for you,
check out the FAQ and SUPPORT sections for further help,
as well as the "Modern Linux Distributions" notes in this section.
Please also see the mod_perl site at http://perl.apache.org/
which one ought to give a good read before undertaking
a mod_perl project.
Activate XSLT file based caching through CacheDB, CacheDir,
and CacheSize settings. This gives cached XSLT performance
near AxKit and greater than Cocoon. XSLT caches transformations
keyed uniquely by XML & XSLT inputs.
PerlSetVar XSLTCache 1
=item XSLTCacheSize
as of version 2.11, this config is no longer supported.
=head2 Caching
The output caching layer is a file dbm based output cache that runs
on top of the MLDBM::Sync so inherits its performance characteristics.
With CacheDB set to MLDBM::Sync::SDBM_File, the cache layer is
very fast at caching entries up to 20K in size, but for greater
cached items, you should set CacheDB to another dbm like DB_File
or GDBM_File.
In order for the cache layer
to function properly, whether for $Response->Include() output
caching, see OBJECTS, or XSLT caching, see XML/XSLT, then
Apache::ASP must be loaded in the parent httpd like so:
# httpd.conf
PerlModule Apache::ASP
-- or --
<Perl>
use Apache::ASP;
</Perl>
The cache layer automatically expires entries upon
server restart, but for this to work, a $ServerID
must be computed when the Apache::ASP module gets
loaded to store in each cached item. Without the
above done, each child httpd process will get its
own $ServerID, so caching will not work at all.
This said, output caching will not work in raw CGI mode,
just running under mod_perl.
=item CacheDB
Like StateDB, sets dbm format for caching. Since SDBM_File
only support key/values pairs of around 1K max in length,
the default for this is MLDBM::Sync::SDBM_File, which is very
fast for < 20K output sizes. For caching larger data than 20K,
DB_File or GDBM_File are probably better to use.
PerlSetVar CacheDB MLDBM::Sync::SDBM_File
=begin html
Here are some benchmarks about the CacheDB when used
with caching output from $Response->Include(\%cache)
running on a Linux 2.2.14 dual PIII-450.
The variables are output size being cached & the CacheDB used,
the default being MLDBM::Sync::SDBM_File.
<table class="noescape" border="0">
<tr><th>CacheDB</th><th>Output Cached</th><th>Operation</th><th>Ops/sec</th></tr>
<tr><td>MLDBM::Sync::SDBM_File</td> <td>3200 bytes</td> <td>read</td> <td>177</td></tr>
<tr><td>DB_File</td> <td>3200 bytes</td> <td>read</td> <td>59</td></tr>
<tr><td>MLDBM::Sync::SDBM_File</td> <td>32000 bytes</td> <td>read</td> <td>42</td></tr>
<tr><td>DB_File</td> <td>32000 bytes</td> <td>read</td> <td>53</td></tr>
<tr><td>MLDBM::Sync::SDBM_File</td> <td>3200 bytes</td> <td>write</td> <td>42</td></tr>
<tr><td>DB_File</td> <td>3200 bytes</td> <td>write</td> <td>39</td></tr>
</table>
=end html
For your own benchmarks to test the relative speeds of the
various DBMs under MLDBM::Sync, which is used by CacheDB,
you may run the ./bench/bench_sync.pl script from the
MLDBM::Sync distribution on your system.
=item CacheDir
By default, the cache directory is at StateDir/cache,
but CacheDir can be used to set the StateDir value for
caching purposes. One may want the CacheDir separate
from StateDir for example StateDir might be a centrally
network mounted file system, while CacheDir might be
a local file cache.
PerlSetVar CacheDir /tmp/asp_demo
On a system like Solaris where there is a RAM disk
mounted on the system like /tmp, I could put the CacheDir
there. On a system like Linux where files are cached
pretty well by default, this is less important.
=item CacheSize
By default, this is 10M of data per cache. When any cache,
like the XSLTCache, reaches this limit, the cache will be purged
by deleting the cached dbm files entirely. This is better for
long term running of dbms than deleting individual records,
because dbm formats will often degrade in performance with
lots of insert & deletes.
Units of M, K, and B are supported for megabytes, kilobytes, and bytes,
with the default unit being B, so the following configs all mean the
same thing;
PerlSetVar CacheSize 10M
PerlSetVar CacheSize 10240K
PerlSetVar CacheSize 10485760B
PerlSetVar CacheSize 10485760
There are 2 caches currently, the XSLTCache, and the
Response cache, the latter which is currently invoked
for caching output from includes with special syntax.
See $Response->Include() for more info on the Response cache.
=head2 Miscellaneous
=item AuthServerVariables
default 0. If you are using basic auth and would like
$Response->Include({
File => 'file.inc',
Cache => 1, # to activate cache layer
Expires => 3600, # to expire in one hour
LastModified => time() - 600, # to expire if cached before 10 minutes ago
Key => $Request->Form, # to cache based on checksum of serialized form data,
Clear => 1, # always executes include & cache output
}, @include_args);
File - include file to execute, can be file name or \$script
script data passed in as a string reference.
Cache - activate caching, will run like normal include without this
Expires - only cache for this long in seconds
LastModified - if cached before this time(), expire
Key - The cache item identity. Can be $data, \$data, \%data, \@data,
this data is serialized and combined with the filename & @include_args
to create a MD5 checksum to fetch from the cache with. If you wanted
to cache the results of a search page from form data POSTed,
then this key could be
{ Key => $Request->Form }
Clear - If set to 1, or boolean true, will always execute the include
and update the cache entry for it.
Motivation: If an include takes 1 second to execute
because of complex SQL to a database, and you can
cache the output of this include because it is not realtime data,
and the cache layer runs at .01 seconds, then you have a
100 fold savings on that part of the script. Site scalability
can be dramatically increased in this way by intelligently
caching bottlenecks in the web application.
Use Sparingly: If you have a fast include, then it may execute faster
than the cache layer runs, in which case you may actually
slow your site down by using this feature. Therefore
try to use this sparingly, and only when sure you really
need it. Apache::ASP scripts generally execute very
quickly, so most developers will not need to use this feature
at all.
=item $Response->Include(\$script_text, @args)
Added in Apache::ASP 2.11, this method allows for executing ASP scripts
that are generated dynamically by passing in a reference to the script
data instead of the file name. This works just like the normal
$Response->Include() API, except a string reference is passed in
instead of a filename. For example:
<%
my $script = "<\% print 'TEST'; %\>";
$Response->Include(\$script);
%>
This include would output TEST. Note that tokens like
<% and %> must be escaped so Apache::ASP does not try
to compile those code blocks directly when compiling
the original script. If the $script data were fetched
directly from some external resource like a database,
then these tokens would not need to be escaped at all as in:
<%
my $script = $dbh->selectrow_array(
"select script_text from scripts where script_id = ?",
undef, $script_id
);
$Response->Include(\$script);
%>
This method could also be used to render other types of dynamic scripts,
like XML docs using XMLSubs for example, though for complex
runtime XML rendering, one should use something better suited like XSLT.
See the $Server->XSLT API for more on this topic.
=item $Response->IsClientConnected()
API Extension. 1 for web client still connected, 0 if
disconnected which might happen if the user hits the stop button.
The original API for this $Response->{IsClientConnected}
is only updated after a $Response->Flush is called,
so this method may be called for a refreshed status.
Note $Response->Flush calls $Response->IsClientConnected
to update $Response->{IsClientConnected} so to use this
you are going straight to the source! But if you are doing
a loop like:
while(@data) {
$Response->End if ! $Response->{IsClientConnected};
my $row = shift @data;
%> <%= $row %> <%
$Response->Flush;
}
Then its more efficient to use the member instead of
the method since $Response->Flush() has already updated
that value for you.
=item $Response->Redirect($url)
Sends the client a command to go to a different url $url.
Script immediately ends.
=item $Response->TrapInclude($file, @args)
Calls $Response->Include() with same arguments as
passed to it, but instead traps the include output buffer
and returns it as as a perl string reference. This allows
one to postprocess the output buffer before sending
to the client.
my $string_ref = $Response->TrapInclude('file.inc');
$$string_ref =~ s/\s+/ /sg; # squash whitespace like Clean 1
print $$string_ref;
The data is returned as a referenece to save on what
might be a large string copy. You may dereference the data
with the $$string_ref notation.
=item $Response->Write($data)
=head2 $Server Object
The server object is that object that handles everything the other
objects do not. The best part of the server object for Win32 users is
the CreateObject method which allows developers to create instances of
ActiveX components, like the ADO component.
=over
=item $Server->{ScriptTimeout} = $seconds
Not implemented. May never be. Please see the
Apache Timeout configuration option, normally in httpd.conf.
=item $Server->Config($setting)
API extension. Allows a developer to read the CONFIG
settings, like Global, GlobalPackage, StateDir, etc.
Currently implemented as a wrapper around
Apache->dir_config($setting)
May also be invoked as $Server->Config(), which will
return a hash ref of all the PerlSetVar settings.
=item $Server->CreateObject($program_id)
Allows use of ActiveX objects on Win32. This routine returns
a reference to an Win32::OLE object upon success, and nothing upon
failure. It is through this mechanism that a developer can
utilize ADO. The equivalent syntax in VBScript is
Set object = Server.CreateObject(program_id)
For further information, try 'perldoc Win32::OLE' from your
favorite command line.
=item $Server->Execute($file, @args)
New method from ASP 3.0, this does the same thing as
$Response->Include($file, @args)
and internally is just a wrapper for such. Seems like we
had this important functionality before the IIS/ASP camp!
=item $Server->File()
Returns the absolute file path to current executing script.
Same as Apache->request->filename when running under mod_perl.
ASP API extension.
=item $Server->GetLastError()
Not implemented, will likely not ever be because this is dependent
on how IIS handles errors and is not relevant in Apache.
=item $Server->HTMLEncode( $string || \$string )
Returns an HTML escapes version of $string. &, ", >, <, are each
escapes with their HTML equivalents. Strings encoded in this nature
should be raw text displayed to an end user, as HTML tags become
escaped with this method.
As of version 2.23, $Server->HTMLEncode() may take a string reference
for an optmization when encoding a large buffer as an API extension.
Here is how one might use one over the other:
my $buffer = '&' x 100000;
$buffer = $Server->HTMLEncode($buffer);
print $buffer;
- or -
my $buffer = '&' x 100000;
$Server->HTMLEncode(\$buffer);
print $buffer;
Using the reference passing method in benchmarks on 100K of
data was 5% more efficient, but maybe useful for some.
It saves on copying the 100K buffer twice.
=item $Server->MapInclude($include)
API extension. Given the include $include, as an absolute or relative file name to the current
executing script, this method returns the file path that the include would
be found from the include search path. The include search path is the
current script directory, Global, and IncludesDir directories.
If the include is not found in the includes search path, then undef, or bool false,
is returned. So one may do something like this:
if($Server->MapInclude('include.inc')) {
$Response->Include('include.inc');
}
This code demonstrates how one might only try to execute an include if
it exists, which is useful since a script will error if it tries to execute an include
that does not exist.
=item $Server->MapPath($url);
Given the url $url, absolute, or relative to the current executing script,
this method returns the equivalent filename that the server would
translate the request to, regardless or whether the request would be valid.
Only a $url that is relative to the host is valid. Urls like "." and
"/" are fine arguments to MapPath, but http://localhost would not be.
To see this method call in action, check out the sample ./site/eg/server.htm
script.
=item $Server->Mail(\%mail, %smtp_args);
With the Net::SMTP and Net::Config modules installed, which are part of the
perl libnet package, you may use this API extension to send email. The
\%mail hash reference that you pass in must have values for at least
the To, From, and Subject headers, and the Body of the mail message.
The return value of this routine is 1 for success, 0 for failure. If the MailHost
SMTP server is not available, this will have a return value of 0.
You could send an email like so:
$Server->Mail({
The return value of this method call will be boolean for
success of the mail being sent.
If you would like to specially configure the Net::SMTP
object used internally, you may set %smtp_args and they
will be passed on when that object is initialized.
"perldoc Net::SMTP" for more into on this topic.
If you would like to include the output of an ASP page as the
body of the mail message, you might do something like:
my $mail_body = $Response->TrapInclude('mail_body.inc');
$Server->Mail({ %mail, Body => $$mail_body });
=item $Server->RegisterCleanup($sub)
non-portable extension
Sets a subroutine reference to be executed after the script ends,
whether normally or abnormally, the latter occurring
possibly by the user hitting the STOP button, or the web server
being killed. This subroutine must be a code reference
created like:
$Server->RegisterCleanup(sub { $main::Session->{served}++; });
or
sub served { $main::Session->{served}++; }
$Server->RegisterCleanup(\&served);
The reference to the subroutine passed in will be executed.
Though the subroutine will be executed in anonymous context,
instead of the script, all objects will still be defined
in main::*, that you would reference normally in your script.
Output written to $main::Response will have no affect at
this stage, as the request to the www client has already completed.
Check out the ./site/eg/register_cleanup.asp script for an example
of this routine in action.
=item $Server->Transfer($file, @args)
New method from ASP 3.0. Transfers control to another script.
The Response buffer will not be cleared automatically, so if you
want this to serve as a faster $Response->Redirect(), you will need to
call $Response->Clear() before calling this method.
This new script will take over current execution and
the current script will not continue to be executed
afterwards. It differs from Execute() because the
original script will not pick up where it left off.
As of Apache::ASP 2.31, this method now accepts optional
arguments like $Response->Include & $Server->Execute.
$Server->Transfer is now just a wrapper for:
$Response->Include($file, @args);
$Response->End;
=item $Server->URLEncode($string)
Returns the URL-escaped version of the string $string. +'s are substituted in
for spaces and special characters are escaped to the ascii equivalents.
Strings encoded in this manner are safe to put in urls... they are especially
useful for encoding data used in a query string as in:
$data = $Server->URLEncode("test data");
$url = "http://localhost?data=$data";
$url evaluates to http://localhost?data=test+data, and is a
valid URL for use in anchor <a> tags and redirects, etc.
=item $Server->URL($url, \%params)
Will return a URL with %params serialized into a query
string like:
$url = $Server->URL('test.asp', { test => value });
which would give you a URL of test.asp?test=value
Used in conjunction with the SessionQuery* settings, the returned
URL will also have the session id inserted into the query string,
making this a critical part of that method of implementing
cookieless sessions. For more information on that topic
please read on the setting
in the CONFIG section, and the SESSIONS section too.
=item $Server->XSLT(\$xsl_data, \$xml_data)
* NON-PORTABLE API EXTENSION *
This method takes string references for XSL and XML data
and returns the XSLT output as a string reference like:
my $xslt_data_ref = $Server->XSLT(\$xsl_data, \$xml_data)
print $$xslt_data_ref;
The XSLT parser defaults to XML::XSLT, and is configured with the
XSLTParser setting, which can also use XML::Sablotron ( support added in 2.11 ),
and XML::LibXSLT ( support added in 2.29 ).
Please see the CONFIG section for more information on the
XSLT* settings that drive this API. The XSLT setting itself
uses this API internally to do its rendering.
This API was created to allow developers easy XSLT component
rendering without having to render the entire ASP scripts
via XSLT. This will make an easy plugin architecture for
those looking to integrate XML into their existing ASP
application frameworks.
At some point, the API will likely take files as arguments,
but not as of the 2.11 release.
=back
=head1 SSI
SSI is great! One of the main features of server side includes
is to include other files in the script being requested. In Apache::ASP,
this is implemented in a couple ways, the most crucial of which
is implemented in the file include. Formatted as
under normal usage of the system, thus this work around.
This fix is important to UseStrict functionality because warnings
automatically become thrown as die() errors with UseStrict enabled,
so we have to disable normal soft warnings here.
-$Response->Include() runtime errors now throw a die() that
can be trapped. This was old functionality that has been restored.
Other compile time errors should still trigger a hard error
like script compilation, global.asa, or $Response->Include()
without an eval()
+Some better error handling with Debug 3 or -3 set, cleaned
up developer errors messages somewhat.
=item $VERSION = 2.37; $DATE="07/03/2002"
-Fixed the testing directory structures for t/long_names.t
so that tar software like Archive::Tar & Solaris tar that
have problems with long file names will still be able
to untar distribution successfully. Now t/long_names.t
generates its testing directory structures at runtime.
-Fixes for "make test" to work under perl 5.8.0 RC2,
courtesy of Manabu Higashida
+SessionQueryForce setting created for disabling use of cookies
for $Session session-id passing, rather requiring use of SessionQuery*
functionality for session-id passing via URL query string.
By default, even when SessionQuery* options are used, cookies will
be used if available with SessionQuery* functionality acting only
as a backup, so this makes it so that cookies will never be used.
+Escape ' with HTMLEncode() to '
-Trying to fix t/server_mail.t to work better for platforms
that it should skip testing on. Updated t/server.t test case.
+Remove exit() from Makefile.PL so CPAN.pm's automatic
follow prereq mechanism works correctly. Thanks to Slaven Rezic
for pointing this out.
+Added Apache::compat loading in mod_perl environment for better
mod_perl 2.0 support.
=item $VERSION = 2.35; $DATE="05/30/2002"
+Destroy better $Server & $Response objects so that my
closure references to these to not attempt to work in the future
against invalid internal data. There was enough data left in these
old objects to make debugging the my closure problem confusing, where
it looked like the ASP object state became invalid.
+Added system debug diagnostics to inspect StateManager group cleanup
(d) Documentation update about flock() work around for
Win95/Win98/WinMe systems, confirmed by Rex Arul
(d) Documentation/site build bug found by Mitsunobu Ozato,
where <% %> not being escaped correctly with $Server->HTMLEncode().
New japanese documentation project started by him
at http://sourceforge.jp/projects/apache-asp-jp/
-InitPackageGlobals() called after new Apache::ASP object created so
core system templates can be compiled even when there was a runtime
compilation error of user templates. Bug fix needed pointed out by
Eamon Daly
=item $VERSION = 2.33; $DATE="04/29/2002"
- fixed up t/server_mail.t test to skip if a sendmail server
is not available on localhost. We only want the test to run
if there is a server to test against.
+ removed cgi/asp script, just a symlink now to the ./asp-perl script
which in this way deprecates it. I had it hard linked, but the
distribution did not untar very well on win32 platform.
+ Reordered the modules in Bundle::Apache::ASP for a cleaner install.
- Fixed bug where XMLSubs where removing <?xml version ... ?> tag
when it was needed in XSLT mode.
+ $Server->Mail({ CC => '...', BCC => '...' }), now works to send
CC & BCC headers/recipients.
+ Removed $Apache::ASP::Register definition which defined the current
executing Apache::ASP object. Only one part of the application was
using it, and this has been fixed. This would have been an unsafe
use of globals for a threaded environment.
+ Decreased latency when doing Application_OnStart, used to sleep(1)
for CleanupMaster sync, but this is not necessary for Application_OnStart
scenario
+ Restructure code / core templates for MailErrorsTo funcationality.
Wrote test mail_error.t to cover this. $ENV{REMOTE_USER} will now
be displayed in the MailErrorsTo message when defined from 401 basic auth.
+ $Server->RegisterCleanup should be thread safe now, as it no longer relies
on access to @Apache::ASP::Cleanup for storing the CODE ref stack.
+ test t/inode_names.t for InodeNames and other file tests covering case
of long file names.
- Fixed long file name sub identifier bug. Added test t/long_names.t.
+ CacheDir may now be set independently of StateDir. It used to default
to StateDir if it was set.
++ Decomposition of modules like Apache::ASP::Session & Apache::ASP::Application
out of ASP.pm file. This should make the source more developer friendly.
This selective code compilation also speeds up CGI requests that do not
need to load unneeded modules like Apache::ASP::Session, by about 50%,
so where CGI mode ran at about 2.1 hits/sec before, now for
light requests that do not load $Session & $Application, requests
run at 3.4 hits/sec, this is on a dual PIII-450 linux 2.4.x
- Caching like for XSLTCache now works in CGI mode.
( run in 1.667 second using v1.01-cache-2.11-cpan-df04353d9ac )