Apache-ASP

 view release on metacpan or  search on metacpan

ASP.pm  view on Meta::CPAN

   
   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;

ASP.pm  view on Meta::CPAN

	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
    }

ASP.pm  view on Meta::CPAN

       # 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 {

ASP.pm  view on Meta::CPAN

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

ASP.pm  view on Meta::CPAN

   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 &amp; 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.

ASP.pm  view on Meta::CPAN

 -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}

ASP.pm  view on Meta::CPAN

  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 )