Apache-ASP

 view release on metacpan or  search on metacpan

ASP.pm  view on Meta::CPAN

    my $checksum = &md5_hex($key).'x'.length($key);
    my $metakey = $checksum . 'xMETA';
    my $rv;

    eval {
	$cache_dbm->{dbm}->Lock;
	if(defined $value) {
	    my $meta = { ServerID => $ServerID, Creation => time() };
	    if(defined $expires && ($expires =~ /^\-?\d+$/)) {
		$meta->{Expires} = $expires;
		$meta->{Timeout} = time + $expires;
	    };
	    $self->{dbg} && $self->Debug("storing $checksum in $cache_name cache");
	    $cache_dbm->STORE($metakey, $meta);
	    $self->{cache_count_store}++;
	    $rv = $cache_dbm->STORE($checksum, $value);
	} else {
	    # don't check meta data for XSLT since transformations don't expire ever
	    if($no_check_meta) {
		$self->{dbg} && $self->Debug("cache $cache_name fetch checksum $checksum no check meta");
		$self->{cache_count_fetch}++;

ASP.pm  view on Meta::CPAN

		if(! $meta) {
		    $meta = { Creation => 0, ServerID => 'NULL' };
		    $new = 1;
		} else {
		    # NEW EXPIRES FOR EXISTING ITEM
		    if(defined $expires && ($expires =~ /^\-?\d+$/) && ($expires != $meta->{Expires})) {
			$self->Debug("new expires $expires, old ".($meta->{Expires} || '')." for $checksum");
			$meta->{Expires} = $expires;
			# use creation timestamp for expires calculation, not current
			# time, or we would refresh the entry
			$meta->{Timeout} = $meta->{Creation} + $expires;
			$cache_dbm->STORE($metakey, $meta);
		    };
		}
		
		# LastModified calculations
		if(defined $last_modified) {
		    if($last_modified !~ /^\d+$/) {
			my $old_last_modified = $last_modified;
			$last_modified = &Apache::ASP::Date::str2time($last_modified);
			$self->{dbg} && $self->Debug("converting string date for LastModified $old_last_modified to unix time $last_modified");
		    }
		    if($last_modified < 0) {
			$self->{dbg} && $self->Debug("negative LastModified $last_modified ignored");
			$last_modified = undef;
		    }
		}
		
		# EARLY TIMEOUT CALCULATION
		if($meta->{Timeout}) {
		    # 10% chance to expire early to prevent collision
		    my $early = ($meta->{Expires} || 0) * rand() * '.1';
		    $self->{dbg} && $self->Debug("will reduce expires for $meta->{Expires} by random $early seconds, checksum $checksum");
		    $meta->{Timeout} = $meta->{Timeout} - $early;
		}
		
		$self->{dbg} && $self->Debug("meta cache data for checksum $checksum", $meta);
		
		if($new) {
		    $self->{dbg} && $self->Debug("no cache entry, checksum $checksum");
		    $self->{cache_count_miss}++;
		    $rv = undef;
		} elsif(defined $meta->{ServerID} && ($$ ne $ServerPID) && ($meta->{ServerID} ne $ServerID)) {
		    # can only run like this when running in preloaded mod_perl mode
		    # This will allow for caching in other modes that simply does not reset
		    # upon server restart
		    $self->{dbg} && $self->Debug("cache expires new server $ServerID, was $meta->{ServerID}");
		    $self->{cache_count_restart}++;
		    $rv = undef;
		} elsif($meta->{Timeout} && ($meta->{Timeout} <= time())) {
		    $self->{dbg} && $self->Debug("cache expires timeout $meta->{Timeout}, checksum $checksum, time ".time);
		    $self->{cache_count_expires}++;
		    $rv = undef;
		} elsif(defined($last_modified) && ($last_modified >= $meta->{Creation})) {
		    $self->{dbg} && $self->Debug("cache expires, checksum $checksum, LastModified $last_modified, Creation $meta->{Creation}");
		    $self->{cache_count_last_modified_expires}++;
		    $rv = undef;
		} else {
		    $self->{dbg} && $self->Debug("cache $cache_name fetch checksum $checksum");
		    $self->{cache_count_fetch}++;
		    $rv = $cache_dbm->{dbm}->FETCH($checksum);

ASP.pm  view on Meta::CPAN

	# in case of system level debugging, mark Net::SMTP debug also
	if((&config($self, 'Debug') || 0) < 0) {
	    $args{Debug} = 1;
	}
    }

    # connect to server
    {
	local $SIG{__WARN__} = sub { $self->Debug('Net::SMTP->new() warning', @_) };
	if($mail->{Test}) {
	    $args{Timeout} = 5;
	}
	$smtp = Net::SMTP->new(%args);
    }
    unless($smtp) {
	$self->Out("[ERROR] can't connect to SMTP server with args ", \%args);
	return 0;
    } else {
	$self->Debug("connected to SMTP server with args ", \%args);
    }

ASP.pm  view on Meta::CPAN

The reason for this config option is to allow operating systems with caching
file systems like Solaris to specify a state directory separately
from the Global directory, which contains more permanent files.
This way one may point StateDir to /tmp/myaspapp, and make one's ASP
application scream with speed.

  PerlSetVar StateDir ./.state

=item StateManager

default 10, this number specifies the numbers of times per SessionTimeout
that timed out sessions are garbage collected.  The bigger the number,
the slower your system, but the more precise Session_OnEnd's will be 
run from global.asa, which occur when a timed out session is cleaned up,
and the better able to withstand Session guessing hacking attempts.
The lower the number, the faster a normal system will run.  

The defaults of 20 minutes for SessionTimeout and 10 times for 
StateManager, has dead Sessions being cleaned up every 2 minutes.

  PerlSetVar StateManager 10

=item StateDB

default SDBM_File, this is the internal database used for state
objects like $Application and $Session.  Because an SDBM_File %hash 
has a limit on the size of a record key+value pair, usually 1024 bytes,
you may want to use another tied database like DB_File or

ASP.pm  view on Meta::CPAN

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

default 0.  Sets the secure tag for the session cookie, so that the cookie
will only be transmitted by the browser under https transmissions.

  PerlSetVar SecureSession 1

=item HTTPOnlySession

ASP.pm  view on Meta::CPAN


Triggered by a user session ending, Session_OnEnd can be useful
for cleaning up and analyzing user data accumulated during a session.

Sessions end when the session timeout expires, and the StateManager
performs session cleanup.  The timing of the Session_OnEnd does not
occur immediately after the session times out, but when the first 
script runs after the session expires, and the StateManager allows
for that session to be cleaned up.  

So on a busy site with default SessionTimeout (20 minutes) and 
StateManager (10 times) settings, the Session_OnEnd for a particular 
session should be run near 22 minutes past the last activity that Session saw.
A site infrequently visited will only have the Session_OnEnd run
when a subsequent visit occurs, and theoretically the last session
of an application ever run will never have its Session_OnEnd run.

Thus I would not put anything mission-critical in the Session_OnEnd,
just stuff that would be nice to run whenever it gets run.

=head2 Script_OnFlush

ASP.pm  view on Meta::CPAN


=item $Session->{LCID}

Not implemented.  May never be until someone needs it.

=item $Session->{SessionID}

SessionID property, returns the id for the current session,
which is exchanged between the client and the server as a cookie.

=item $Session->{Timeout} [= $minutes]

Timeout property, if minutes is being assigned, sets this 
default timeout for the user session, else returns 
the current session timeout.  

If a user session is inactive for the full
timeout, the session is destroyed by the system.
No one can access the session after it times out, and the system
garbage collects it eventually.

=item $Session->Abandon()

ASP.pm  view on Meta::CPAN


=head2 $Server Object

The server object is that object that handles everything the other
objects do not.  The best part of the server object for Win32 users is 
the CreateObject method which allows developers to create instances of
ActiveX components, like the ADO component.

=over

=item $Server->{ScriptTimeout} = $seconds

Not implemented. May never be.  Please see the 
Apache Timeout configuration option, normally in httpd.conf.  

=item $Server->Config($setting)

API extension.  Allows a developer to read the CONFIG
settings, like Global, GlobalPackage, StateDir, etc.
Currently implemented as a wrapper around 

  Apache->dir_config($setting)

May also be invoked as $Server->Config(), which will

ASP.pm  view on Meta::CPAN

  on a simple hello world benchmark on a WinNT PII300.

 ++Better SessionManagement, more aware of server farms that 
  don't have reliable NFS locking.  The key here is to have only
  one process on one server in charge of session garbage collection
  at any one time, and try to create this situation with a snazzy
  CleanupMaster routine.  This is done by having a process register
  itself in the internal database with a server key created at
  apache start time.  If this key gets stale, another process can 
  become the master, and this period will not exceed the period
  SessionTimeout / StateManager.

  ** Work on session manager sponsored by LRN, http://www.lrn.com.  **
  ** This work was used to deploy a server farm in production with  **
  ** NFS mounted StateDir. Thanks to Craig Samuel for his belief in **
  ** open source. :)                                                **

  Future work for server farm capabilities might include breaking
  up the internal database into one of 256 internal databases 
  hashed by the first 2 chars of the session id.  Also on the plate
  is Apache::Session like abilities with locking and/or data storage

ASP.pm  view on Meta::CPAN

 +Prettied the error messaging with Debug 2.

 +$Response->Debug(@args) debugging extension, which
  allows a developer to hook into the module's debugging,
  and only have @args be written to error_log when Debug is greater
  than 0.

 -Put write locking code around State writes, like $Session
  and $Application.  I thought I fixed this bug a while ago.

 -API change: converted $Session->Timeout() and $Session->SessionID() 
  methods into $Session->{Timeout} and $Session->{SessionID} properties.
  The use of these properties as methods is deprecated, but 
  backwards compatibility will remain.  Updated ./eg/session.asp
  to use these new properties.

 +Implemented $Response->{PICS} which if set sends out a PICS-Label
  HTTP header, useful for ratings.

 +Implemented $Response->{CacheControl} and $Response->{Charset} members.
  By default, CacheControl is 'private', and this value gets sent out
  every request as HTTP header Cache-Control.  Charset appends itself

ASP.pm  view on Meta::CPAN

 ++global.asa implemented with events Session_OnStart and Session_OnEnd
  working appropriately.

 +StateDir configuration directive implemented.
  StateDir allows the session state directory to be specified separately 
  from the Global directory, useful for operating systems with caching file 
  systems.

 +StateManager config directive.  StateManager specifies how frequently
  Sessions are cleaned up, with 10 (default) meaning that old Sessions
  will be cleaned up 10 times per SessionTimeout period (default 20 minutes).

 +$Application->SessionCount() implemented, non-portable method.
	: returns the number of currently active sessions

 -STOP button fix.  Users may hit STOP button during script 
  execution, and Apache::ASP will cleanup with a routine registered
  in Apache's $r->register_cleanup.  Works well supposedly.

 +PerlScript compatibility work, trying to make ports smoother.
	: Collection emulator, no ->{Count} property

ASP.pm  view on Meta::CPAN

 -----------
 $Session, $Application, $Response, $Request objects available
 for use in asp pages.

 $Session & $Application data is preserved using SDBM files.

 $Session id's are tracked through the use of cookies.

 Security
 --------
 Timeouts any attempt to use a session id that doesn't already 
 exist.  Should stop hackers, since there is no wire speed guessing
 cookies.

=head1 LICENSE

Copyright (c) 1998-2018, Josh Chamas

All rights reserved.  This program is free software; you can 
redistribute it and/or modify it under the same terms as Perl itself.

README  view on Meta::CPAN

        The reason for this config option is to allow operating systems with
        caching file systems like Solaris to specify a state directory
        separately from the Global directory, which contains more permanent
        files. This way one may point StateDir to /tmp/myaspapp, and make one's
        ASP application scream with speed.

          PerlSetVar StateDir ./.state

    StateManager
        default 10, this number specifies the numbers of times per
        SessionTimeout that timed out sessions are garbage collected. The bigger
        the number, the slower your system, but the more precise Session_OnEnd's
        will be run from global.asa, which occur when a timed out session is
        cleaned up, and the better able to withstand Session guessing hacking
        attempts. The lower the number, the faster a normal system will run.

        The defaults of 20 minutes for SessionTimeout and 10 times for
        StateManager, has dead Sessions being cleaned up every 2 minutes.

          PerlSetVar StateManager 10

    StateDB
        default SDBM_File, this is the internal database used for state objects
        like $Application and $Session. Because an SDBM_File %hash has a limit
        on the size of a record key+value pair, usually 1024 bytes, you may want
        to use another tied database like DB_File or MLDBM::Sync::SDBM_File.

README  view on Meta::CPAN

        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
        cookie will only be transmitted by the browser under https
        transmissions.

          PerlSetVar SecureSession 1

    HTTPOnlySession
        default 0. Sets HttpOnly flag to session cookie to mitigate XSS attacks.

README  view on Meta::CPAN

  Session_OnEnd
    Triggered by a user session ending, Session_OnEnd can be useful for cleaning
    up and analyzing user data accumulated during a session.

    Sessions end when the session timeout expires, and the StateManager performs
    session cleanup. The timing of the Session_OnEnd does not occur immediately
    after the session times out, but when the first script runs after the
    session expires, and the StateManager allows for that session to be cleaned
    up.

    So on a busy site with default SessionTimeout (20 minutes) and StateManager
    (10 times) settings, the Session_OnEnd for a particular session should be
    run near 22 minutes past the last activity that Session saw. A site
    infrequently visited will only have the Session_OnEnd run when a subsequent
    visit occurs, and theoretically the last session of an application ever run
    will never have its Session_OnEnd run.

    Thus I would not put anything mission-critical in the Session_OnEnd, just
    stuff that would be nice to run whenever it gets run.

  Script_OnFlush

README  view on Meta::CPAN

    $Session->{CodePage}
        Not implemented. May never be until someone needs it.

    $Session->{LCID}
        Not implemented. May never be until someone needs it.

    $Session->{SessionID}
        SessionID property, returns the id for the current session, which is
        exchanged between the client and the server as a cookie.

    $Session->{Timeout} [= $minutes]
        Timeout property, if minutes is being assigned, sets this default
        timeout for the user session, else returns the current session timeout.

        If a user session is inactive for the full timeout, the session is
        destroyed by the system. No one can access the session after it times
        out, and the system garbage collects it eventually.

    $Session->Abandon()
        The abandon method times out the session immediately. All Session data
        is cleared in the process, just as when any session times out.

README  view on Meta::CPAN

        object model, but is implemented here because it is useful. In
        particular, when accessing databases with license requirements, one can
        monitor usage effectively through accessing this value.

  $Server Object
    The server object is that object that handles everything the other objects
    do not. The best part of the server object for Win32 users is the
    CreateObject method which allows developers to create instances of ActiveX
    components, like the ADO component.

    $Server->{ScriptTimeout} = $seconds
        Not implemented. May never be. Please see the Apache Timeout
        configuration option, normally in httpd.conf.

    $Server->Config($setting)
        API extension. Allows a developer to read the CONFIG settings, like
        Global, GlobalPackage, StateDir, etc. Currently implemented as a wrapper
        around

          Apache->dir_config($setting)

        May also be invoked as $Server->Config(), which will return a hash ref

README  view on Meta::CPAN

          on a simple hello world benchmark on a WinNT PII300.

         ++Better SessionManagement, more aware of server farms that 
          don't have reliable NFS locking.  The key here is to have only
          one process on one server in charge of session garbage collection
          at any one time, and try to create this situation with a snazzy
          CleanupMaster routine.  This is done by having a process register
          itself in the internal database with a server key created at
          apache start time.  If this key gets stale, another process can 
          become the master, and this period will not exceed the period
          SessionTimeout / StateManager.

          ** Work on session manager sponsored by LRN, http://www.lrn.com.  **
          ** This work was used to deploy a server farm in production with  **
          ** NFS mounted StateDir. Thanks to Craig Samuel for his belief in **
          ** open source. :)                                                **

          Future work for server farm capabilities might include breaking
          up the internal database into one of 256 internal databases 
          hashed by the first 2 chars of the session id.  Also on the plate
          is Apache::Session like abilities with locking and/or data storage

README  view on Meta::CPAN

         +Prettied the error messaging with Debug 2.

         +$Response->Debug(@args) debugging extension, which
          allows a developer to hook into the module's debugging,
          and only have @args be written to error_log when Debug is greater
          than 0.

         -Put write locking code around State writes, like $Session
          and $Application.  I thought I fixed this bug a while ago.

         -API change: converted $Session->Timeout() and $Session->SessionID() 
          methods into $Session->{Timeout} and $Session->{SessionID} properties.
          The use of these properties as methods is deprecated, but 
          backwards compatibility will remain.  Updated ./eg/session.asp
          to use these new properties.

         +Implemented $Response->{PICS} which if set sends out a PICS-Label
          HTTP header, useful for ratings.

         +Implemented $Response->{CacheControl} and $Response->{Charset} members.
          By default, CacheControl is 'private', and this value gets sent out
          every request as HTTP header Cache-Control.  Charset appends itself

README  view on Meta::CPAN

         ++global.asa implemented with events Session_OnStart and Session_OnEnd
          working appropriately.

         +StateDir configuration directive implemented.
          StateDir allows the session state directory to be specified separately 
          from the Global directory, useful for operating systems with caching file 
          systems.

         +StateManager config directive.  StateManager specifies how frequently
          Sessions are cleaned up, with 10 (default) meaning that old Sessions
          will be cleaned up 10 times per SessionTimeout period (default 20 minutes).

         +$Application->SessionCount() implemented, non-portable method.
                : returns the number of currently active sessions

         -STOP button fix.  Users may hit STOP button during script 
          execution, and Apache::ASP will cleanup with a routine registered
          in Apache's $r->register_cleanup.  Works well supposedly.

         +PerlScript compatibility work, trying to make ports smoother.
                : Collection emulator, no ->{Count} property

README  view on Meta::CPAN

         -----------
         $Session, $Application, $Response, $Request objects available
         for use in asp pages.

         $Session & $Application data is preserved using SDBM files.

         $Session id's are tracked through the use of cookies.

         Security
         --------
         Timeouts any attempt to use a session id that doesn't already 
         exist.  Should stop hackers, since there is no wire speed guessing
         cookies.

LICENSE
    Copyright (c) 1998-2018, Josh Chamas

    All rights reserved. This program is free software; you can redistribute it
    and/or modify it under the same terms as Perl itself.

    Apache::ASP is a perl native port of Active Server Pages for Apache and

lib/Apache/ASP/Session.pm  view on Meta::CPAN

    my($self, $index) = @_;

    # putting these comparisons in a regexp was a little
    # slower than keeping them in these 'eq' statements
    if($index eq '_SELF') {
	$self;
    } elsif($index eq '_STATE') {
	$self->{state};
    } elsif($index eq 'SessionID') {
	$self->{id};
    } elsif($index eq 'Timeout') {
	$self->Timeout();
    } else {
	$self->{state}->FETCH($index);
    }
}

