Apache-ASP
view release on metacpan or search on metacpan
lib/Apache/ASP/StateManager.pm view on Meta::CPAN
join(", ", keys %Apache::ASP::State::DB));
$self->{state_db} =~ /^(.*)$/; # untaint
$self->{state_db} = $1; # untaint
# load the state database module && serializer
$self->LoadModule('StateDB', $self->{state_db});
}
if($self->{state_serializer} = &config($self, 'StateSerializer')) {
$self->{state_serializer} =~ tr///; # untaint
$self->LoadModule('StateSerializer', $self->{state_serializer});
}
# INTERNAL tie to the application internal info
my %Internal;
tie(%Internal, 'Apache::ASP::State', $self, 'internal', 'server')
|| $self->Error("can't tie to internal state");
my $internal = $self->{Internal} = bless \%Internal, 'Apache::ASP::State';
$self->{state_serialize} && $internal->LOCK;
# APPLICATION create application object
$self->{app_state} = &config($self, 'AllowApplicationState', undef, 1);
if($self->{app_state}) {
# load at runtime for CGI environments, preloaded for mod_perl
require Apache::ASP::Application;
($self->{Application} = &Apache::ASP::Application::new($self))
|| $self->Error("can't get application state");
$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');
$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;
$session = $self->{Session} = &Apache::ASP::Session::new($self)
|| $self->Die("can't create session");
$self->{state_serialize} && $session->Lock();
} else {
$self->{dbg} && $self->Debug("no sessions allowed config");
}
# update after long state init, possible with SessionSerialize config
$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;
( run in 0.853 second using v1.01-cache-2.11-cpan-39bf76dae61 )