Apache-ASP
view release on metacpan or search on metacpan
CreateObject =>
'OLE-active objects not supported for this platform, '.
'try installing Win32::OLE',
Gzip =>
'Compress::Zlib is needed to make gzip content-encoding work, '.
'If you want to use this feature, get yourself the latest '.
'Compress::Zlib from CPAN. ',
HiRes => undef,
FormFill =>
'HTML::FillInForm is needed to use the FormFill feature '.
'for auto filling forms with $Response->Form() data',
MailAlert => undef,
SendMail => "No mailing support",
StateDB =>
'cannot load StateDB '.
'must be a valid perl module with a db tied hash interface '.
'such as: SDBM_File (default), or DB_File',
StateSerializer =>
'cannot load StateSerializer '.
'must be a valid serializing perl module for use with MLDBM '.
'such as Data::Dumper (default), or Storable',
StatINC => "You need this module for StatINC, please download it from CPAN",
'Cache' => "You need this module for xml output caching",
XSLT => 'Cannot load XML::XSLT. Try installing the module.',
);
sub handler {
my($package, $r) = @_;
my $status = 200;
# allows it to be called as an object method
ref $package and $r = $package;
# default to Apache request object if not passed in, for possible DSO fix
# rarely happens, but just in case
my $filename;
unless($filename = eval { $r->filename }) {
my $rtest = $ModPerl2 ? Apache2::RequestUtil->request() : Apache->request();
if($filename = eval { $rtest->filename }) {
$r = $rtest;
} else {
return &DSOError($rtest);
}
}
# better error checking ?
$filename ||= $r->filename();
# using _ is optimized to use last stat() record
return(404) if (! -e $filename or -d _);
# alias $0 to filename, bind to glob for bug workaround
local *0 = \$filename;
# ASP object creation, a lot goes on in there!
# method call used for speed optimization, as OO calls are slow
my $self = &Apache::ASP::new('Apache::ASP', $r, $filename);
# for runtime use/require library loads from global/INCDir
# do this in the handler section to cover all the execution stages
# following object set up as possible.
local @INC = ($self->{global}, $INCDir, @INC);
# Execute if no errors
$self->{errs} || &Run($self);
# moved print of object to the end, so we'll pick up all the
# runtime config directives set while the code is running
$self->{dbg} && $self->Debug("ASP Done Processing $self", $self );
# error processing
if($self->{errs}) {
require Apache::ASP::Error;
$status = $self->ProcessErrors;
}
# XX return code of 302 hangs server on WinNT
# STATUS hook back to Apache
my $response = $self->{Response};
if($status != 500 and defined $response->{Status} and $response->{Status} != 302) {
# if still default then set to what has been set by the
# developer
$status = $response->{Status};
}
# X: we DESTROY in register_cleanup, but if we are filtering, and we
# handle a virtual request to an asp app, we need to free up the
# the locked resources now, or the session requests will collide
# a performance hack would be to share an asp object created between
# virtual requests, but don't worry about it for now since using SSI
# is not really performance oriented anyway.
#
# If we are not filtering, we let RegisterCleanup get it, since
# there will be a perceived performance increase on the client side
# since the connection is terminated before the garabage collection is run.
#
# Also need to destroy if we return a 500, as we could be serving an
# error doc next, before the cleanup phase
if($self->{filter} || ($status == 500) || ( $r->isa('Apache::ASP::CGI'))) {
$self->DESTROY();
}
if($status eq '200') {
$status = 0; # OK status code is default unless there was an internal error
}
$status;
delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
my $currdir = cwd();
$share_path = "$currdir/$share_path";
}
# not finding the ShareDir creates a hard error, because the Apache/ASP/Share
# directory will become one of the fundamental underpinings of the project
# People will need to rely on being able to load shared includes, and not have
# to discover the lack of loading Share:: at runtime, rather this is a compile
# time error.
-d $share_path || die("Apache::ASP::Share directory not found. ".
"Please make sure to install all the modules that make up the Apache::ASP installation."
);
$ShareDir = $share_path;
# once we find the $ShareDir, we can truncate the library path
# and push it onto @INC with use lib... this is to help with loading
# future Apache::ASP::* modules when the lib path it was found at is
# relative to some directory. This was needed to have the "make test"
# test suite to work which loads libraries from "blib/lib", but Apache::ASP
# will chdir() into the script directory so that can ruin this
# library lookup.
#
my $lib_path = $share_path;
$lib_path =~ s/Apache.ASP.Share.?$//s;
-d $lib_path || die("\%INC library path $lib_path not found.");
$INCDir = $lib_path;
# clear taint, for some reason, tr/// or s/^(.*)$/ did not work on perl 5.6.1
$INCDir =~ /^(.*)$/s;
$INCDir = $1;
# make sure this gets on @INC at startup, can't hurt
eval "use lib qw($INCDir);";
1;
}
sub FileId {
my($self, $file, $abs_file, $no_compile_checksum) = @_;
$file || die("no file passed to FileId()");
my $id;
# calculate compile checksum for file id
unless($self->{compile_checksum}) {
my $r = $self->{r};
my $checksum = md5_hex(join('&-+',
$VERSION,
map { &config($self, $_) || '' }
@CompileChecksumKeys
)
);
# $self->{dbg} && $self->Debug("compile checksum $checksum");
$self->{compile_checksum} = $checksum;
}
my $compile_checksum = $no_compile_checksum ? '' : $self->{compile_checksum};
my @inode_stat = ();
if($self->{inode_names}) {
@inode_stat = stat($file);
# one or the other device or file ids must be not 0
unless($inode_stat[0] || $inode_stat[1]) {
@inode_stat = ();
}
}
if(@inode_stat) {
$id = sprintf("____DEV%X_INODE%X",@inode_stat[0,1]);
$id .= 'x'.$compile_checksum;
} else {
if($abs_file) {
$file = $abs_file;
}
$file =~ s|/+|/|sg;
$file =~ s/[\Wx]/_/sg;
my $file_name_length = length($file);
if($file_name_length >= 35) {
$id = substr($file, $file_name_length - 35, 36);
# only do the hex of the original file to create a unique identifier for the long id
$id .= 'x'.&md5_hex($file.$compile_checksum);
} else {
$id = $file.'x'.$compile_checksum;
}
}
$id = '__ASP_'.$id;
}
# defaults to parsing the script's file, or data from a file handle
# in the case of filtering, but we can also pass in text to parse,
# which is useful for doing includes separately for compiling
sub Parse {
my($self, $file) = @_;
my $file_exists = 0;
my $parse_file = $file;
my $r = $self->{r};
my $data;
# get script data, from varied data sources;
$file || die("can't parse without file data");
$self->{dbg} && $self->Debug("parse file $file");
# file can be a filename, scalar ref, or scalar
if(ref $file) {
if ($file =~ /SCALAR/) {
$data = $$file;
} elsif ($file =~ /GLOB/) {
local $/ = undef;
$data = <$file>
}
} elsif((length($file) < 1024) && ($file !~ /^GLOB/) && (-e $file)) {
# filename has length < 1024, should be fine across OS's
$self->{dbg} && $self->Debug("parsing $file");
$data = ${$self->ReadFile($file)};
$file_exists = 1;
$self->{parse_file_count}++;
} else {
$data = $file; # raw script, no ref
}
# prevent recursion
unless($self->{register_includes}{$include}) {
$self->{register_includes}{$include} = 1;
local $self->{compile_error} = undef;
local $self->{compile_eval} = undef;
my $code = eval { $self->CompileInclude($include); };
my $debug = $code ? "success" : "error: $@";
$self->{dbg} && $self->Debug("register include $include with $debug");
}
'';
}
/exsgi;
}
sub CompileInclude {
my($self, $include, $package, $is_base_script) = @_;
my($include_ref, $mtime, $subid);
local $self->{use_strict} = $self->{use_strict};
if($include =~ /^Share::/) {
# Share:: components must always run under UseStrict
$self->{use_strict} = 1;
}
if ( ref $include ) {
# $self->{dbg} && $self->Debug("compiling scalar data $include for include");
$include_ref = $include;
# $include = $$include;
} else { # file here
if($is_base_script) {
# if its the base script being executed, then we already know
# it exists because of earlier file tests, and do not need to
# search for it
#
# leave $include alone
} else {
# streamlined, SearchDirs now caches per request
my $file = &SearchDirs($self, $include);
die("no include $include") unless defined $file;
$include = $file;
}
# treat as anonymous subroutine compilation like data passed in
# as a scalar ref as above if we have NoCache set
if($self->{no_cache}) {
$include = $self->ReadFile($include);
$include_ref = $include;
goto COMPILE_INCLUDE_PARSE;
}
my $id = &FileId($self, $include);
$subid = ($package || $self->{GlobalASA}{'package'})."::$id".'xINC';
my $compiled = $Apache::ASP::CompiledIncludes{$subid};
if($compiled && ! $self->{stat_scripts}) {
$self->{dbg} && $self->Debug("no stat: found cached code for include $id");
return $compiled;
}
# return cached code if include hasn't been modified recently
$mtime = (stat($include))[9];
if($compiled && ($compiled->{mtime} > $mtime)) {
# $self->Debug("found cached code for include $id");
# now check for changed includes, return if not changed
my $includes_changed = 0;
if(my $includes = $Apache::ASP::Includes{$include}) {
for my $k (keys %$includes) {
my $v = $includes->{$k} || 0;
my @stat = stat($k);
if(@stat) {
if($stat[9] >= $v) {
$self->{dbg} && $self->Debug("file $k mtime changed from $v to $stat[9]");
$includes_changed = 1;
last;
}
} else {
$self->{dbg} && $self->Debug("can't get mtime for file $k: $!");
$includes_changed = 1;
last;
}
}
}
if(! $includes_changed) {
return $compiled;
} else {
$self->{dbg} && $self->Debug("includes changed for $include, recompiling");
}
}
}
COMPILE_INCLUDE_PARSE:
my $parse_data = $self->Parse($include);
my $no_cache = $self->{no_cache};
my $data;
# use Data::Dumper qw(Dumper);
# print STDERR Dumper($include, $parse_data);
# $self->Debug($self);
if ($parse_data->{is_perl}) {
my $sub = $self->CompilePerl($parse_data->{data}, $subid, $package);
# for perl with subs in it, do not cache the code compilation
# to help prevent my closure problems for newbies, --jc 2/11/2003
unless($no_cache) {
$no_cache = $self->TestForSubs($parse_data->{data});
if($no_cache) {
$self->Debug("test for subs returned $no_cache, no_cache = $no_cache");
}
}
if ($sub) {
$data = {
mtime => time(),
code => $sub,
perl => $parse_data->{data},
file => $include_ref || $include,
};
}
} elsif($parse_data->{is_raw}) {
$data = {
mtime => time(),
code => $parse_data->{data},
perl => $parse_data->{data},
file => $include_ref || $include,
};
} else {
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
$Request->ServerVariables set like AUTH_TYPE, AUTH_USER,
AUTH_NAME, REMOTE_USER, & AUTH_PASSWD, then set this and
Apache::ASP will initialize these values from Apache->*auth*
commands. Use of these environment variables keeps applications
cross platform compatible as other servers set these too
when performing basic 401 auth.
PerlSetVar AuthServerVariables 0
=item BufferingOn
default 1, if true, buffers output through the response object.
$Response object will only send results to client browser if
a $Response->Flush() is called, or if the asp script ends. Lots of
output will need to be flushed incrementally.
If false, 0, the output is immediately written to the client,
CGI style. There will be a performance hit server side if output
is flushed automatically to the client, but is probably small.
I would leave this on, since error handling is poor, if your asp
script errors after sending only some of the output.
PerlSetVar BufferingOn 1
=item InodeNames
Default 0. Set to 1 to uses a stat() call on scripts and includes to
derive subroutine namespace based on device and inode numbers. In case of
multiple symbolic links pointing to the same script this will result
in the script being compiled only once. Use only on unix flavours
which support the stat() call that know about device and inode
numbers.
PerlSetVar InodeNames 1
=item RequestParams
Default 0, if set creates $Request->Params object with combined
contents of $Request->QueryString and $Request->Form. This
is for developer convenience simlar to CGI.pm's param() method.
PerlSetVar RequestParams 1
=item RequestBinaryRead
Default On, if set to Off will not read POST data into $Request->Form().
One potential reason for configuring this to Off might be to initialize the Apache::ASP
object in an Apache handler phase earlier than the normal PerlRequestHandler
phase, so that it does not interfere with normal reading of POST data later
in the request.
PerlSetVar RequestBinaryRead On
=item StatINC
default 0, if true, reloads perl libraries that have changed
on disk automatically for ASP scripts. If false, the www server
must be restarted for library changes to take effect.
A known bug is that any functions that are exported, e.g. confess
Carp qw(confess), will not be refreshed by StatINC. To refresh
these, you must restart the www server.
This setting should be used in development only because it is so slow.
For a production version of StatINC, see StatINCMatch.
PerlSetVar StatINC 1
=item StatINCMatch
default undef, if defined, it will be used as a regular expression
to reload modules that match as in StatINC. This is useful because
StatINC has a very high performance penalty in production, so if
you can narrow the modules that are checked for reloading each
script execution to a handful, you will only suffer a mild performance
penalty.
The StatINCMatch setting should be a regular expression like: Struct|LWP
which would match on reloading Class/Struct.pm, and all the LWP/.*
libraries.
If you define StatINCMatch, you do not need to define StatINC.
PerlSetVar StatINCMatch .*
=item StatScripts
default 1, if set to 0, changed scripts, global.asa, and includes
will not be reloaded. Coupled with Apache mod_perl startup and restart
handlers executing Apache::ASP->Loader() for your application
this allows your application to be frozen, and only reloaded on the
next server restart or stop/start.
There are a few advantages for not reloading scripts and modules
in production. First there is a slight performance improvement
by not having to stat() the script, its includes and the global.asa
every request.
From an application deployment standpoint, you
also gain the ability to deploy your application as a
snapshot taken when the server starts and restarts.
This provides you with the reassurance that during a
production server update from development sources, you
do not have to worry with sources being used for the
wrong libraries and such, while they are all being
copied over.
Finally, though you really should not do this, you can
work on a live production application, with a test server
reloading changes, but your production server does see
the changes until you restart or stop/start it. This
saves your public from syntax errors while you are just
doing a quick bug fix.
PerlSetVar StatScripts 1
=item SoftRedirect
default 0, if true, a $Response->Redirect() does not end the
script. Normally, when a Redirect() is called, the script
is ended automatically. SoftRedirect 1, is a standard
way of doing redirects, allowing for html output after the
redirect is specified.
PerlSetVar SoftRedirect 0
=item Filter
On/Off, default Off. With filtering enabled, you can take advantage of
full server side includes (SSI), implemented through Apache::SSI.
SSI is implemented through this mechanism by using Apache::Filter.
A sample configuration for full SSI with filtering is in the
./site/eg/.htaccess file, with a relevant example script ./site/eg/ssi_filter.ssi.
You may only use this option with modperl v1.16 or greater installed
and PERL_STACKED_HANDLERS enabled. Filtering may be used in
conjunction with other handlers that are also "filter aware".
If in doubt, try building your mod_perl with
perl Makefile.PL EVERYTHING=1
With filtering through Apache::SSI, you should expect near a
a 20% performance decrease.
PerlSetVar Filter Off
=item CgiHeaders
default 0. When true, script output that looks like HTTP / CGI
headers, will be added to the HTTP headers of the request.
So you could add:
Set-Cookie: test=message
<html>...
to the top of your script, and all the headers preceding a newline
will be added as if with a call to $Response->AddHeader(). This
faster & more correct, thanks to Nikolay Melekhin for pointing out this need.
(d) Added old perlmonth.com articles to ./site/articles in distribution
and linked to them from the docs RESOURCES section
(d) Updated documention for the $Application->SessionCount API
+ Scripts with named subroutines, which is warned against in the style guide,
will not be cached to help prevent my closure problems that often
hurt new developers working in mod_perl environments. The downside
is that these script will have a performance penalty having to be
recompiled each invocation, but this will kill many closure caching
bugs that are hard to detect.
- $Request->FileUpload('upload_file', 'BrowserFile') would return
a glob before that would be the file name in scalar form. However
this would be interpreted as a reference incorrectly. The fix
is to make sure this is always a scalar by stringifying
this data internally. Thanks to Richard Curtis for pointing
out this bug.
=item $VERSION = 2.51; $DATE="02/10/2003"
+ added t/session_query_parse.t test to cover use of SessionQueryParse
and $Server->URL APIs
- Fixed duplicate "&" bug associated with using $Server->URL
and SessionQueryParse together
+ Patch to allow $Server->URL() to be called multiple times on the same URL
as in $Server->URL($Server->URL($url, \%params), \%more_params)
(d) Added new testimonials & sites & created a separate testimonials page.
- SessionQueryParse will now add to & to the query strings
embedded in the HTML, instead of & for proper HTML generation.
Thanks to Peter Galbavy for pointing out and Thanos Chatziathanassiou
for suggesting the fix.
- $Response->{ContentType} set to text/html for developer error reporting,
in case this was set to something else before the error occured.
Thanks to Philip Mak for reporting.
- Couple of minor bug fixes under PerlWarn use, thanks Peter Galbavy
for reporting.
+ Added automatic load of "use Apache2" for compat with mod_perl2
request objects when Apache::ASP is loaded via "PerlModule Apache::ASP"
Thanks to Richard Curtis for reporting bug & subsequent testing.
- When GlobalPackage config changes, but global.asa has not, global.asa
will be recompiled anyway to update the GlobalPackage correctly.
Changing GlobalPackage before would cause errors if global.asa was
already compiled.
++ For ANY PerlSetVar type config, OFF/Off/off will be assumed
to have value of 0 for that setting. Before, only a couple settings
had this semantics, but they all do now for consistency.
- Fix for InodeNames config on OpenBSD, or any OS that might have
a device # of 0 for the file being stat()'d, thanks to Peter Galbavy
for bug report.
++ Total XSLT speedups, 5-10% on large XSLT, 10-15% on small XSLT
+ bypass meta data check like expires for XSLT Cache() API use
because XSLT tranformations don't expire, saves hit to cache dbm
for meta data
+ use of direct Apache::ASP::State methods like FETCH/STORE
in Cache() layer so we don't have to go through slower tied interface.
This will speed up XSLT & and include output caching mostly.
+ minor optimizations for speed & memory usage
=item $VERSION = 2.49; $DATE="11/10/2002"
-- bug introduced in 2.47 cached script compilations for executing
scripts ( not includes ) of the same name in different directories
for the same Global/GlobalPackage config for an application.
Fix was to remove optimization that caused problem, and
created test case t/same_name.t to cover bug.
=item $VERSION = 2.47; $DATE="11/06/2002"
++ Runtime speed enhancements for 15-20% improvement including:
+ INTERNAL API ReadFile() now returns scalar ref as memory optimization
+ cache InodeNames config setting in ASP object now for common lookups
+ removed CompileChecksum() INTERNAL API, since it was an unnecesary
method decomposition along a common code path
+ removed IsChanged() INTERNAL API since compiling of scripts
is now handled by CompileInclude() which does this functionality already
+ removed unnecessary decomp of IncludesChanged() INTERNAL API, which was along
critical code path
+ do not call INTERNAL SearchDirs() API when compiling base script
since we have already validated its path earlier
+ Use stat(_) type shortcut for stat() & -X calls where possible
+ Moved @INC initilization up to handler() & consolidated with $INCDir lib
+ removed useless Apache::ASP::Collection::DESTROY
+ removed useless Apache::ASP::Server::DESTROY
+ removed useless Apache::ASP::GlobalASA::DESTROY
+ removed useless Apache::ASP::Response::DESTROY
- Default path for $Response->{Cookies} was from CookiePath
config, but this was incorrect as CookiePath config is only
for $Session cookie, so now path for $Response->{Cookies}
defaults to /
- Fixed bug where global.asa events would get undefined with
StatINC and GlobalPackage set when the GlobalPackage library
changed & get reloaded.
(d) Documented long time config NoCache.
-- Fixed use with Apache::Filter, capable as both source
and destination filter. Added ./site/eg/filter.filter example
to demonstrate these abilities.
+ Use $r->err_headers_out->add Apache::Table API for cookies
now instead of $r->cgi_header_out. Added t/cookies.t test to
cover new code path as well as general $Response->Cookies API.
Also make cookies headers sorted by cookie and dictionary key
while building headers for repeatable behavior, this latter was
to facilitate testing.
- fixed $Server->Mail error_log output when failing to connect
to SMTP server.
+ added tests to cover UniquePackages & NoCache configs since this
config logic was updated
+ made deprecated warnings for use of certain $Response->Member
calls more loudly write to error_log, so I can remove the AUTOLOAD
for Response one day
- Probably fixed behavior in CgiHeaders, at least under perl 5.8.0, and
added t/cgi_headers.t to cover this config.
+ removed $Apache::ASP::CompressGzip setting ability, used to possibly
set CompressGzip in the module before, not documented anyway
+ removed $Apache::ASP::Filter setting ability to set Filter globally,
not documented anyway
+ removed old work around for setting ServerStarting to 0
at runtime, which was bad for Apache::DBI on win32 a long
time ago:
$Apache::ServerStarting and $Apache::ServerStarting = 0;
If this code is still needed in Apache::ASP->handler() let
me know.
+ check to make sure data in internal database is a HASH ref
before using it for session garbage collection. This is to
help prevent against internal database corruption in a
network share that does not support flock() file locking.
-Fix for running under perl 5.6.1 by removing parser optimization
introduced in 2.11.
-Now file upload forms, forms with ENCTYPE="multipart/form-data"
can have multiple check boxes and select items marked for
@params = $Request->Form('param_name') functionality. This
will be demonstrated via the ./site/eg/file_upload.asp example.
=item $VERSION = 2.11; $DATE="05/29/2001";
+Parser optimization from Dariusz Pietrzak
-work around for global destruction error message for perl 5.6
during install
+$Response->{IsClientConnected} now will be set
correctly with ! $r->connection->aborted after each
$Response->Flush()
+New XSLTParser config which can be set to XML::XSLT or
XML::Sablotron. XML::Sablotron renders 10 times faster,
but differently. XML::XSLT is pure perl, so has wider
platform support than XML::Sablotron. This config affects
both the XSLT config and the $Server->XSLT() method.
+New $Server->XSLT(\$xsl_data, \$xml_data) API which
allows runtime XSLT on components instead of having to process
the entire ASP output as XSLT.
-XSLT support for XML::XSL 0.32. Things broke after .24.
-XSLTCacheSize config no longer supported. Was a bad
Tie::Cache implementation. Should be file based cache
to greatly increases cache hit ratio.
++$Response->Include(), $Response->TrapInclude(),
and $Server->Execute() will all take a scalar ref
or \'asdfdsafa' type code as their first argument to execute
a raw script instead of a script file name. At this time,
compilation of such a script, will not be cached. It is
compiled/executed as an anonymous subroutine and will be freed
when it goes out of scope.
+ -p argument to cgi/asp script to set GlobalPackage
config for static site builds
-pod commenting fix where windows clients are used for
ASP script generation.
+Some nice performance enhancements, thank to submissions from
Ime Smits. Added some 1-2% per request execution speed.
+Added StateDB MLDBM::Sync::SDBM_File support for faster
$Session + $Application than DB_File, yet still overcomes
SDBM_File's 1024 bytes value limitation. Documented in
StateDB config, and added Makefile.PL entry.
+Removed deprecated MD5 use and replace with Digest::MD5 calls
+PerlSetVar InodeNames 1 config which will compile scripts hashed by
their device & inode identifiers, from a stat($file)[0,1] call.
This allows for script directories, the Global directory,
and IncludesDir directories to be symlinked to without
recompiling identical scripts. Likely only works on Unix
systems. Thanks to Ime Smits for this one.
+Streamlined code internally so that includes & scripts were
compiled by same code. This is a baby step toward fusing
include & script code compilation models, leading to being
able to compile bits of scripts on the fly as ASP subs,
and being able to garbage collect ASP code subroutines.
-removed @_ = () in script compilation which would trigger warnings
under PerlWarn being set, thanks for Carl Lipo for reporting this.
-StatINC/StatINCMatch fix for not undeffing compiled includes
and pages in the GlobalPackage namespace
-Create new HTML::FillInForm object for each FormFill
done, to avoid potential bug with multiple forms filled
by same object. Thanks to Jim Pavlick for the tip.
+Added PREREQ_PM to Makefile.PL, so CPAN installation will
pick up the necessary modules correctly, without having
to use Bundle::Apache::ASP, thanks to Michael Davis.
+ > mode for opening lock files, not >>, since its faster
+$Response->Flush() fixed, by giving $| = 1 perl hint
to $r->print() and the rest of the perl sub.
+$Response->{Cookies}{cookie_name}{Expires} = -86400 * 300;
works so negative relative time may be used to expire cookies.
+Count() + Key() Collection class API implementations
+Added editors/aasp.vim VIM syntax file for Apache::ASP,
courtesy of Jon Topper.
++Better line numbering with #line perl pragma. Especially
helps with inline includes. Lots of work here, & integrated
with Debug 2 runtime pretty print debugging.
+$Response->{Debug} member toggles on/off whether
$Response->Debug() is active, overriding the Debug setting
for this purpose. Documented.
-When Filter is on, Content-Length won't be set and compression
won't be used. These things would not work with a filtering
handler after Apache::ASP
=item $VERSION = 2.09; $DATE="01/30/2001";
+Examples in ./site/eg are now UseStrict friendly.
Also fixed up ./site/eg/ssi_filter.ssi example.
+Auto purge of old stale session group directories, increasing
session manager performance when using Sessions when migrating
to Apache::ASP 2.09+ from older versions.
+SessionQueryParse now works for all $Response->{ContentType}
created with SDBM_File for the StateDB (default),
it will keep this StateDB setting until it ends.
+StateSerializer config setting. Default Data::Dumper,
can also be set to Storable. Controls how data is
serialized before writing to $Application & $Session.
+Beefed up the make test suite.
+Improved the locking, streamlining a bit of the
$Application / $Session setup process. Bench is up to
22 from 21 hits / sec on dev NT box.
+Cut more fat for faster startup, now on my dev box
I get 44 hits per sec Apache::ASP vs. 48 Embperl
vs. 52 CGI via Apache::Registry for the HelloWorld Scripts.
-Improved linking for the online site documentation,
where a few links before were bad.
=item $VERSION = 0.17; $DATE="11/15/99";
++20%+ faster startup script execution, as measured by the
HelloWorld bench. I cut a lot of the fat out of
the code, and is now at least 20% faster on startup
both with and without state.
On my dev (NT, apache 1.3.6+mod_perl) machine, I now get:
42 hits per sec on Apache::ASP HelloWorld bench
46 hits per sec on Embperl (1.2b10) and
51 hits per sec for CGI Apache::Registry scripts
Before Apache::ASP was clocking some 31 hits per sec.
Apache::ASP also went from 75 to 102 hits per second
on Solaris.
+PerlTaintCheck On friendly. This is mod_perl's way
of providing -T taint checking. When Apache::ASP
is used with state objects like $Session or $Application,
MLDBM must also be made taint friendly with:
$MLDBM::RemoveTaint = 1;
which could be put in the global.asa. Documented.
+Added $Response->ErrorDocument($error_code, $uri_or_string)
API extension which allows for setting of Apache's error
document at runtime. This is really just a wrapper
for Apache->custom_response() renamed so it syncs with
the Apache ErrorDocument config setting. Updated
documentation, and added error_document.htm example.
=OrderCollections setting was added, but then REMOVED
because it was not going to be used. It bound
$Request->* collections/hashes to Tie::IxHash, so that data
in those collections would be read in the order the
browser sent it, when eaching through or with keys.
-global.asa will be reloaded when changed. This broke
when I optimized the modification times with (stat($file))[9]
rather than "use File::stat; stat($file)->mtime"
-Make Apache::ASP->Loader() PerlRestartHandler safe,
had some unstrict code that was doing the wrong thing.
-IncludesDir config now works with DynamicIncludes.
+DebugBufferLength feature added, giving control to
how much buffered output gets shown when debugging errors.
++Tuning of $Response->Write(), which processes all
static html internally, to be almost 50% faster for
its typical use, when BufferingOn is enabled, and
CgiHeaders are disabled, both being defaults.
This can show significant speed improvements for tight
loops that render ASP output.
+Auto linking of ./site/eg/ text to example scripts
at web site.
+$Application->GetSession($session_id) API extension, useful
for managing active user sessions when storing session ids
in $Application. Documented.
-disable use of flock() on Win95/98 where it is unimplemented
-@array context of $Request->Form('name') returns
undef when value for 'name' is undefined. Put extra
logic in there to make sure this happens.
=item $VERSION = 0.16; $DATE="09/22/99";
-$Response->{Buffer} and PerlSetVar BufferingOn
configs now work when set to 0, to unbuffer output,
and send it out to the web client as the script generates it.
Buffering is enabled by default, as it is faster, and
allows a script to error cleanly in the middle of execution.
+more bullet proof loading of Apache::Symbol, changed the
way Apache::ASP loads modules in general. It used to
check for the module to load every time, if it hadn't loaded
successfully before, but now it just tries once per httpd,
so the web server will have to be restarted to see new installed
modules. This is just for modules that Apache::ASP relies on.
Old modules that are changed or updated with an installation
are still reloaded with the StatINC settings if so configured.
+ASP web site wraps <font face="courier new"> around <pre>
tags now to override the other font used for the text
areas. The spacing was all weird in Netscape before
for <pre> sections.
-Fixed Content-Length calculation when using the Clean
option, so that the length is calculated after the HTML
is clean, not before. This would cause a browser to
hang sometimes.
+Added IncludesDir config option that if set will also be
( run in 0.992 second using v1.01-cache-2.11-cpan-39bf76dae61 )