sub STORE {
    my($self, $index, $value) = @_;
    if($index eq 'Timeout') {
	$self->Timeout($value);
    } else {	
	$self->{state}->STORE($index, $value);
    }
}

# firstkey and nextkey skip the _UA key so the user 
# we need to keep the ua info in the session db itself,
# so we are not dependent on writes going through to Internal
# for this very critical informatioh. _UA is used for security
# validation / the user's user agent.

lib/Apache/ASP/Session.pm  view on Meta::CPAN

    my $rv = $state->CLEAR();
    $ua && $state->STORE('_UA', $ua);
    $rv;
}

sub SessionID {
    my $self = shift;
    tied(%$self)->{id};
}

sub Timeout {
    my($self, $minutes) = @_;

    if(tied(%$self)) {
	$self = tied(%$self);
    }

    if($minutes) {
	$self->{asp}{Internal}->LOCK;
	my($internal_session) = $self->{asp}{Internal}{$self->{id}};
	$internal_session->{refresh_timeout} = $minutes * 60;

lib/Apache/ASP/Session.pm  view on Meta::CPAN

	$self->{asp}{Internal}{$self->{id}} = $internal_session;
	$self->{asp}{Internal}->UNLOCK;
    } else {
	my($refresh) = $self->{asp}{Internal}{$self->{id}}{refresh_timeout};
	$refresh ||= $self->{asp}{session_timeout};
	$refresh / 60;
    }
}    

