view release on metacpan or search on metacpan
use strict;
no strict qw(refs);
use vars qw($VERSION
%NetConfig %LoadedModules %LoadModuleErrors
%Codes %includes %Includes %CompiledIncludes
@Objects %Register %XSLT
$ServerID $ServerPID $SrandPid
$CompileErrorSize $CacheSize @CompileChecksumKeys
%ScriptLanguages $ShareDir $INCDir $AbsoluteFileMatch
$QuickStartTime
$SessionCookieName
$LoadModPerl
$ModPerl2
);
# other common modules load now, these are optional though, so we do not error upon failure
# just do this once perl mod_perl parent startup
unless($LoadModPerl++) {
my @load_modules = qw( Config lib Time::HiRes );
if($ENV{MOD_PERL}) {
# Only pre-load these if in a mod_perl environment for sharing memory post fork.
# $Apache::Server::AddPerlVersion = 1;
#use integer; # don't use screws up important numeric logic
@Objects = ('Application', 'Session', 'Response', 'Server', 'Request');
map { eval "sub $_ { shift->{$_} }" } @Objects;
# use regexp directly, not sub for speed
$AbsoluteFileMatch = '^(/|[a-zA-Z]:)';
$CacheSize = 1024*1024*10;
$SessionCookieName = 'session-id';
# ServerID creates a unique identifier for the server
srand();
$ServerID = substr(md5_hex($$.rand().time().(-M('..')||'').(-M('/')||'')), 0, 16);
$ServerPID = $$;
# DEFAULT VALUES
$Apache::ASP::CompileErrorSize = 500;
@CompileChecksumKeys = qw ( Global DynamicIncludes UseStrict XMLSubsMatch XMLSubsPerlArgs XMLSubsStrict GlobalPackage UniquePackages IncludesDir InodeNames PodComments );
This configuration setting may be changed in production
as the state database's serializer type is stored
in the internal state manager which will always use
Data::Dumper & SDBM_File to store data.
PerlSetVar StateSerializer Data::Dumper
=head2 Sessions
=item CookiePath
URL root that client responds to by sending the session cookie.
If your asp application falls under the server url "/asp",
then you would set this variable to /asp. This then allows
you to run different applications on the same server, with
different user sessions for each application.
PerlSetVar CookiePath /
=item CookieDomain
Default 0, this NON-PORTABLE configuration will allow sessions to span
multiple web sites that match the same domain root. This is useful if
your web sites are hosted on the same machine and can share the same
StateDir configuration, and you want to shared the $Session data
across web sites. Whatever this is set to, that will add a
; domain=$CookieDomain
part to the Set-Cookie: header set for the session-id cookie.
PerlSetVar CookieDomain .your.global.domain
=item SessionTimeout
Default 20 minutes, when a user's session has been inactive for this
period of time, the Session_OnEnd event is run, if defined, for
that session, and the contents of that session are destroyed.
PerlSetVar SessionTimeout 20
=item SecureSession
=item SessionCount
default 0, if true enables the $Application->SessionCount API
which returns how many sessions are currently active in
the application. This config was created
because there is a performance hit associated with this
count tracking, so it is disabled by default.
PerlSetVar SessionCount 1
=head2 Cookieless Sessions
=item SessionQueryParse
default 0, if true, will automatically parse the $Session
session id into the query string of each local URL found in the
$Response buffer. For this setting to work therefore,
buffering must be enabled. This parsing will only occur
when a session cookie has not been sent by a browser, so the
first script of a session enabled site, and scripts viewed by
web browsers that have cookies disabled will trigger this behavior.
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
functionality is here for compatibility with raw cgi scripts,
and those used to this kind of coding.
When set to 0, CgiHeaders style headers will not be parsed from the
script response.
in ./site/eg/binary_write.htm
Please note that if you are on Win32, you will need to
call binmode on a file handle before reading, if
its data is binary.
=item $Response->Clear()
Erases buffered ASP output.
=item $Response->Cookies($name, [$key,] $value)
Sets the key or attribute of cookie with name $name to the value $value.
If $key is not defined, the Value of the cookie is set.
ASP CookiePath is assumed to be / in these examples.
$Response->Cookies('name', 'value');
--> Set-Cookie: name=value; path=/
$Response->Cookies("Test", "data1", "test value");
$Response->Cookies("Test", "data2", "more test");
$Response->Cookies(
"Test", "Expires",
&HTTP::Date::time2str(time+86400)
);
$Response->Cookies("Test", "Secure", 1);
$Response->Cookies("Test", "Path", "/");
$Response->Cookies("Test", "Domain", "host.com");
--> Set-Cookie:Test=data1=test%20value&data2=more%20test; \
expires=Fri, 23 Apr 1999 07:19:52 GMT; \
path=/; domain=host.com; secure
The latter use of $key in the cookies not only sets cookie attributes
such as Expires, but also treats the cookie as a hash of key value pairs
which can later be accesses by
$Request->Cookies('Test', 'data1');
$Request->Cookies('Test', 'data2');
Because this is perl, you can (NOT PORTABLE) reference the cookies
directly through hash notation. The same 5 commands above could be compressed to:
$Response->{Cookies}{Test} =
{
Secure => 1,
Value =>
{
data1 => 'test value',
data2 => 'more test'
},
Expires => 86400, # not portable, see above
Domain => 'host.com',
Path => '/'
};
and the first command would be:
# you don't need to use hash notation when you are only setting
# a simple value
$Response->{Cookies}{'Test Name'} = 'Test Value';
I prefer the hash notation for cookies, as this looks nice, and is
quite perlish. It is here to stay. The Cookie() routine is
very complex and does its best to allow access to the
underlying hash structure of the data. This is the best emulation
I could write trying to match the Collections functionality of
cookies in IIS ASP.
For more information on Cookies, please go to the source at
http://home.netscape.com/newsref/std/cookie_spec.html
=item $Response->Debug(@args)
API Extension. If the Debug config option is set greater than 0,
this routine will write @args out to server error log. refs in @args
will be expanded one level deep, so data in simple data structures
like one-level hash refs and array refs will be displayed. CODE
refs like
Note that BinaryRead will not return any data for file uploads.
Please see the $Request->FileUpload() interface for access
to this data. $Request->Form() data will also be available
as normal.
=item $Request->ClientCertificate()
Not implemented.
=item $Request->Cookies($name [,$key])
Returns the value of the Cookie with name $name. If a $key is
specified, then a lookup will be done on the cookie as if it were
a query string. So, a cookie set by:
Set-Cookie: test=data1=1&data2=2
would have a value of 2 returned by $Request->Cookies('test','data2').
If no name is specified, a hash will be returned of cookie names
as keys and cookie values as values. If the cookie value is a query string,
it will automatically be parsed, and the value will be a hash reference to
these values.
When in doubt, try it out. Remember that unless you set the Expires
attribute of a cookie with $Response->Cookies('cookie', 'Expires', $xyz),
the cookies that you set will only last until you close your browser,
so you may find your self opening & closing your browser a lot when
debugging cookies.
For more information on cookies in ASP, please read $Response->Cookies()
=item $Request->FileUpload($form_field, $key)
API extension. The FileUpload interface to file upload data is
stabilized. The internal representation of the file uploads
is a hash of hashes, one hash per file upload found in
the $Request->Form() collection. This collection of collections
may be queried through the normal interface like so:
$Request->FileUpload('upload_file', 'ContentType');
IMPORTANT (FAQ): Make sure that the web server has write access to
that directory. Usually a
chmod -R 0777 eg
will do the trick :)
=head1 SESSIONS
Cookies are used by default for user $Session support ( see OBJECTS ).
In order to track a web user and associate server side data
with that client, the web server sets, and the web client returns
a 32 byte session id identifier cookie. This implementation
is very secure and may be used in secure HTTPS transactions,
and made stronger with SecureSession, HTTPOnlySession and
ParanoidSession settings (see CONFIG ).
However good cookies are for this kind of persistent
state management between HTTP requests, they have long
been under fire for security risks associated with
JavaScript security exploits and privacy abuse by
large data tracking companies.
Because of these reasons, web users will sometimes turn off
their cookies, rendering normal ASP session implementations
powerless, resulting in a new $Session generated every request.
This is not good for ASP style sessions.
=head2 Cookieless Sessions
*** See WARNING Below ***
So we now have more ways to track sessions with the
SessionQuery* CONFIG settings, that allow a web developer
to embed the session id in URL query strings when use
of cookies is denied. The implementations work such that
if a user has cookies turned on, then cookies will be
used, but for those users with cookies turned off,
the session ids will be parsed into document URLs.
Please see the CONFIG section for more info.
The following objects in Apache::ASP respond as Collections:
$Application
$Session
$Request->FileUpload *
$Request->FileUpload('upload_file') *
$Request->Form
$Request->QueryString
$Request->Cookies
$Response->Cookies
$Response->Cookies('some_cookie')
* FileUpload API Extensions
And as such may be used with the following syntax, as compared
with the Apache::ASP native calls. Please note the native Apache::ASP
interface is compatible with the deprecated PerlScript interface.
C = PerlScript Compatibility N = Native Apache::ASP
## Collection->Contents($name)
[N] $Application->{XYZ} = "Fred"
## Collection->GetProperty($property, $name)
[C] $Application->Contents->GetProperty('Item', 'XYZ')
[N] $Application->{XYZ}
## Collection->Item($name)
[C] print $Request->QueryString->Item('message'), "<br>\n\n";
[N] print $Request->{QueryString}{'message'}, "<br>\n\n";
## Working with Cookies
[C] $Response->SetProperty('Cookies', 'Testing', 'Extra');
[C] $Response->SetProperty('Cookies', 'Testing', {'Path' => '/'});
[C] print $Request->Cookies(Testing) . "<br>\n";
[N] $Response->{Cookies}{Testing} = {Value => Extra, Path => '/'};
[N] print $Request->{Cookies}{Testing} . "<br>\n";
Several incompatibilities exist between PerlScript and Apache::ASP:
> Collection->{Count} property has not been implemented.
> VBScript dates may not be used for Expires property of cookies.
> Win32::OLE::in may not be used. Use keys() to iterate over.
> The ->{Item} property does not work, use the ->Item() method.
=head1 STYLE GUIDE
http://www.apache-asp.org/articles/perlmonth3_tune.html
Embedded Perl ( part of a series on Perl )
http://www.wdvl.com/Authoring/Languages/Perl/PerlfortheWeb/index15.html
=head2 Books
mod_perl "Eagle" Book
http://www.modperl.com
mod_perl Developer's Cookbook
http://www.modperlcookbook.org
Programming the Perl DBI
http://www.oreilly.com/catalog/perldbi/
=head2 Reference Cards
Apache & mod_perl Reference Cards
http://www.refcards.com/
++ mod_perl 2 optmizations, there was a large code impact on this,
as much code was restructured to reduce the differences between
mod_perl 1 and mod_perl 2, most importantly, Apache::compat is
no longer used
+ preloaded CGI for file uploads in the mod_perl environment
- When XSLT config is set, $Response->Redirect() should work now
Thanks to Marcus Zoller for pointing problem out
+ Added CookieDomain setting, documented, and added test to cover
it in t/cookies.t . Setting suggested by Uwe Riehm, who nicely
submitted some code for this.
=item $VERSION = 2.53; $DATE="04/10/2003"
+ XMLSubs tags with "-" in them will have "-" replaced with "_" or underscore, so a
tag like <my:render-table /> will be translated to &my::render_table() ... tags with
- in them are common in extended XML syntaxes, but perl subs cannot have - in them only.
+ Clean setting now works on output when $Response->{ContentType} begins with text/html;
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
+$Server->Config() call will return a hash ref
to all the config setting for that request, like
Apache->dir_config would.
-StatINC setting with Apache::ASP->Loader() works again.
This makes StatINC & StatINCMatch settings viable
for production & development use when the system has
very many modules.
-Cookieless session support with configs like SessionQueryParse
and SessionQuery now work for URLs with frags in them
like http://localhost?arg=value#frag
+@rv = $Response->Include() now works where there are
multiple return values from an include like:
<% return(1,2); %>
=item $VERSION = 2.21; $DATE="8/5/2001";
+Documented RequestParams config in CONFIG misc section.
+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.
separate package. As of v.10, scripts are compiled by default
into the same package, so that scripts, dynamic includes & global.asa
can share globals. This BROKE scripts in the same ASP Application
that defined the same sub routines, as their subs would redefine
each other.
UniquePackages has scripts compiled into separate perl packages,
so they may define subs with the same name, w/o fear of overlap.
Under this settings, scripts will not be able to share globals.
-Secure field for cookies in $Response->Cookies() must be TRUE to
force cookie to be secure. Before, it just had to be defined,
which gave wrong behavior for Secure => 0.
+$Response->{IsClientConnected} set to one by default. Will
work out a real value when I upgrade to apache 1.3.6. This
value has no meaning before, as apache aborts the perl code
when a client drops its connection in earlier versions.
+better compile time debugging of dynamic includes, with
Debug 2 setting
asp -b -o out *.asp
Without an output directory, script output is written to STDOUT
=item $VERSION = 0.09; $DATE="04/22/1999";
+Updated Makefile.PL optional modules output for CGI & DB_File
+Improved docs on $Response->Cookies() and $Request->Cookies()
+Added PERFORMANCE doc to main README, and added sub section
on precompiling scripts with Apache::ASP->Loader()
+Naming of CompileIncludes switched over to DynamicIncludes
for greater clarity.
+Dynamic includes can now reference ASP objects like $Session
w/o the $main::* syntax. These subs are no longer anonymous
subs, and are now compiled into the namespace of the global.asa package.
- <% @array... %> no longer dropped from code.
+perl =pod comments are stripped from script before compiling, and associated
PodComments configuration options.
+Command line cgi/asp script takes various options, and allows execution
of multiple asp scripts at one time. This script should be used for
command line debugging. This is also the beginning of building
a static site from asp scripts with the -b option, suppressing headers.
+$Response->AddHeader('Set-Cookie') works for multiple cookies.
-$Response->Cookies('foo', '0') works, was dropping 0 because of boolean test
-Fixed up some config doc errors.
=item $VERSION = 0.07; $DATE="01/20/1999";
-removed SIG{__WARN__} handler, it was a bad idea.
-fixes file locking on QNX, work around poor flock porting
: For a session, scripts execute one at a time
: NOT recommended use, please see note.
-MLDBM can be used for other things without messing up internal use
: before if it was used with different DB's and serializers,
internal state could be lost.
--State file locking. Corruption worries, and loss of data no more.
+CGI header support, developer can use CGI.pm for *output*, or just print()
: print "Set-Cookie: test=cookie\n", and things will just work
: use CGI.pm for output
: utilizes $r->send_cgi_header(), thanks Doug!
+Improved Cookie implementation, more flexible and complete
- Domain cookie key now works
: Expire times now taken from time(), and relative time in sec
: Request->Cookies() reading more flexible, with wantarray()
on hash cookie values, %hash = $Request->Cookie('test');
-make test module naming correction, was t.pm, now T.pm for Unix
+POD / README cleanup, formatting and HTML friendly.
=item $VERSION = 0.03; $DATE="09/14/1998";
+Installation 'make test' now works
+ActiveX objects on Win32 implemented with $Server->CreateObject()
+Cookies implemented: $Response->Cookies() & $Request->Cookies()
-Fixed $Response object API, converting some methods to object members.
Deprecated methods, but backwards compatible.
+Improved error messaging, debug output
+$, influences $Response->Write(@strings) behavior
+perl print() works, sending output to $Response object
DB_File since it does not have the default 1024 byte limit that
SDBM_File has on key/value lengths.
This configuration setting may be changed in production as the state
database's serializer type is stored in the internal state manager which
will always use Data::Dumper & SDBM_File to store data.
PerlSetVar StateSerializer Data::Dumper
Sessions
CookiePath
URL root that client responds to by sending the session cookie. If your
asp application falls under the server url "/asp", then you would set
this variable to /asp. This then allows you to run different
applications on the same server, with different user sessions for each
application.
PerlSetVar CookiePath /
CookieDomain
Default 0, this NON-PORTABLE configuration will allow sessions to span
multiple web sites that match the same domain root. This is useful if
your web sites are hosted on the same machine and can share the same
StateDir configuration, and you want to shared the $Session data across
web sites. Whatever this is set to, that will add a
; domain=$CookieDomain
part to the Set-Cookie: header set for the session-id cookie.
PerlSetVar CookieDomain .your.global.domain
SessionTimeout
Default 20 minutes, when a user's session has been inactive for this
period of time, the Session_OnEnd event is run, if defined, for that
session, and the contents of that session are destroyed.
PerlSetVar SessionTimeout 20
SecureSession
default 0. Sets the secure tag for the session cookie, so that the
PerlSetVar SessionSerialize 0
SessionCount
default 0, if true enables the $Application->SessionCount API which
returns how many sessions are currently active in the application. This
config was created because there is a performance hit associated with
this count tracking, so it is disabled by default.
PerlSetVar SessionCount 1
Cookieless Sessions
SessionQueryParse
default 0, if true, will automatically parse the $Session session id
into the query string of each local URL found in the $Response buffer.
For this setting to work therefore, buffering must be enabled. This
parsing will only occur when a session cookie has not been sent by a
browser, so the first script of a session enabled site, and scripts
viewed by web browsers that have cookies disabled will trigger this
behavior.
Although this runtime parsing method is computationally expensive, this
perl Makefile.PL EVERYTHING=1
With filtering through Apache::SSI, you should expect near a a 20%
performance decrease.
PerlSetVar Filter Off
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
functionality is here for compatibility with raw cgi scripts,
and those used to this kind of coding.
When set to 0, CgiHeaders style headers will not be parsed from the
script response.
For an example of BinaryWrite, see the binary_write.htm example in
./site/eg/binary_write.htm
Please note that if you are on Win32, you will need to call binmode on a
file handle before reading, if its data is binary.
$Response->Clear()
Erases buffered ASP output.
$Response->Cookies($name, [$key,] $value)
Sets the key or attribute of cookie with name $name to the value $value.
If $key is not defined, the Value of the cookie is set. ASP CookiePath
is assumed to be / in these examples.
$Response->Cookies('name', 'value');
--> Set-Cookie: name=value; path=/
$Response->Cookies("Test", "data1", "test value");
$Response->Cookies("Test", "data2", "more test");
$Response->Cookies(
"Test", "Expires",
&HTTP::Date::time2str(time+86400)
);
$Response->Cookies("Test", "Secure", 1);
$Response->Cookies("Test", "Path", "/");
$Response->Cookies("Test", "Domain", "host.com");
--> Set-Cookie:Test=data1=test%20value&data2=more%20test; \
expires=Fri, 23 Apr 1999 07:19:52 GMT; \
path=/; domain=host.com; secure
The latter use of $key in the cookies not only sets cookie attributes
such as Expires, but also treats the cookie as a hash of key value pairs
which can later be accesses by
$Request->Cookies('Test', 'data1');
$Request->Cookies('Test', 'data2');
Because this is perl, you can (NOT PORTABLE) reference the cookies
directly through hash notation. The same 5 commands above could be
compressed to:
$Response->{Cookies}{Test} =
{
Secure => 1,
Value =>
{
data1 => 'test value',
data2 => 'more test'
},
Expires => 86400, # not portable, see above
Domain => 'host.com',
Path => '/'
};
and the first command would be:
# you don't need to use hash notation when you are only setting
# a simple value
$Response->{Cookies}{'Test Name'} = 'Test Value';
I prefer the hash notation for cookies, as this looks nice, and is quite
perlish. It is here to stay. The Cookie() routine is very complex and
does its best to allow access to the underlying hash structure of the
data. This is the best emulation I could write trying to match the
Collections functionality of cookies in IIS ASP.
For more information on Cookies, please go to the source at
http://home.netscape.com/newsref/std/cookie_spec.html
$Response->Debug(@args)
API Extension. If the Debug config option is set greater than 0, this
routine will write @args out to server error log. refs in @args will be
expanded one level deep, so data in simple data structures like
one-level hash refs and array refs will be displayed. CODE refs like
$Response->Debug(sub { "some value" });
return all of the form data. This data is the raw data sent by the
client, without any parsing done on it by Apache::ASP.
Note that BinaryRead will not return any data for file uploads. Please
see the $Request->FileUpload() interface for access to this data.
$Request->Form() data will also be available as normal.
$Request->ClientCertificate()
Not implemented.
$Request->Cookies($name [,$key])
Returns the value of the Cookie with name $name. If a $key is specified,
then a lookup will be done on the cookie as if it were a query string.
So, a cookie set by:
Set-Cookie: test=data1=1&data2=2
would have a value of 2 returned by $Request->Cookies('test','data2').
If no name is specified, a hash will be returned of cookie names as keys
and cookie values as values. If the cookie value is a query string, it
will automatically be parsed, and the value will be a hash reference to
these values.
When in doubt, try it out. Remember that unless you set the Expires
attribute of a cookie with $Response->Cookies('cookie', 'Expires',
$xyz), the cookies that you set will only last until you close your
browser, so you may find your self opening & closing your browser a lot
when debugging cookies.
For more information on cookies in ASP, please read $Response->Cookies()
$Request->FileUpload($form_field, $key)
API extension. The FileUpload interface to file upload data is
stabilized. The internal representation of the file uploads is a hash of
hashes, one hash per file upload found in the $Request->Form()
collection. This collection of collections may be queried through the
normal interface like so:
$Request->FileUpload('upload_file', 'ContentType');
$Request->FileUpload('upload_file', 'FileHandle');
./site/eg installation directory do its work.
IMPORTANT (FAQ): Make sure that the web server has write access to that
directory. Usually a
chmod -R 0777 eg
will do the trick :)
SESSIONS
Cookies are used by default for user $Session support ( see OBJECTS ). In
order to track a web user and associate server side data with that client,
the web server sets, and the web client returns a 32 byte session id
identifier cookie. This implementation is very secure and may be used in
secure HTTPS transactions, and made stronger with SecureSession,
HTTPOnlySession and ParanoidSession settings (see CONFIG ).
However good cookies are for this kind of persistent state management
between HTTP requests, they have long been under fire for security risks
associated with JavaScript security exploits and privacy abuse by large data
tracking companies.
Because of these reasons, web users will sometimes turn off their cookies,
rendering normal ASP session implementations powerless, resulting in a new
$Session generated every request. This is not good for ASP style sessions.
Cookieless Sessions
*** See WARNING Below ***
So we now have more ways to track sessions with the SessionQuery* CONFIG
settings, that allow a web developer to embed the session id in URL query
strings when use of cookies is denied. The implementations work such that if
a user has cookies turned on, then cookies will be used, but for those users
with cookies turned off, the session ids will be parsed into document URLs.
The first and easiest method that a web developer may use to implement
cookieless sessions are with SessionQueryParse* directives which enable
CONFIG section for more info.
The following objects in Apache::ASP respond as Collections:
$Application
$Session
$Request->FileUpload *
$Request->FileUpload('upload_file') *
$Request->Form
$Request->QueryString
$Request->Cookies
$Response->Cookies
$Response->Cookies('some_cookie')
* FileUpload API Extensions
And as such may be used with the following syntax, as compared with the
Apache::ASP native calls. Please note the native Apache::ASP interface is
compatible with the deprecated PerlScript interface.
C = PerlScript Compatibility N = Native Apache::ASP
## Collection->Contents($name)
[N] $Application->{XYZ} = "Fred"
## Collection->GetProperty($property, $name)
[C] $Application->Contents->GetProperty('Item', 'XYZ')
[N] $Application->{XYZ}
## Collection->Item($name)
[C] print $Request->QueryString->Item('message'), "<br>\n\n";
[N] print $Request->{QueryString}{'message'}, "<br>\n\n";
## Working with Cookies
[C] $Response->SetProperty('Cookies', 'Testing', 'Extra');
[C] $Response->SetProperty('Cookies', 'Testing', {'Path' => '/'});
[C] print $Request->Cookies(Testing) . "<br>\n";
[N] $Response->{Cookies}{Testing} = {Value => Extra, Path => '/'};
[N] print $Request->{Cookies}{Testing} . "<br>\n";
Several incompatibilities exist between PerlScript and Apache::ASP:
> Collection->{Count} property has not been implemented.
> VBScript dates may not be used for Expires property of cookies.
> Win32::OLE::in may not be used. Use keys() to iterate over.
> The ->{Item} property does not work, use the ->Item() method.
STYLE GUIDE
Here are some general style guidelines. Treat these as tips for best
Apache::ASP Site Tuning ( #3 in 3 part series )
http://www.apache-asp.org/articles/perlmonth3_tune.html
Embedded Perl ( part of a series on Perl )
http://www.wdvl.com/Authoring/Languages/Perl/PerlfortheWeb/index15.html
Books
mod_perl "Eagle" Book
http://www.modperl.com
mod_perl Developer's Cookbook
http://www.modperlcookbook.org
Programming the Perl DBI
http://www.oreilly.com/catalog/perldbi/
Reference Cards
Apache & mod_perl Reference Cards
http://www.refcards.com/
Web Sites
++ mod_perl 2 optmizations, there was a large code impact on this,
as much code was restructured to reduce the differences between
mod_perl 1 and mod_perl 2, most importantly, Apache::compat is
no longer used
+ preloaded CGI for file uploads in the mod_perl environment
- When XSLT config is set, $Response->Redirect() should work now
Thanks to Marcus Zoller for pointing problem out
+ Added CookieDomain setting, documented, and added test to cover
it in t/cookies.t . Setting suggested by Uwe Riehm, who nicely
submitted some code for this.
$VERSION = 2.53; $DATE="04/10/2003"
+ XMLSubs tags with "-" in them will have "-" replaced with "_" or underscore, so a
tag like <my:render-table /> will be translated to &my::render_table() ... tags with
- in them are common in extended XML syntaxes, but perl subs cannot have - in them only.
+ Clean setting now works on output when $Response->{ContentType} begins with text/html;
like "text/html; charset=iso-8859-2" ... before Clean would only work on output marked
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
+$Server->Config() call will return a hash ref
to all the config setting for that request, like
Apache->dir_config would.
-StatINC setting with Apache::ASP->Loader() works again.
This makes StatINC & StatINCMatch settings viable
for production & development use when the system has
very many modules.
-Cookieless session support with configs like SessionQueryParse
and SessionQuery now work for URLs with frags in them
like http://localhost?arg=value#frag
+@rv = $Response->Include() now works where there are
multiple return values from an include like:
<% return(1,2); %>
$VERSION = 2.21; $DATE="8/5/2001";
+Documented RequestParams config in CONFIG misc section.
+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.
separate package. As of v.10, scripts are compiled by default
into the same package, so that scripts, dynamic includes & global.asa
can share globals. This BROKE scripts in the same ASP Application
that defined the same sub routines, as their subs would redefine
each other.
UniquePackages has scripts compiled into separate perl packages,
so they may define subs with the same name, w/o fear of overlap.
Under this settings, scripts will not be able to share globals.
-Secure field for cookies in $Response->Cookies() must be TRUE to
force cookie to be secure. Before, it just had to be defined,
which gave wrong behavior for Secure => 0.
+$Response->{IsClientConnected} set to one by default. Will
work out a real value when I upgrade to apache 1.3.6. This
value has no meaning before, as apache aborts the perl code
when a client drops its connection in earlier versions.
+better compile time debugging of dynamic includes, with
Debug 2 setting
directory. Useful for building static html sites, based on
asp scripts. An example use would be:
asp -b -o out *.asp
Without an output directory, script output is written to STDOUT
$VERSION = 0.09; $DATE="04/22/1999";
+Updated Makefile.PL optional modules output for CGI & DB_File
+Improved docs on $Response->Cookies() and $Request->Cookies()
+Added PERFORMANCE doc to main README, and added sub section
on precompiling scripts with Apache::ASP->Loader()
+Naming of CompileIncludes switched over to DynamicIncludes
for greater clarity.
+Dynamic includes can now reference ASP objects like $Session
w/o the $main::* syntax. These subs are no longer anonymous
subs, and are now compiled into the namespace of the global.asa package.
- <% @array... %> no longer dropped from code.
+perl =pod comments are stripped from script before compiling, and associated
PodComments configuration options.
+Command line cgi/asp script takes various options, and allows execution
of multiple asp scripts at one time. This script should be used for
command line debugging. This is also the beginning of building
a static site from asp scripts with the -b option, suppressing headers.
+$Response->AddHeader('Set-Cookie') works for multiple cookies.
-$Response->Cookies('foo', '0') works, was dropping 0 because of boolean test
-Fixed up some config doc errors.
$VERSION = 0.07; $DATE="01/20/1999";
-removed SIG{__WARN__} handler, it was a bad idea.
-fixes file locking on QNX, work around poor flock porting
+removed message about Win32::OLE on UNIX platforms from Makefile.PL
: For a session, scripts execute one at a time
: NOT recommended use, please see note.
-MLDBM can be used for other things without messing up internal use
: before if it was used with different DB's and serializers,
internal state could be lost.
--State file locking. Corruption worries, and loss of data no more.
+CGI header support, developer can use CGI.pm for *output*, or just print()
: print "Set-Cookie: test=cookie\n", and things will just work
: use CGI.pm for output
: utilizes $r->send_cgi_header(), thanks Doug!
+Improved Cookie implementation, more flexible and complete
- Domain cookie key now works
: Expire times now taken from time(), and relative time in sec
: Request->Cookies() reading more flexible, with wantarray()
on hash cookie values, %hash = $Request->Cookie('test');
-make test module naming correction, was t.pm, now T.pm for Unix
+POD / README cleanup, formatting and HTML friendly.
$VERSION = 0.03; $DATE="09/14/1998";
+Installation 'make test' now works
+ActiveX objects on Win32 implemented with $Server->CreateObject()
+Cookies implemented: $Response->Cookies() & $Request->Cookies()
-Fixed $Response object API, converting some methods to object members.
Deprecated methods, but backwards compatible.
+Improved error messaging, debug output
+$, influences $Response->Write(@strings) behavior
+perl print() works, sending output to $Response object
lib/Apache/ASP/CGI.pm view on Meta::CPAN
$self->subprocess_env(Apache::ASP::CGI::Table->new);
my $env = $self->subprocess_env;
%$env = %ENV;
$self->filename($filename);
$self->connection->remote_ip($ENV{REMOTE_HOST} || $ENV{REMOTE_ADDR} || '0.0.0.0');
$self->connection->aborted(0);
$self->current_callback('PerlHandler');
# $self->headers_in->set('Cookie', $ENV{HTTP_COOKIE});
for my $env_key ( sort keys %ENV ) {
if($env_key =~ /^HTTP_(.+)$/ or $env_key =~ /^(CONTENT_TYPE|CONTENT_LENGTH)$/) {
my $env_header_in = $1;
my $header_key = join('-', map { ucfirst(lc($_)) } split(/\_/, $env_header_in));
$self->headers_in->set($header_key, $ENV{$env_key});
}
}
# we kill the state for now stuff for now, as it's just leaving .state
# directories everywhere you run this stuff
lib/Apache/ASP/Request.pm view on Meta::CPAN
use strict;
sub new {
my $asp = shift;
my $r = $asp->{r};
my $self = bless
{
asp => $asp,
# content => undef,
# Cookies => undef,
# FileUpload => undef,
# Form => undef,
# QueryString => undef,
# ServerVariables => undef,
Method => $r->method || 'GET',
TotalBytes => 0,
};
# calculate whether to read POST data here
my $request_binary_read = &config($asp, 'RequestBinaryRead', undef, 1);
lib/Apache/ASP/Request.pm view on Meta::CPAN
my $query = $r->args();
my $parsed_query = $query ? &ParseParams($self, \$query) : {};
$self->{'QueryString'} = bless $parsed_query, 'Apache::ASP::Collection';
if(&config($asp, 'RequestParams')) {
$self->{'Params'} = bless { %$parsed_query, %$form }, 'Apache::ASP::Collection';
}
# do cookies now
my %cookies;
if(my $cookie = $headers_in->get('Cookie')) {
my @parts = split(/;\s*/, ($cookie || ''));
for(@parts) {
my($name, $value) = split(/\=/, $_, 2);
$name = &Unescape($self, $name);
next if ($name eq $Apache::ASP::SessionCookieName);
next if $cookies{$name}; # skip dup's
$cookies{$name} = ($value =~ /\=/) ?
&ParseParams($self, $value) : &Unescape($self, $value);
}
}
$self->{Cookies} = bless \%cookies, 'Apache::ASP::Collection';
$self;
}
sub DESTROY {
my $self = shift;
if($self->{cgi}) {
# make sure CGI file handles are freed
$self->{cgi}->DESTROY();
lib/Apache/ASP/Request.pm view on Meta::CPAN
# which is fine for CGI.pm
sub READ {
my $self = $_[0];
$_[1] ||= '';
$_[1] .= $self->{content};
$self->{ServerVariables}{CONTENT_LENGTH};
}
sub BINMODE { };
# COLLECTIONS, normal, Cookies are special, with the dictionary lookup
# directly aliased as this should be faster than autoloading
sub Form { shift->{Form}->Item(@_) }
sub FileUpload { shift->{FileUpload}->Item(@_) }
sub QueryString { shift->{QueryString}->Item(@_) }
sub ServerVariables { shift->{ServerVariables}->Item(@_) }
sub Params {
my $self = shift;
$self->{Params}
|| die("\$Request->Params object does not exist, enable with 'PerlSetVar RequestParams 1'");
lib/Apache/ASP/Request.pm view on Meta::CPAN
my $rv = sysread(*STDIN, $data, $length, 0);
$asp->{dbg} && $asp->Debug("read $rv bytes from STDIN for CGI mode, tried $length bytes");
} else {
$r->read($data, $length);
$asp->{dbg} && $asp->Debug("read ".length($data)." bytes, tried $length bytes");
}
return $data;
}
}
sub Cookies {
my($self, $name, $key) = @_;
if(! $name) {
$self->{Cookies};
} elsif($key) {
$self->{Cookies}{$name}{$key};
} else {
# when we just have the name, are we expecting a dictionary or not
my $cookie = $self->{Cookies}{$name};
if(ref $cookie && wantarray) {
return %$cookie;
} else {
# CollectionItem support here one day, to not return
# an undef object, CollectionItem needs tied hash support
return $cookie;
}
}
}
lib/Apache/ASP/Response.pm view on Meta::CPAN
{
asp => $asp,
out => \$out,
# internal extension allowing various scripts like Session_OnStart
# to end the same response
# Ended => 0,
CacheControl => 'private',
CH => &config($asp, 'CgiHeaders') || 0,
# Charset => undef,
Clean => &config($asp, 'Clean') || 0,
Cookies => bless({}, 'Apache::ASP::Collection'),
ContentType => 'text/html',
'Debug' => $asp->{dbg},
FormFill => &config($asp, 'FormFill'),
IsClientConnected => 1,
# PICS => undef,
# Status => 200,
# header_buffer => '',
# header_done => 0,
Buffer => &config($asp, 'BufferingOn', undef, 1),
BinaryRef => \$out,
lib/Apache/ASP/Response.pm view on Meta::CPAN
};
sub BinaryWrite {
$_[0]->Flush();
$_[0]->{asp}{dbg} && $_[0]->{asp}->Debug("binary write of ".length($_[1])." bytes");
&Write;
}
sub Clear { my $out = shift->{out}; $$out = ''; }
sub Cookies {
my($self, $name, $key, $value) = @_;
if(defined($name) && defined($key) && defined($value)) {
$self->{Cookies}{$name}{$key} = $value;
} elsif(defined($name) && defined($key)) {
# we are assigning cookie with name the value of key
if(ref $key) {
# if a hash, set the values in it to the keys values
# we don't just assign the ref directly since for PerlScript
# compatibility
while(my($k, $v) = each %{$key}) {
$self->{Cookies}{$name}{$k} = $v;
}
} else {
$self->{Cookies}{$name}{Value} = $key;
}
} elsif(defined($name)) {
# if the cookie was just stored as the name value, then we will
# will convert it into its hash form now, so we can store other
# things. We will probably be storing other things now, since
# we are referencing the cookie directly
my $cookie = $self->{Cookies}{$name} || {};
$cookie = ref($cookie) ? $cookie : { Value => $cookie };
$self->{Cookies}{$name} = bless $cookie, 'Apache::ASP::Collection';
} else {
$self->{Cookies};
}
}
sub End {
my $self = shift;
# by not calling EndSoft(), but letting it be called naturally after
# Execute() in hander(), we allow more natural Buffer flushing to occur
# even if we are in a situation where Flush() has been made null like
# in an XMLSubs or cached or trapped include
# &EndSoft($self);
lib/Apache/ASP/Response.pm view on Meta::CPAN
} else {
$dbg && defined $status && $self->{asp}->Debug("status $status");
}
if(defined $self->{Charset}) {
$r->content_type($self->{ContentType}.'; charset='.$self->{Charset});
} else {
$r->content_type($self->{ContentType}); # add content-type
}
if(%{$self->{'Cookies'}}) {
&AddCookieHeaders($self); # do cookies
}
# do the expiration time
if(defined $self->{Expires}) {
my $ttl = $self->{Expires};
$r->headers_out->set('Expires', &Apache::ASP::Date::time2str(time()+$ttl));
$dbg && $self->{asp}->Debug("expires in $self->{Expires}");
} elsif(defined $self->{ExpiresAbsolute}) {
my $date = $self->{ExpiresAbsolute};
my $time = &Apache::ASP::Date::str2time($date);
lib/Apache/ASP/Response.pm view on Meta::CPAN
$r->send_http_header();
}
}
}
}
1;
}
# do cookies, try our best to emulate cookie collections
sub AddCookieHeaders {
my $self = shift;
my $cookies = $self->{'Cookies'};
my $dbg = $self->{asp}{dbg};
# print STDERR Data::Dumper::DumperX($cookies);
my($cookie_name, $cookie);
for $cookie_name (sort keys %{$cookies}) {
# skip key used for session id
if($Apache::ASP::SessionCookieName eq $cookie_name) {
confess("You can't use $cookie_name for a cookie name ".
"since it is reserved for session management"
);
}
my($k, $v, @data, $header, %dict, $is_ref, $cookie, $old_k);
$cookie = $cookies->{$cookie_name};
unless(ref $cookie) {
$cookie->{Value} = $cookie;
lib/Apache/ASP/Response.pm view on Meta::CPAN
my @dict;
for my $k ( sort keys %{$cookie->{Value}} ) {
my $v = $cookie->{Value}{$k};
push(@dict, $server->URLEncode($k) . '=' . $server->URLEncode($v));
}
$cookie->{Value} = join('&', @dict);
}
$data[0] = $server->URLEncode($cookie_name) . "=$cookie->{Value}";
# have to clean the data now of undefined values, but
# keeping the position is important to stick to the Cookie-Spec
my @cookie;
for(0..4) {
next unless $data[$_];
push(@cookie, $data[$_]);
}
my $cookie_header = join('; ', @cookie);
$self->{r}->err_headers_out->add('Set-Cookie', $cookie_header);
$dbg && $self->{asp}->Debug({cookie_header=>$cookie_header});
}
}
# with the WriteRef vs. Write abstration, direct calls
# to write might slow a little, but more common static
# html calls to WriteRef will be saved the HTML copy
sub Write {
my $self = shift;
lib/Apache/ASP/Response.pm view on Meta::CPAN
}
# for the split, we do not need to handle other entity references besides &
# because &, =, and ; should be the only special characters in the query string
# and the only of these characters that are represented by an entity reference
# is & as & ... the rest of the special characters that might be encoded
# in a URL should be URI escaped
# --jc 2/10/2003
my @new_query_parts;
map {
(! /^$Apache::ASP::SessionCookieName\=/) && push(@new_query_parts, $_);
}
split(/&|&/, $query);
my $new_query = join('&',
@new_query_parts,
$Apache::ASP::SessionCookieName.'='.$asp->{session_id}
);
$new_url .= '?'.$new_query;
if($frag) {
$new_url .= $frag;
}
$asp->{dbg} && $asp->Debug("parsed session into $new_url");
$new_url;
} else {
$rel_url;
}
lib/Apache/ASP/Server.pm view on Meta::CPAN
if(
# if we have match expression, try it
($match && $url =~ /$match/)
# then if server path, check matches cookie space
|| ($url =~ m|^/| and $url =~ m|^$asp->{cookie_path}|)
# then do all local paths, matching NOT some URI PROTO
|| ($url !~ m|^[^\?\/]+?:|)
)
{
# this should overwrite an incorrectly passed in data
$params->{$Apache::ASP::SessionCookieName} = $asp->{session_id};
}
}
my($k,$v, @query);
# changed to use sort so this function outputs the same URL every time
for my $k ( sort keys %$params ) {
my $v = $params->{$k};
# inline the URLEncode function for speed
$k =~ s/([^a-zA-Z0-9_\-.])/uc sprintf("%%%02x",ord($1))/egs;
lib/Apache/ASP/StateManager.pm view on Meta::CPAN
$self->{state_serialize} && $self->{Application}->Lock;
} else {
$self->{dbg} && $self->Debug("no application allowed config");
}
# SESSION if we are tracking state, set up the appropriate objects
my $session;
if($self->{session_state}) {
## SESSION INITS
$self->{cookie_path} = &config($self, 'CookiePath', undef, '/');
$self->{cookie_domain} = &config($self, 'CookieDomain');
$self->{paranoid_session} = &config($self, 'ParanoidSession');
$self->{remote_ip} = eval { $r->connection()->remote_ip() }; # may not exist in Apache 2.4
$self->{remote_ip} ||= eval { $r->useragent_ip() }; # should exist in Apache 2.4, best for end user agent IP address
$self->{remote_ip} ||= eval { $r->connection()->client_ip() }; # if useragent_ip not defined for Apache 2.4, try this one
$self->{session_count} = &config($self, 'SessionCount');
# cookieless session support, cascading values
$self->{session_url_parse_match} = &config($self, 'SessionQueryParseMatch');
lib/Apache/ASP/StateManager.pm view on Meta::CPAN
# combo get / set
sub SessionId {
my($self, $id) = @_;
if(defined $id) {
unless($self->{session_url_force}) {
# don't set the cookie when we are just using SessionQuery* configs
my $secure = $self->{secure_session} ? '; secure' : '';
my $httponly = $self->{http_only_session} ? '; HttpOnly' : '';
my $domain = $self->{cookie_domain} ? '; domain='.$self->{cookie_domain} : '';
$self->{r}->err_headers_out->add('Set-Cookie', "$SessionCookieName=$id; path=$self->{cookie_path}".$domain.$secure.$httponly);
}
$self->{session_id} = $id;
} else {
# if we have already parsed it out, return now
# quick session_id caching, mostly for use with
# cookie less url building
$self->{session_id} && return $self->{session_id};
my $session_cookie = 0;
unless($self->{session_url_force}) {
# don't read the cookie when we are just using SessionQuery* configs
my $cookie = $self->{r}->headers_in->{"Cookie"} || '';
my(@parts) = split(/\;\s*/, $cookie);
for(@parts) {
my($name, $value) = split(/\=/, $_, 2);
if($name eq $SessionCookieName) {
$id = $value;
$session_cookie = 1;
$self->{dbg} && $self->Debug("session id from cookie: $id");
last;
}
}
}
my $session_from_url;
if(! defined($id) && $self->{session_url}) {
$id = delete $self->{Request}{QueryString}{$SessionCookieName};
# if there was more than one session id in the query string, then just
# take the first one
ref($id) =~ /ARRAY/ and ($id) = @$id;
$id && $self->{dbg} && $self->Debug("session id from query string: $id");
$session_from_url = 1;
}
# SANTIZE the id against hacking
if(defined $id) {
if($id =~ /^[0-9a-z]{8,32}$/s) {
site/changes.html view on Meta::CPAN
++ mod_perl 2 optmizations, there was a large code impact on this,
as much code was restructured to reduce the differences between
mod_perl 1 and mod_perl 2, most importantly, Apache::compat is
no longer used
+ preloaded CGI for file uploads in the mod_perl environment
- When XSLT config is set, $Response->Redirect() should work now
Thanks to Marcus Zoller for pointing problem out
+ Added CookieDomain setting, documented, and added test to cover
it in t/cookies.t . Setting suggested by Uwe Riehm, who nicely
submitted some code for this.
</pre></font>
<p>
<a name=%24VERSION%20%3D%2022c8082fb></a>
<font face=verdana><font class=title size=+0 color=#555555><b>$VERSION = 2.53; $DATE="04/10/2003"</b></font>
<font face="courier new" size=3><pre>
+ XMLSubs tags with "-" in them will have "-" replaced with "_" or underscore, so a
tag like <my:render-table /> will be translated to &my::render_table() ... tags with
site/changes.html view on Meta::CPAN
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 <a href=eg/filter.filter>./site/eg/filter.filter</a> 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
site/changes.html view on Meta::CPAN
+$Server->Config() call will return a hash ref
to all the config setting for that request, like
Apache->dir_config would.
-StatINC setting with Apache::ASP->Loader() works again.
This makes StatINC & StatINCMatch settings viable
for production & development use when the system has
very many modules.
-Cookieless session support with configs like SessionQueryParse
and SessionQuery now work for URLs with frags in them
like <tt>http://localhost?arg=value#frag</tt>
+@rv = $Response->Include() now works where there are
multiple return values from an include like:
<% return(1,2); %>
</pre></font>
<p>
<a name=%24VERSION%20%3D%202c37caa32></a>
site/changes.html view on Meta::CPAN
+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.
site/changes.html view on Meta::CPAN
separate package. As of v.10, scripts are compiled by default
into the same package, so that scripts, dynamic includes & global.asa
can share globals. This BROKE scripts in the same ASP Application
that defined the same sub routines, as their subs would redefine
each other.
UniquePackages has scripts compiled into separate perl packages,
so they may define subs with the same name, w/o fear of overlap.
Under this settings, scripts will not be able to share globals.
-Secure field for cookies in $Response->Cookies() must be TRUE to
force cookie to be secure. Before, it just had to be defined,
which gave wrong behavior for Secure => 0.
+$Response->{IsClientConnected} set to one by default. Will
work out a real value when I upgrade to apache 1.3.6. This
value has no meaning before, as apache aborts the perl code
when a client drops its connection in earlier versions.
+better compile time debugging of dynamic includes, with
Debug 2 setting
site/changes.html view on Meta::CPAN
Without an output directory, script output is written to STDOUT
</pre></font>
<p>
<a name=%24VERSION%20%3D%2005ee189f2></a>
<font face=verdana><font class=title size=+0 color=#555555><b>$VERSION = 0.09; $DATE="04/22/1999";</b></font>
<font face="courier new" size=3><pre>
+Updated Makefile.PL optional modules output for CGI & DB_File
+Improved docs on $Response->Cookies() and $Request->Cookies()
+Added PERFORMANCE doc to main README, and added sub section
on precompiling scripts with Apache::ASP->Loader()
+Naming of CompileIncludes switched over to DynamicIncludes
for greater clarity.
+Dynamic includes can now reference ASP objects like $Session
w/o the $main::* syntax. These subs are no longer anonymous
subs, and are now compiled into the namespace of the global.asa package.
site/changes.html view on Meta::CPAN
- <% @array... %> no longer dropped from code.
+perl =pod comments are stripped from script before compiling, and associated
PodComments configuration options.
+Command line cgi/asp script takes various options, and allows execution
of multiple asp scripts at one time. This script should be used for
command line debugging. This is also the beginning of building
a static site from asp scripts with the -b option, suppressing headers.
+$Response->AddHeader('Set-Cookie') works for multiple cookies.
-$Response->Cookies('foo', '0') works, was dropping 0 because of boolean test
-Fixed up some config doc errors.
</pre></font>
<p>
<a name=%24VERSION%20%3D%2003960e08a></a>
<font face=verdana><font class=title size=+0 color=#555555><b>$VERSION = 0.07; $DATE="01/20/1999";</b></font>
<font face="courier new" size=3><pre>
-removed SIG{__WARN__} handler, it was a bad idea.
site/changes.html view on Meta::CPAN
: For a session, scripts execute one at a time
: NOT recommended use, please see note.
-MLDBM can be used for other things without messing up internal use
: before if it was used with different DB's and serializers,
internal state could be lost.
--State file locking. Corruption worries, and loss of data no more.
+CGI header support, developer can use CGI.pm for *output*, or just print()
: print "Set-Cookie: test=cookie\n", and things will just work
: use CGI.pm for output
: utilizes $r->send_cgi_header(), thanks Doug!
+Improved Cookie implementation, more flexible and complete
- Domain cookie key now works
: Expire times now taken from time(), and relative time in sec
: Request->Cookies() reading more flexible, with wantarray()
on hash cookie values, %hash = $Request->Cookie('test');
-make test module naming correction, was t.pm, now T.pm for Unix
+POD / README cleanup, formatting and HTML friendly.
</pre></font>
<p>
<a name=%24VERSION%20%3D%200ec664faf></a>
<font face=verdana><font class=title size=+0 color=#555555><b>$VERSION = 0.03; $DATE="09/14/1998";</b></font>
<font face="courier new" size=3><pre>
+Installation 'make test' now works
+ActiveX objects on Win32 implemented with $Server->CreateObject()
+Cookies implemented: $Response->Cookies() & $Request->Cookies()
-Fixed $Response object API, converting some methods to object members.
Deprecated methods, but backwards compatible.
+Improved error messaging, debug output
+$, influences $Response->Write(@strings) behavior
+perl print() works, sending output to $Response object
site/config.html view on Meta::CPAN
<a href=#RequestParam25a784ba>RequestParams</a>
</font>
</td>
</tr>
<tr>
<td valign=top >
<font face="lucida console" size=-1>
<a href=#CookiePath>CookiePath</a>
</font>
</td>
<td valign=top >
<font face="lucida console" size=-1>
<a href=#RequestBinarc4419e4b>RequestBinaryRead</a>
</font>
</td>
</tr>
<tr>
<td valign=top >
<font face="lucida console" size=-1>
<a href=#CookieDomain>CookieDomain</a>
</font>
</td>
<td valign=top >
<font face="lucida console" size=-1>
<a href=#StatINC>StatINC</a>
</font>
</td>
</tr>
site/config.html view on Meta::CPAN
<a href=#CompressGzip>CompressGzip</a>
</font>
</td>
</tr>
<tr>
<td valign=top bgcolor=#005196>
<font face="lucida console" size=-1>
<font color=white><b><a href=#Cookieless%20S21cbf4f4><font color=white>Cookieless Sessions</font></a></b></font>
</font>
</td>
<td valign=top >
<font face="lucida console" size=-1>
<a href=#FormFill>FormFill</a>
</font>
</td>
</tr>
site/config.html view on Meta::CPAN
<font face="courier new" size=3><pre>
PerlSetVar StateSerializer Data::Dumper
</pre></font>
<p>
<a name=Sessions></a>
<font face=verdana><font class=title size=+0 color=#555555><b>Sessions</b></font>
</font>
<p>
<a name=CookiePath></a>
<font face=verdana><font class=title size=-1 color=#555555><b>CookiePath</b></font>
<font face="courier new" size=3><pre>
</pre></font>URL root that client responds to by sending the session cookie.
If your asp application falls under the server url "/asp",
then you would set this variable to /asp. This then allows
you to run different applications on the same server, with
different user sessions for each application.
<font face="courier new" size=3><pre>
PerlSetVar CookiePath /
</pre></font>
<p>
<a name=CookieDomain></a>
<font face=verdana><font class=title size=-1 color=#555555><b>CookieDomain</b></font>
<font face="courier new" size=3><pre>
</pre></font>Default 0, this NON-PORTABLE configuration will allow sessions to span
multiple web sites that match the same domain root. This is useful if
your web sites are hosted on the same machine and can share the same
StateDir configuration, and you want to shared the $Session data
across web sites. Whatever this is set to, that will add a
<font face="courier new" size=3><pre>
; domain=$CookieDomain
</pre></font>part to the Set-Cookie: header set for the session-id cookie.
<font face="courier new" size=3><pre>
PerlSetVar CookieDomain .your.global.domain
</pre></font>
<p>
<a name=SessionTimeo21fc354e></a>
<font face=verdana><font class=title size=-1 color=#555555><b>SessionTimeout</b></font>
<font face="courier new" size=3><pre>
</pre></font>Default 20 minutes, when a user's session has been inactive for this
period of time, the Session_OnEnd event is run, if defined, for
that session, and the contents of that session are destroyed.
<font face="courier new" size=3><pre>
site/config.html view on Meta::CPAN
</pre></font>default 0, if true enables the $Application->SessionCount API
which returns how many sessions are currently active in
the application. This config was created
because there is a performance hit associated with this
count tracking, so it is disabled by default.
<font face="courier new" size=3><pre>
PerlSetVar SessionCount 1
</pre></font>
<p>
<a name=Cookieless%20S21cbf4f4></a>
<font face=verdana><font class=title size=+0 color=#555555><b>Cookieless Sessions</b></font>
</font>
<p>
<a name=SessionQuery6920bb61></a>
<font face=verdana><font class=title size=-1 color=#555555><b>SessionQueryParse</b></font>
<font face="courier new" size=3><pre>
</pre></font>default 0, if true, will automatically parse the $Session
session id into the query string of each local URL found in the
$Response buffer. For this setting to work therefore,
buffering must be enabled. This parsing will only occur
site/config.html view on Meta::CPAN
PerlSetVar Filter Off
</pre></font>
<p>
<a name=CgiHeaders></a>
<font face=verdana><font class=title size=-1 color=#555555><b>CgiHeaders</b></font>
<font face="courier new" size=3><pre>
</pre></font>default 0. When true, script output that looks like HTTP / <a href=cgi.html><font size=-1 face=verdana><b>CGI</b></font></a>
headers, will be added to the HTTP headers of the request.
So you could add:
<font face="courier new" size=3><pre> Set-Cookie: test=message
<html>...
</pre></font>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
functionality is here for compatibility with raw cgi scripts,
and those used to this kind of coding.
<font face="courier new" size=3><pre>
</pre></font>When set to 0, CgiHeaders style headers will not be parsed from the
script response.
<font face="courier new" size=3><pre>
site/eg/.htaccess view on Meta::CPAN
PerlSetVar TimeHiRes 1
PerlSetVar CompressGzip 0
PerlSetVar UseStrict 1
#PerlSetVar CacheDB DB_File
PerlSetVar CacheDB MLDBM::Sync::SDBM_File
# .asp files for Session state enabled
<Files ~ (\.asp)>
SetHandler perl-script
PerlHandler Apache::ASP
PerlSetVar CookiePath /
PerlSetVar SessionTimeout 5
PerlSetVar RegisterIncludes 1
PerlSetVar XMLSubsMatch my:\w+
PerlSetVar AllowApplicationState 1
PerlSetVar AllowSessionState 1
# PerlSetVar StateSerializer Storable
# PerlSetVar StateDB DB_File
# PerlSetVar StatScripts 0
</Files>
site/eg/.htaccess view on Meta::CPAN
<Files ~ (\filter.filter)>
SetHandler perl-script
PerlHandler Apache::ASP Apache::ASP
PerlSetVar Global .
PerlSetVar Filter On
</Files>
<Files ~ (session_query_parse.asp$)>
SetHandler perl-script
PerlHandler Apache::ASP
PerlSetVar CookiePath /
PerlSetVar SessionTimeout 1
PerlSetVar SessionQueryParseMatch ^http://localhost
</Files>
<Files ~ (xml_subs_strict\.asp)>
SetHandler perl-script
PerlHandler Apache::ASP
PerlSetVar CookiePath /
PerlSetVar SessionTimeout 5
PerlSetVar RegisterIncludes 1
PerlSetVar XMLSubsMatch my:\w+
PerlSetVar XMLSubsStrict 1
</Files>
site/eg/response.asp view on Meta::CPAN
# Buffer
(defined $Session->{buffer})
|| ($Session->{buffer} = $Response->{Buffer});
if($form->{buffer}) {
$Session->{buffer} = ! $Session->{buffer};
}
my $buffer_display = $Session->{buffer}
? "Set Buffer Off" : "Set Buffer On";
$Response->{Buffer} = $Session->{buffer};
# Cookie
if($form->{cookie_name}) {
$Response->{Cookies}{$form->{cookie_name}} =
$form->{cookie_value};
}
%>
<center>
<table border=1 cellpadding=2>
<tr><td colspan=2 align=center><b>Response Object Demonstration</b></td></tr>
<form action=<%=$demo->{file}%> method=GET>
<tr>
<td colspan=2 align=center>
site/eg/response.asp view on Meta::CPAN
<tr>
<td><b>Expires On</b></td>
<td><%=$update_time%></td>
</tr>
<% } %>
<tr>
<td><b>Buffering</b></td>
<td><%=$Response->{Buffer} ? "On" : "Off"%></td>
</tr>
<tr>
<td><b>Cookie (Name=Value)</b></td>
<td>
<input type=text name=cookie_name
value="<%=$form->{cookie_name}%>">
=
<input type=text name=cookie_value
value="<%=$form->{cookie_value}%>">
</td>
</tr>
<tr>
<td><b>Cookies*</b></td>
<td>
<%
while(my($k, $v) = each %{$Request->Cookies()}) {
if(ref $v) {
print "$k:<br>\n";
for(keys %$v) {
print "- $v->{$_}=$_<br>\n";
}
} else {
print "$k=$v\n";
}
print "<p>\n";
}
site/objects.html view on Meta::CPAN
<tr>
<td valign=top >
<font face="lucida console" size=-1>
<a href=#%24Session-%3EUnc1c1024f>$Session->UnLock()</a>
</font>
</td>
<td valign=top >
<font face="lucida console" size=-1>
<a href=#%24Request-%3ECoe6d79e01>$Request->Cookies($name [,$key])</a>
</font>
</td>
</tr>
<tr>
<td valign=top >
<font face="lucida console" size=-1>
site/objects.html view on Meta::CPAN
<a href=#%24Server-%3EGetb3d1ac42>$Server->GetLastError()</a>
</font>
</td>
</tr>
<tr>
<td valign=top >
<font face="lucida console" size=-1>
<a href=#%24Response-%3ECd77d06d7>$Response->Cookies($name, [$key,] $value)</a>
</font>
</td>
<td valign=top >
<font face="lucida console" size=-1>
<a href=#%24Server-%3EHTMb165f10b>$Server->HTMLEncode( $string || \$string )</a>
</font>
</td>
</tr>
site/objects.html view on Meta::CPAN
its data is binary.</font>
<p>
<a name=%24Response-%3EC08958c05></a>
<font face=verdana><font class=title size=-1 color=#555555><b>$Response->Clear()</b></font>
<font face="courier new" size=3><pre>
</pre></font>Erases buffered ASP output.</font>
<p>
<a name=%24Response-%3ECd77d06d7></a>
<font face=verdana><font class=title size=-1 color=#555555><b>$Response->Cookies($name, [$key,] $value)</b></font>
<font face="courier new" size=3><pre>
</pre></font>Sets the key or attribute of cookie with name $name to the value $value.
If $key is not defined, the Value of the cookie is set.
ASP CookiePath is assumed to be / in these examples.
<font face="courier new" size=3><pre>
$Response->Cookies('name', 'value');
--> Set-Cookie: name=value; path=/
$Response->Cookies("Test", "data1", "test value");
$Response->Cookies("Test", "data2", "more test");
$Response->Cookies(
"Test", "Expires",
&HTTP::Date::time2str(time+86400)
);
$Response->Cookies("Test", "Secure", 1);
$Response->Cookies("Test", "Path", "/");
$Response->Cookies("Test", "Domain", "host.com");
--> Set-Cookie:Test=data1=test%20value&data2=more%20test; \
expires=Fri, 23 Apr 1999 07:19:52 GMT; \
path=/; domain=host.com; secure
</pre></font>The latter use of $key in the cookies not only sets cookie attributes
such as Expires, but also treats the cookie as a hash of key value pairs
which can later be accesses by
<font face="courier new" size=3><pre>
$Request->Cookies('Test', 'data1');
$Request->Cookies('Test', 'data2');
</pre></font>Because this is perl, you can (NOT PORTABLE) reference the cookies
directly through hash notation. The same 5 commands above could be compressed to:
<font face="courier new" size=3><pre>
$Response->{Cookies}{Test} =
{
Secure => 1,
Value =>
{
data1 => 'test value',
data2 => 'more test'
},
Expires => 86400, # not portable, see above
Domain => 'host.com',
Path => '/'
};
</pre></font>and the first command would be:
<font face="courier new" size=3><pre>
# you don't need to use hash notation when you are only setting
# a simple value
$Response->{Cookies}{'Test Name'} = 'Test Value';
</pre></font>I prefer the hash notation for cookies, as this looks nice, and is
quite perlish. It is here to stay. The Cookie() routine is
very complex and does its best to allow access to the
underlying hash structure of the data. This is the best emulation
I could write trying to match the Collections functionality of
cookies in IIS ASP.
<font face="courier new" size=3><pre>
</pre></font>For more information on Cookies, please go to the source at
<a href=http://home.netscape.com/newsref/std/cookie_spec.html>http://home.netscape.com/newsref/std/cookie_spec.html</a></font>
<p>
<a name=%24Response-%3EDe321f073></a>
<font face=verdana><font class=title size=-1 color=#555555><b>$Response->Debug(@args)</b></font>
<font face="courier new" size=3><pre>
</pre></font>API Extension. If the Debug config option is set greater than 0,
this routine will write @args out to server error log. refs in @args
will be expanded one level deep, so data in simple data structures
like one-level hash refs and array refs will be displayed. CODE
site/objects.html view on Meta::CPAN
as normal.</font>
<p>
<a name=%24Request-%3ECled50cd44></a>
<font face=verdana><font class=title size=-1 color=#555555><b>$Request->ClientCertificate()</b></font>
<font face="courier new" size=3><pre>
</pre></font>Not implemented.</font>
<p>
<a name=%24Request-%3ECoe6d79e01></a>
<font face=verdana><font class=title size=-1 color=#555555><b>$Request->Cookies($name [,$key])</b></font>
<font face="courier new" size=3><pre>
</pre></font>Returns the value of the Cookie with name $name. If a $key is
specified, then a lookup will be done on the cookie as if it were
a query string. So, a cookie set by:
<font face="courier new" size=3><pre>
Set-Cookie: test=data1=1&data2=2
</pre></font>would have a value of 2 returned by $Request->Cookies('test','data2').
<font face="courier new" size=3><pre>
</pre></font>If no name is specified, a hash will be returned of cookie names
as keys and cookie values as values. If the cookie value is a query string,
it will automatically be parsed, and the value will be a hash reference to
these values.
<font face="courier new" size=3><pre>
</pre></font>When in doubt, try it out. Remember that unless you set the Expires
attribute of a cookie with $Response->Cookies('cookie', 'Expires', $xyz),
the cookies that you set will only last until you close your browser,
so you may find your self opening & closing your browser a lot when
debugging cookies.
<font face="courier new" size=3><pre>
</pre></font>For more information on cookies in ASP, please read $Response->Cookies()</font>
<p>
<a name=%24Request-%3EFi6799fcec></a>
<font face=verdana><font class=title size=-1 color=#555555><b>$Request->FileUpload($form_field, $key)</b></font>
<font face="courier new" size=3><pre>
</pre></font>API extension. The FileUpload interface to file upload data is
stabilized. The internal representation of the file uploads
is a hash of hashes, one hash per file upload found in
the $Request->Form() collection. This collection of collections
may be queried through the normal interface like so:
site/perlscript.html view on Meta::CPAN
Please see the <a href=config.html><font size=-1 face=verdana><b>CONFIG</b></font></a> section for more info.
<font face="courier new" size=3><pre>
</pre></font>The following objects in Apache::ASP respond as Collections:
<font face="courier new" size=3><pre>
$Application
$Session
$Request->FileUpload *
$Request->FileUpload('upload_file') *
$Request->Form
$Request->QueryString
$Request->Cookies
$Response->Cookies
$Response->Cookies('some_cookie')
* FileUpload API Extensions
</pre></font>And as such may be used with the following syntax, as compared
with the Apache::ASP native calls. Please note the native Apache::ASP
interface is compatible with the deprecated PerlScript interface.
<font face="courier new" size=3><pre>
C = PerlScript Compatibility N = Native Apache::ASP
## Collection->Contents($name)
[C] $Application->Contents('XYZ')
site/perlscript.html view on Meta::CPAN
[N] $Application->{XYZ} = "Fred"
## Collection->GetProperty($property, $name)
[C] $Application->Contents->GetProperty('Item', 'XYZ')
[N] $Application->{XYZ}
## Collection->Item($name)
[C] print $Request->QueryString->Item('message'), "<br>\n\n";
[N] print $Request->{QueryString}{'message'}, "<br>\n\n";
## Working with Cookies
[C] $Response->SetProperty('Cookies', 'Testing', 'Extra');
[C] $Response->SetProperty('Cookies', 'Testing', {'Path' => '/'});
[C] print $Request->Cookies(Testing) . "<br>\n";
[N] $Response->{Cookies}{Testing} = {Value => Extra, Path => '/'};
[N] print $Request->{Cookies}{Testing} . "<br>\n";
</pre></font>Several incompatibilities exist between PerlScript and Apache::ASP:
<font face="courier new" size=3><pre>
> Collection->{Count} property has not been implemented.
> VBScript dates may not be used for Expires property of cookies.
> Win32::OLE::in may not be used. Use keys() to iterate over.
> The ->{Item} property does not work, use the ->Item() method.
</pre></font>
</font>
</td>
site/resources.html view on Meta::CPAN
<a href="http://www.wdvl.com/Authoring/Languages/Perl/PerlfortheWeb/index15.html">Embedded Perl ( part of a series on Perl )</a>
</pre></font>
<p>
<a name=Books></a>
<font face=verdana><font class=title size=+0 color=#555555><b>Books</b></font>
<font face="courier new" size=3><pre>
<a href="http://www.modperl.com">mod_perl "Eagle" Book</a>
<a href="http://www.modperlcookbook.org">mod_perl Developer's Cookbook</a>
<a href="http://www.oreilly.com/catalog/perldbi/">Programming the Perl DBI</a>
</pre></font>
<p>
<a name=Reference%20Ca8ece5e1d></a>
<font face=verdana><font class=title size=+0 color=#555555><b>Reference Cards</b></font>
<font face="courier new" size=3><pre>
<a href="http://www.refcards.com/">Apache & mod_perl Reference Cards</a>
</pre></font>
site/sessions.html view on Meta::CPAN
</td>
<td valign=top bgcolor=white>
<font size=+0 face=verdana,arial>
<font face=verdana><font class=title size=+1 color=#555555><b>SESSIONS</b></font>
<font face="courier new" size=3><pre>
</pre></font>Cookies are used by default for user $Session support ( see <a href=objects.html><font size=-1 face=verdana><b>OBJECTS</b></font></a> ).
In order to track a web user and associate server side data
with that client, the web server sets, and the web client returns
a 32 byte session id identifier cookie. This implementation
is very secure and may be used in secure HTTPS transactions,
and made stronger with SecureSession, HTTPOnlySession and
ParanoidSession settings (see <a href=config.html><font size=-1 face=verdana><b>CONFIG</b></font></a> ).
<font face="courier new" size=3><pre>
</pre></font>However good cookies are for this kind of persistent
state management between HTTP requests, they have long
been under fire for security risks associated with
JavaScript security exploits and privacy abuse by
large data tracking companies.
<font face="courier new" size=3><pre>
</pre></font>Because of these reasons, web users will sometimes turn off
their cookies, rendering normal ASP session implementations
powerless, resulting in a new $Session generated every request.
This is not good for ASP style sessions.</font>
<p>
<a name=Cookieless%20Sf057c84c></a>
<font face=verdana><font class=title size=+0 color=#555555><b>Cookieless Sessions</b></font>
<font face="courier new" size=3><pre>
*** See WARNING Below ***
</pre></font>So we now have more ways to track sessions with the
SessionQuery* <a href=config.html><font size=-1 face=verdana><b>CONFIG</b></font></a> settings, that allow a web developer
to embed the session id in URL query strings when use
of cookies is denied. The implementations work such that
if a user has cookies turned on, then cookies will be
used, but for those users with cookies turned off,
the session ids will be parsed into document URLs.
<font face="courier new" size=3><pre>
t/cookies.t view on Meta::CPAN
use Apache::ASP::CGI::Test;
use lib qw(t . ..);
use T;
use strict;
my $t = T->new;
my $r = Apache::ASP::CGI::Test->do_self(
UseStrict => 1,
CookieDomain => 'apache-asp.com',
SecureSession => 1,
CookiePath => '/eg/'
);
my $header = $r->test_header_out;
my $body = $r->test_body_out;
my @cookie_tests = (
'Set-Cookie: test=cookie; path=/',
'Set-Cookie: test2=value; expires=Wed, 06 Nov 2002 21:52:30 GMT; path=/path/; domain=test.com; secure',
'Set-Cookie: test3=key1=value1&key2=value2; path=/',
'Set-Cookie: session-id=[0-9a-f]+; path=/eg/; domain=apache-asp.com; secure',
);
for my $cookie_test ( @cookie_tests ) {
# $cookie_test =~ s/(\W)/$1/isg;
$t->eok(($header =~ /$cookie_test/s) ? 1 : 0, "Cookies header test");
}
$t->eok($body =~ /^\s*1\.\.1\nok\s*$/ ? 1 : 0, "Body test");
$t->done;
__END__
<%
$Response->{Cookies}{test} = "cookie";
$Response->{Cookies}{test2} = {
Value => 'value',
Path => "/path/",
Secure => 1,
Expires => "Wed, 06 Nov 2002 21:52:30 GMT",
Domain => 'test.com',
};
$Response->Cookies("test3", "key1", "value1");
$Response->Cookies("test3", "key2", "value2");
$t->ok;
%>