sub Abandon {
    shift->Timeout(-1);
}

sub TTL {
    my $self = shift;
    $self = tied(%$self);
    # time to live is current timeout - time... positive means
    # session is still active, returns ttl in seconds
    my $timeout = $self->{asp}{Internal}{$self->{id}}{timeout};
    my $ttl = $timeout - time();
}

lib/Apache/ASP/StateManager.pm  view on Meta::CPAN

package Apache::ASP;

# quickly decomped out of Apache::ASP so we could load the routines only
# when we are managing State objects

use Apache::ASP::State;

use strict;
use vars qw(
  $CleanupGroups
 $SessionIDLength $SessionTimeout $StateManager
  $DefaultStateDB $DefaultStateSerializer
);

$SessionTimeout = 20;
$StateManager   = 10;

# Some OS's have hashed directory lookups up to 16 bytes, so we leave room
# for .lock extension ... nevermind, security is more important, back to 32
# $SessionIDLength = 11;
$SessionIDLength = 32;
$DefaultStateDB = 'SDBM_File';
$DefaultStateSerializer = 'Data::Dumper';

sub InitState {

lib/Apache/ASP/StateManager.pm  view on Meta::CPAN

	$self->{session_url_parse_match} = &config($self, 'SessionQueryParseMatch');
	$self->{session_url_parse} = $self->{session_url_parse_match} || &config($self, 'SessionQueryParse');
	$self->{session_url_match} = $self->{session_url_parse_match} || &config($self, 'SessionQueryMatch');
	$self->{session_url} = $self->{session_url_parse} || $self->{session_url_match} || &config($self, 'SessionQuery');
	$self->{session_url_force} = &config($self, 'SessionQueryForce');
	
	$self->{session_serialize} = &config($self, 'SessionSerialize');
	$self->{secure_session}    = &config($self, 'SecureSession');
	$self->{http_only_session} = &config($self, 'HTTPOnlySession');
	# session timeout in seconds since that is what we work with internally
	$self->{session_timeout}   = &config($self, 'SessionTimeout', undef, $SessionTimeout) * 60;
	$self->{'ua'}              = $self->{headers_in}->get('User-Agent') || 'UNKNOWN UA';
	# refresh group by some increment smaller than session timeout
	# to withstand DoS, bruteforce guessing attacks
	# defaults to checking the group once every 2 minutes
	$self->{group_refresh}     = int($self->{session_timeout} / $self->{state_manager});
	
	# Session state is dependent on internal state

	# load at runtime for CGI environments, preloaded for mod_perl
	require Apache::ASP::Session;

lib/Apache/ASP/StateManager.pm  view on Meta::CPAN

    $self->{Response}->IsClientConnected();

    # POSTPOSE STATE EVENTS, so we can delay the Response object creation
    # until after the state objects are created
    if($session) {
	my $last_session_timeout;
	if($session->Started()) {
	    # we only want one process purging at a time
	    if($self->{app_state}) {
		$internal->LOCK();
		if(($last_session_timeout = $internal->{LastSessionTimeout} || 0) < time()) {
		    $internal->{'LastSessionTimeout'} = $self->{session_timeout} + time;
		    $internal->UNLOCK();
		    $self->{Application}->Lock;
		    my $obj = tied(%{$self->{Application}});
		    if($self->CleanupGroups('PURGE')) {
			$last_session_timeout && $global_asa->ApplicationOnEnd();
			$global_asa->ApplicationOnStart();
		    }
		    $self->{Application}->UnLock;
		} 
		$internal->UNLOCK();
	    }
	    $global_asa->SessionOnStart();
	}

	if($self->{app_state}) {
	    # The last session timeout should only be updated every group_refresh period
	    # another optimization, rand() so not all at once either
	    $internal->LOCK();
	    $last_session_timeout ||= $internal->{'LastSessionTimeout'};
	    if($last_session_timeout < $self->{session_timeout} + time + 
	       (rand() * $self->{group_refresh} / 2)) 
	      {
		  $self->{dbg} && $self->Debug("updating LastSessionTimeout from $last_session_timeout");
		  $internal->{'LastSessionTimeout'} = 
		    $self->{session_timeout} + time() + $self->{group_refresh};
	      }
	    $internal->UNLOCK();
	}
    }

    $self;
}

# Cleanup a state group, by default the group of the current session

site/apps/bookmarks/.htaccess  view on Meta::CPAN

DirectoryIndex index.asp
<Files ~ \.asp$>
	SetHandler perl-script
	PerlHandler Apache::ASP
	PerlSetVar Global .
	PerlSetVar GlobalPackage My::Bookmarks
	PerlSetVar StateDir /tmp/asp_apps_bookmarks
	PerlSetVar Debug 2
	PerlSetVar SessionTimeout 15
	PerlSetVar StatScripts On
	PerlSetVar AllowApplicationState On
	PerlSetVar AllowSessionState On
	PerlSetVar TimeHiRes On
</Files>

site/articles/perlmonth1_intro.html  view on Meta::CPAN

set of objects and events, my favorite being $Session, which was one of ASP's
key selling points for me.  $Session is ASP's answer to the problem of HTTP being a 
stateless protocol.  By using temporary session cookies, each web user 
has a unique $Session in which you may store data, and that follows them from
script to script. Because the data storage
for $Session is handled on the server, you do not have to worry about
size limits of cookies as an alternate mechanism of storing user session data.
<p>
There are some very useful events as well.  Let's say that you are
using <tt>$Session->{login}</tt> to control a user account login and logout.  Because
$Session automatically times out every SessionTimeout, if a user
walks away from her/his computer for SessionTimeout minutes, the
<tt>$Session->{login}</tt> is destroyed along with the rest of the data stored in 
$Session, and the next person that uses the computer will find themselves
automatically logged out from the account.  This is a huge security win if 
you maintain a set of accounts at your web site that hold sensitive information like
credit card numbers.
<p>
Here is a basic listing of the built-in <a href=http://www.apache-asp.org/objects.html>objects</a> 
available to the developer within every <a href=http://www.apache-asp.org>Apache::ASP</a>
script:
<pre>

site/articles/perlmonth2_build.html  view on Meta::CPAN

first user's bookmarks. 
<p>

<h3>Specification</h3>
Often times, there is a specification round that we
must do to pick our web application environment and 
hardware, as well as supported client software, but this is a no 
brainer here.  We are choosing Apache::ASP because of its built 
in <tt>$Session</tt> which make user logins easy, and its built 
in event <tt>Session_OnEnd</tt> which will automatically destroy 
the contents of <tt>$Session</tt> every <tt>SessionTimeout</tt>, which 
defaults to 20 minutes.
<p>
Also, because our web application has more than one page, we 
will make use of the same headers and footers for each
page, using the includes <tt>&lt;!--#include file=src.inc--&gt;</tt>
functionality to modularize the html.

<h3>Design</h3>
Before we start coding, let's take a minute to diagram
what pages and actions our MyBookmarks web application 

site/articles/perlmonth2_build.html  view on Meta::CPAN

	<tr bgcolor=gray><td><font color=white><b># .htaccess</b></td></tr>
	<tr bgcolor=#c0c0c0><td><pre>
<tt>DirectoryIndex index.asp
&lt;Files ~ \.asp$&gt;
	SetHandler perl-script
	PerlHandler Apache::ASP
	PerlSetVar Global .
	PerlSetVar GlobalPackage My::Bookmarks
	PerlSetVar StateDir /tmp/asp_apps_bookmarks
	PerlSetVar Debug 2
	PerlSetVar SessionTimeout 15
	PerlSetVar StatScripts 1
	PerlSetVar AllowApplicationState 1
	PerlSetVar AllowSessionState 1
&lt;/Files&gt;</tt></pre></td></tr>
	</table>
	</center>
	<p>
	

	<p>

site/articles/perlmonth3_tune.html  view on Meta::CPAN

	<td bgcolor=#c0c0c0>My::Bookmarks</td>
	</tr>

	<tr>
	<td bgcolor=#c0c0c0>SessionSerialize</td>
	<td bgcolor=#c0c0c0>0</td>
	<td bgcolor=#c0c0c0>0</td>
	</tr>

	<tr>
	<td bgcolor=#c0c0c0>SessionTimeout</td>
	<td bgcolor=#c0c0c0>15</td>
	<td bgcolor=#c0c0c0>15</td>
	</tr>

	<tr>
	<td bgcolor=pink>StateDir</td>
	<td bgcolor=pink>.state</td>
	<td bgcolor=pink>/tmp/bookmarks</td>
	</tr>

site/articles/perlmonth3_tune.html  view on Meta::CPAN

	<td bgcolor=#c0c0c0>My::Bookmarks</td>
	</tr>

	<tr>
	<td bgcolor=#c0c0c0>SessionSerialize</td>
	<td bgcolor=#c0c0c0>0</td>
	<td bgcolor=#c0c0c0>0</td>
	</tr>

	<tr>
	<td bgcolor=#c0c0c0>SessionTimeout</td>
	<td bgcolor=#c0c0c0>15</td>
	<td bgcolor=#c0c0c0>15</td>
	</tr>

	<tr>
	<td bgcolor=#c0c0c0>StateDir</td>
	<td bgcolor=#c0c0c0>/tmp/bookmarks</td>
	<td bgcolor=#c0c0c0>/tmp/bookmarks</td>
	</tr>

site/articles/perlmonth3_tune.html  view on Meta::CPAN

	<td bgcolor=#c0c0c0>My::Bookmarks</td>
	</tr>

	<tr>
	<td bgcolor=#c0c0c0>SessionSerialize</td>
	<td bgcolor=#c0c0c0>0</td>
	<td bgcolor=#c0c0c0>0</td>
	</tr>

	<tr>
	<td bgcolor=#c0c0c0>SessionTimeout</td>
	<td bgcolor=#c0c0c0>15</td>
	<td bgcolor=#c0c0c0>15</td>
	</tr>

	<tr>
	<td bgcolor=#c0c0c0>StateDir</td>
	<td bgcolor=#c0c0c0>/tmp/bookmarks</td>
	<td bgcolor=#c0c0c0>/tmp/bookmarks</td>
	</tr>

site/articles/perlmonth3_tune.html  view on Meta::CPAN

	<td bgcolor=#c0c0c0>My::Bookmarks</td>
	</tr>

	<tr>
	<td bgcolor=#c0c0c0>SessionSerialize</td>
	<td bgcolor=#c0c0c0>0</td>
	<td bgcolor=#c0c0c0>0</td>
	</tr>

	<tr>
	<td bgcolor=#c0c0c0>SessionTimeout</td>
	<td bgcolor=#c0c0c0>15</td>
	<td bgcolor=#c0c0c0>15</td>
	</tr>

	<tr>
	<td bgcolor=#c0c0c0>StateDir</td>
	<td bgcolor=#c0c0c0>/tmp/bookmarks</td>
	<td bgcolor=#c0c0c0>/tmp/bookmarks</td>
	</tr>

site/articles/perlmonth3_tune.html  view on Meta::CPAN

	<td bgcolor=#c0c0c0>My::Bookmarks</td>
	</tr>

	<tr>
	<td bgcolor=pink>SessionSerialize</td>
	<td bgcolor=pink>0</td>
	<td bgcolor=pink>1</td>
	</tr>

	<tr>
	<td bgcolor=#c0c0c0>SessionTimeout</td>
	<td bgcolor=#c0c0c0>15</td>
	<td bgcolor=#c0c0c0>15</td>
	</tr>

	<tr>
	<td bgcolor=#c0c0c0>StateDir</td>
	<td bgcolor=#c0c0c0>/tmp/bookmarks</td>
	<td bgcolor=#c0c0c0>/tmp/bookmarks</td>
	</tr>

site/articles/perlmonth3_tune.html  view on Meta::CPAN

	<td bgcolor=#c0c0c0>My::Bookmarks</td>
	</tr>

	<tr>
	<td bgcolor=pink>SessionSerialize</td>
	<td bgcolor=pink>0</td>
	<td bgcolor=pink>1</td>
	</tr>

	<tr>
	<td bgcolor=#c0c0c0>SessionTimeout</td>
	<td bgcolor=#c0c0c0>15</td>
	<td bgcolor=#c0c0c0>15</td>
	</tr>

	<tr>
	<td bgcolor=pink>StateDir</td>
	<td bgcolor=pink>.state</td>
	<td bgcolor=pink>/tmp/bookmarks</td>
	</tr>

site/changes.html  view on Meta::CPAN

  on a simple hello world benchmark on a WinNT PII300.

 ++Better SessionManagement, more aware of server farms that 
  don&#39;t have reliable NFS locking.  The key here is to have only
  one process on one server in charge of session garbage collection
  at any one time, and try to create this situation with a snazzy
  CleanupMaster routine.  This is done by having a process register
  itself in the internal database with a server key created at
  apache start time.  If this key gets stale, another process can 
  become the master, and this period will not exceed the period
  SessionTimeout / StateManager.

  ** Work on session manager sponsored by LRN, <a href=http://www.lrn.com>http://www.lrn.com</a>.  **
  ** This work was used to deploy a server farm in production with  **
  ** NFS mounted StateDir. Thanks to Craig Samuel for his belief in **
  ** open source. :)                                                **

  Future work for server farm capabilities might include breaking
  up the internal database into one of 256 internal databases 
  hashed by the first 2 chars of the session id.  Also on the plate
  is Apache::Session like abilities with locking and/or data storage

site/changes.html  view on Meta::CPAN

 +Prettied the error messaging with Debug 2.

 +$Response-&gt;Debug(@args) debugging extension, which
  allows a developer to hook into the module&#39;s debugging,
  and only have @args be written to error_log when Debug is greater
  than 0.

 -Put write locking code around State writes, like $Session
  and $Application.  I thought I fixed this bug a while ago.

 -API change: converted $Session-&gt;Timeout() and $Session-&gt;SessionID() 
  methods into $Session-&gt;{Timeout} and $Session-&gt;{SessionID} properties.
  The use of these properties as methods is deprecated, but 
  backwards compatibility will remain.  Updated ./eg/session.asp
  to use these new properties.

 +Implemented $Response-&gt;{PICS} which if set sends out a PICS-Label
  HTTP header, useful for ratings.

 +Implemented $Response-&gt;{CacheControl} and $Response-&gt;{Charset} members.
  By default, CacheControl is &#39;private&#39;, and this value gets sent out
  every request as HTTP header Cache-Control.  Charset appends itself

site/changes.html  view on Meta::CPAN

 ++global.asa implemented with events Session_OnStart and Session_OnEnd
  working appropriately.

 +StateDir configuration directive implemented.
  StateDir allows the session state directory to be specified separately 
  from the Global directory, useful for operating systems with caching file 
  systems.

 +StateManager config directive.  StateManager specifies how frequently
  Sessions are cleaned up, with 10 (default) meaning that old Sessions
  will be cleaned up 10 times per SessionTimeout period (default 20 minutes).

 +$Application-&gt;SessionCount() implemented, non-portable method.
	: returns the number of currently active sessions

 -STOP button fix.  Users may hit STOP button during script 
  execution, and Apache::ASP will cleanup with a routine registered
  in Apache&#39;s $r-&gt;register_cleanup.  Works well supposedly.

 +PerlScript compatibility work, trying to make ports smoother.
	: Collection emulator, no -&gt;{Count} property

site/changes.html  view on Meta::CPAN

 -----------
 $Session, $Application, $Response, $Request objects available
 for use in asp pages.

 $Session &amp; $Application data is preserved using SDBM files.

 $Session id&#39;s are tracked through the use of cookies.

 Security
 --------
 Timeouts any attempt to use a session id that doesn&#39;t already 
 exist.  Should stop hackers, since there is no wire speed guessing
 cookies.
</pre></font>
	

</font>
</td>

<td bgcolor=white valign=top>
&nbsp;

site/config.html  view on Meta::CPAN

			<a href=#StatINC>StatINC</a>
			</font>
			</td>
							
		</tr>
		
		<tr>
		
			<td valign=top >
			<font face="lucida console" size=-1>
			<a href=#SessionTimeo21fc354e>SessionTimeout</a>
			</font>
			</td>
		
			<td valign=top >
			<font face="lucida console" size=-1>
			<a href=#StatINCMatch>StatINCMatch</a>
			</font>
			</td>
							
		</tr>

site/config.html  view on Meta::CPAN

This way one may point StateDir to /tmp/myaspapp, and make one&#39;s ASP
application scream with speed.
<font face="courier new" size=3><pre>
  PerlSetVar StateDir ./.state
</pre></font>
	
	<p>
	<a name=StateManager></a>
	<font face=verdana><font class=title size=-1 color=#555555><b>StateManager</b></font>
<font face="courier new" size=3><pre>
</pre></font>default 10, this number specifies the numbers of times per SessionTimeout
that timed out sessions are garbage collected.  The bigger the number,
the slower your system, but the more precise Session_OnEnd&#39;s will be 
run from global.asa, which occur when a timed out session is cleaned up,
and the better able to withstand Session guessing hacking attempts.
The lower the number, the faster a normal system will run.  
<font face="courier new" size=3><pre>
</pre></font>The defaults of 20 minutes for SessionTimeout and 10 times for 
StateManager, has dead Sessions being cleaned up every 2 minutes.
<font face="courier new" size=3><pre>
  PerlSetVar StateManager 10
</pre></font>
	
	<p>
	<a name=StateDB></a>
	<font face=verdana><font class=title size=-1 color=#555555><b>StateDB</b></font>
<font face="courier new" size=3><pre>
</pre></font>default SDBM_File, this is the internal database used for state

site/config.html  view on Meta::CPAN

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&#39;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>
  PerlSetVar SessionTimeout 20
</pre></font>
	
	<p>
	<a name=SecureSessio77114c01></a>
	<font face=verdana><font class=title size=-1 color=#555555><b>SecureSession</b></font>
<font face="courier new" size=3><pre>
</pre></font>default 0.  Sets the secure tag for the session cookie, so that the cookie
will only be transmitted by the browser under https transmissions.
<font face="courier new" size=3><pre>
  PerlSetVar SecureSession 1

site/eg/.htaccess  view on Meta::CPAN

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>

# .htm files for the ASP parsing, but not the $Session object

site/eg/.htaccess  view on Meta::CPAN

       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/session.asp  view on Meta::CPAN

#!/usr/bin/perl /usr/bin/asp-perl

<%
    my $form = $Request->Form();

# process form here
if($form->{increment}) {
    $Session->{Count}++;
} elsif($form->{timeout}) {
    $Session->Timeout(.25);
} elsif($form->{abandon}) {
    $Session->Abandon();
}

my @rows = (
	 '$Session->{Count}',
	 '$Session->{Timeout}',
	 '$Session->{SessionID}'
	 );
%>
<!--#include file=header.inc-->

This file demonstrates the use of the $Session object, as well
as one implementantion of cookieless sessions involving the 
use of the SessionQuery setting, and the <nobr>$Server->URL($url, \%params)</nobr>
method to add session ids to the form query string.
<p>
To demo the cookieless sessions, just turn off your cookies
and use this form.
<p>
<center>
<table border=1>
<tr><td colspan=2 align=center><b>Session Object Demonstration</b></td></tr>
<form action=<%=$Server->URL($demo->{file})%> method=POST>
<tr>
	<td colspan=2 align=center>
	<input type=submit name=increment value="Increment Count">
	<input type=submit name=timeout   value="Timeout 15 Seconds">
	<input type=submit name=abandon   value="Abandon">
	<td>
</tr>
</form>
<% for (@rows){ %>
	<tr>
		<td><tt><%=$Server->HTMLEncode($_)%></tt></td>		 
		<td><%=eval($_) || $@%></td>
	</tr>
<% } %>

site/events.html  view on Meta::CPAN

<font face="courier new" size=3><pre>
</pre></font>Triggered by a user session ending, Session_OnEnd can be useful
for cleaning up and analyzing user data accumulated during a session.
<font face="courier new" size=3><pre>
</pre></font>Sessions end when the session timeout expires, and the StateManager
performs session cleanup.  The timing of the Session_OnEnd does not
occur immediately after the session times out, but when the first 
script runs after the session expires, and the StateManager allows
for that session to be cleaned up.  
<font face="courier new" size=3><pre>
</pre></font>So on a busy site with default SessionTimeout (20 minutes) and 
StateManager (10 times) settings, the Session_OnEnd for a particular 
session should be run near 22 minutes past the last activity that Session saw.
A site infrequently visited will only have the Session_OnEnd run
when a subsequent visit occurs, and theoretically the last session
of an application ever run will never have its Session_OnEnd run.
<font face="courier new" size=3><pre>
</pre></font>Thus I would not put anything mission-critical in the Session_OnEnd,
just stuff that would be nice to run whenever it gets run.</font>
	
	<p>

site/objects.html  view on Meta::CPAN

			<a href=#%24Request-%3E%7BM81641f4a>$Request->{Method}</a>
			</font>
			</td>
							
		</tr>
		
		<tr>
		
			<td valign=top >
			<font face="lucida console" size=-1>
			<a href=#%24Session-%3E%7BTf539b225>$Session->{Timeout} [= $minutes]</a>
			</font>
			</td>
		
			<td valign=top >
			<font face="lucida console" size=-1>
			<a href=#%24Request-%3E%7BT6acbcf5a>$Request->{TotalBytes}</a>
			</font>
			</td>
							
		</tr>

site/objects.html  view on Meta::CPAN

		<tr>
		
			<td valign=top >
			<font face="lucida console" size=-1>
			<a href=#%24Response-%3E%7Bc48a3e9e>$Response->{PICS}</a>
			</font>
			</td>
		
			<td valign=top >
			<font face="lucida console" size=-1>
			<a href=#%24Server-%3E%7BSc74a89b4a>$Server->{ScriptTimeout} = $seconds</a>
			</font>
			</td>
							
		</tr>
		
		<tr>
		
			<td valign=top >
			<font face="lucida console" size=-1>
			<a href=#%24Response-%3E%7B7098f2f6>$Response->{Status} = $status</a>

site/objects.html  view on Meta::CPAN

	
	<p>
	<a name=%24Session-%3E%7BS1049f4e8></a>
	<font face=verdana><font class=title size=-1 color=#555555><b>$Session->{SessionID}</b></font>
<font face="courier new" size=3><pre>
</pre></font>SessionID property, returns the id for the current session,
which is exchanged between the client and the server as a cookie.</font>
	
	<p>
	<a name=%24Session-%3E%7BTf539b225></a>
	<font face=verdana><font class=title size=-1 color=#555555><b>$Session->{Timeout} [= $minutes]</b></font>
<font face="courier new" size=3><pre>
</pre></font>Timeout property, if minutes is being assigned, sets this 
default timeout for the user session, else returns 
the current session timeout.  
<font face="courier new" size=3><pre>
</pre></font>If a user session is inactive for the full
timeout, the session is destroyed by the system.
No one can access the session after it times out, and the system
garbage collects it eventually.</font>
	
	<p>
	<a name=%24Session-%3EAbc5f4cea0></a>

site/objects.html  view on Meta::CPAN

	<a name=%24Server%20Objeed08cf85></a>
	<font face=verdana><font class=title size=+0 color=#555555><b>$Server Object</b></font>
<font face="courier new" size=3><pre>
</pre></font>The server object is that object that handles everything the other
objects do not.  The best part of the server object for Win32 users is 
the CreateObject method which allows developers to create instances of
ActiveX components, like the ADO component.</font>
	
	<p>
	<a name=%24Server-%3E%7BSc74a89b4a></a>
	<font face=verdana><font class=title size=-1 color=#555555><b>$Server->{ScriptTimeout} = $seconds</b></font>
<font face="courier new" size=3><pre>
</pre></font>Not implemented. May never be.  Please see the 
Apache Timeout configuration option, normally in httpd.conf.</font>
	
	<p>
	<a name=%24Server-%3ECon7d9785f8></a>
	<font face=verdana><font class=title size=-1 color=#555555><b>$Server->Config($setting)</b></font>
<font face="courier new" size=3><pre>
</pre></font>API extension.  Allows a developer to read the <a href=config.html><font size=-1 face=verdana><b>CONFIG</b></font></a>
settings, like Global, GlobalPackage, StateDir, etc.
Currently implemented as a wrapper around 
<font face="courier new" size=3><pre>
  Apache-&gt;dir_config($setting)

t/session.inc  view on Meta::CPAN

<%
eval { $Session->Lock };
$t->eok($Session->Timeout > 1, "timeout check > 1");
$t->eok($Session->{Timeout} > 1, "timeout check > 1");
$t->eok(! $@, "\$Session->Lock: $@");
$t->eok(length($Session->{SessionID}) >= 8, "session id not long enough");
my $count = 0;
for(1..3) {
	$Session->{count}++;
	$count++;
	$t->eok($count == $Session->{count}, 
		'failure to increment $Session->{count}');
}
eval { $Session->UnLock() };

t/session_events.t  view on Meta::CPAN


$0 =~ /^(.*)$/;
$0 = $1;
chdir(dirname($0));
$0 = basename($0);

my $t = T->new();

my %config = (
	      'NoState' => 0,
	      'SessionTimeout' => 20,
	      'Debug' => 0,
	      'SessionCount' => 1,
	      'Global' => 'session_events',
	      'SessionQuery' => 1,
	      );

my $r = Apache::ASP::CGI->init($0);
map { $r->dir_config->set($_, $config{$_}) } keys %config;

my $ASP = Apache::ASP->new($r);



( run in 1.054 second using v1.01-cache-2.11-cpan-a5abf4f5562 )