Apache-SessionManager

 view release on metacpan or  search on metacpan

SessionManager.pm  view on Meta::CPAN

}

sub handler {
	my $r = shift;
	my (%session_config,%session,$session_id,%cookie_options);

	return (MP2 ? Apache::DECLINED : Apache::Constants::DECLINED) unless $r->is_initial_req;

	my $debug_prefix = '[' . $r->connection->remote_ip . "] SessionManager ($$): ";
	$session_config{'SessionManagerDebug'} = $r->dir_config('SessionManagerDebug') || 0;
	foreach ( qw/SessionManagerURITracking SessionManagerTracking SessionManagerEnableModBackhand 
		          SessionManagerStoreArgs SessionManagerCookieArgs SessionManagerSetEnv SessionManagerExpire 
		          SessionManagerHeaderExclude SessionManagerIPExclude/ ) {
		$session_config{$_} = $r->dir_config($_);
	}

	$r->log_error($debug_prefix . '---START REQUEST: ' .  $r->uri . ' ---') if $session_config{'SessionManagerDebug'} > 0;
	#print STDERR "$debug_prefix ---START REQUEST: " .  $r->uri . " ---\n" if $session_config{'SessionManagerDebug'} > 0;

	# Get and remove session ID from URI
	if ( $session_config{'SessionManagerURITracking'} eq 'On' ) {
		$r->log_error($debug_prefix . 'start URI ' . $r->uri) if $session_config{'SessionManagerDebug'} > 0;
		#print STDERR "$debug_prefix start URI " . $r->uri . "\n" if $session_config{'SessionManagerDebug'} > 0;
	
		# retrieve session ID from URL (or HTTP 'Referer:' header)
		my (undef, $uri_session_id, $rest) = split /\/+/, $r->uri, 3;

		if ( $uri_session_id =~ /^[0-9a-h]+$/ ) {
			$session_id = $uri_session_id;
			# Remove the session from the URI
			$r->uri("/$rest");
			$r->log_error($debug_prefix . 'end URI ' . $r->uri) if $session_config{'SessionManagerDebug'} > 0;
			#print STDERR "$debug_prefix end URI " . $r->uri . "\n" if $session_config{'SessionManagerDebug'} > 0;
		}
	}
	
	# declines each request if session manager is off
	return (MP2 ? Apache::DECLINED : Apache::Constants::DECLINED) unless ( $session_config{'SessionManagerTracking'} eq 'On' );

	# declines requests matching IP exclusion list
	if ( $session_config{'SessionManagerIPExclude'} ) {
		require Socket;
		foreach ( split(/\s+/,$session_config{'SessionManagerIPExclude'}) ) {
			$r->log_error($debug_prefix . '_isInRange(' . $r->connection->remote_ip . ",$_)") if $session_config{'SessionManagerDebug'} >= 5;
			#print STDERR "$debug_prefix _isInRange(" . $r->connection->remote_ip . ",$_)\n" if $session_config{'SessionManagerDebug'} >= 5;
			return (MP2 ? Apache::DECLINED : Apache::Constants::DECLINED) if _isInRange($r->connection->remote_ip,$_); 
		}
	}

	# declines requests matching any of exclusions headers
	foreach my $header ( $r->dir_config->get('SessionManagerHeaderExclude') ) {
		my ($key,$value) = split(/\s*=\s*>\s*/,$header,2);
		# Header and its value must exists in order to check it
		next unless ($r->headers_in->{$key} && $value);
		if ( $r->headers_in->{$key} =~ /$value/i ) {
			return (MP2 ? Apache::DECLINED : Apache::Constants::DECLINED)
		}
	}

	# Set exclusion extension(s)
	$session_config{'SessionManagerItemExclude'} = $r->dir_config('SessionManagerItemExclude') || '(\.gif|\.jpe?g|\.png|\.mpe?g|\.css|\.js|\.txt|\.mp3|\.wav|\.swf|\.avi|\.au|\.ra?m)$';

	# declines requests if resource type is to exlcude
	return (MP2 ? Apache::DECLINED : Apache::Constants::DECLINED) if ( $r->uri =~ /$session_config{'SessionManagerItemExclude'}/i );

	$session_config{'SessionManagerStore'} = $r->dir_config('SessionManagerStore') || 'File';
	$session_config{'SessionManagerLock'} = $r->dir_config('SessionManagerLock') || 'Null';
	$session_config{'SessionManagerGenerate'} = $r->dir_config('SessionManagerGenerate') || 'MD5';
	$session_config{'SessionManagerSerialize'} = $r->dir_config('SessionManagerSerialize') || 'Storable';
	$session_config{'SessionManagerExpire'} = 
		$session_config{'SessionManagerExpire'} =~ /^(none|no|disabed)$/i ? 0 
		: $session_config{'SessionManagerExpire'} !~ /^\d+$/ ? 3600
		: $session_config{'SessionManagerExpire'};
	$session_config{'SessionManagerInactivity'} = ( $r->dir_config('SessionManagerInactivity') =~ /^\d+$/ ) ? $r->dir_config('SessionManagerInactivity') : undef;
	$session_config{'SessionManagerName'} = $r->dir_config('SessionManagerName') || 'PERLSESSIONID';

	# Print SesssionManager configs to error_log
	if ( $session_config{'SessionManagerDebug'} >= 3 ) {
		$r->log_error($debug_prefix . 'configuration settings:');
		#print STDERR "$debug_prefix configuration settings\n";
		foreach (sort keys %session_config)	{
			$r->log_error($debug_prefix . ' ' x 8 . "$_ = $session_config{$_}");
			#print STDERR "\t$_ = $session_config{$_}\n";
		}
	}

	# Get session ID from cookie
	unless ( $session_config{'SessionManagerURITracking'} eq 'On' ) {

		if ( $libapreq ) {
			# Test libapreq 1 or 2 version to use correct 'fetch' API
			my %cookies = $Apache::Request::VERSION >= 2 ? Apache::Cookie->fetch($r) : Apache::Cookie->fetch;
			$session_id = $cookies{$session_config{'SessionManagerName'}}->value if defined $cookies{$session_config{'SessionManagerName'}};
			$r->log_error($debug_prefix . 'Apache::Cookie fetch') if $session_config{'SessionManagerDebug'} >= 5;
			#print STDERR "$debug_prefix Apache::Cookie fetch\n" if $session_config{'SessionManagerDebug'} >= 5;
		}
		# Fetch cookies with CGI::Cookie				
		else {
			# At this phase (HeaderParser | Translation), no $ENV{'COOKIE'} var is set, so we use CGI::Cookie parse method by passing 'Cookie' HTTP header
			my %cookies = CGI::Cookie->parse($r->headers_in->{'Cookie'});
			$session_id = $cookies{$session_config{'SessionManagerName'}}->value if defined $cookies{$session_config{'SessionManagerName'}};
			$r->log_error($debug_prefix . 'CGI::Cookie fetch') if $session_config{'SessionManagerDebug'} >= 5;
			#print STDERR "$debug_prefix CGI::Cookie fetch\n" if $session_config{'SessionManagerDebug'} >= 5;
		}
	}

	# Prepare Apache::Session::Flex options parameters call
	my %apache_session_flex_options = (
		Store     => $session_config{'SessionManagerStore'},
		Lock      => $session_config{'SessionManagerLock'},
		Generate  => $session_config{'SessionManagerGenerate'},
		Serialize => $session_config{'SessionManagerSerialize'}
	); 

	# Load session data store specific parameters
	foreach my $arg ( split(/\s*,\s*/,$session_config{'SessionManagerStoreArgs'}) ) {
		my ($key,$value) = split(/\s*=\s*>\s*/,$arg);
		$apache_session_flex_options{$key} = $value;
	}

	if ( $session_config{'SessionManagerDebug'} >= 5 ) {

SessionManager.pm  view on Meta::CPAN


in order to use L<Apache::Session::SharedMem|Apache::Session::SharedMem> to
store sessions in RAM (but you must install
L<Apache::Session::SharedMem|Apache::Session::SharedMem>  before!)

The default value is C<File>.

=item C<SessionManagerLock> Null|MySQL|Semaphore|File

This single directive set lock manager for
L<Apache::Session::Flex|Apache::Session::Flex>. The default value is C<Null>.

=item C<SessionManagerGenerate> MD5|ModUniqueId|ModUsertrack

This single directive set session ID generator for
L<Apache::Session::Flex|Apache::Session::Flex>. The default value is C<MD5>.

=item C<SessionManagerSerialize> Storable|Base64|UUEncode

This single directive set serializer for
L<Apache::Session::Flex|Apache::Session::Flex>. The default value is
C<Storable>.

=item C<SessionManagerStoreArgs>

With this directive you must provide whatever arguments are expected by the
backing store and lock manager  that you've chosen. The arguments are passed as
comma-separated  list of name/value pairs.

For instance if you use File for your datastore, you need to pass store and
lock directories:

   PerlSetVar SessionManagerStoreArgs "Directory     => /tmp/apache_sessions, \
                                       LockDirectory => /tmp/apache_sessions/lock"

If you use MySQL for your datastore, you need to pass database connection
informations:

   PerlSetVar SessionManagerStoreArgs "DataSource => dbi:mysql:sessions, \
                                       UserName   => user, \
                                       Password   => password" 

Please see the documentation for store/lock modules in order to pass right
arguments.

=item C<SessionManagerItemExclude> string|regex

This single directive defines the exclusion string. For example:

   PerlSetVar SessionManagerItemExclude exclude_string

All the HTTP requests containing the 'exclude_string' string in the URI will be
declined. Also is possible to use regex:

   PerlSetVar SessionManagerItemExclude "\.m.*$"

and all the request (URI) ending by ".mpeg", ".mpg" or ".mp3" will be declined.

If C<SessionManagerItemExclude> isn't defined, the default value is:

C<(\.gif|\.jpe?g|\.png|\.mpe?g|\.css|\.js|\.txt|\.mp3|\.wav|\.swf|\.avi|\.au|\.ra?m)$>

B<Note> If you want process each request, you can set
C<SessionManagerItemExclude> with:

   PerlSetVar SessionManagerItemExclude "^$"

=item C<SessionManagerHeaderExclude>

This directive allows to define HTTP headers contents in order to decline
requests that match them. For example:

   PerlSetVar SessionManagerHeaderExclude "User-Agent => SomeBot"

All the HTTP requests containing the 'SomeBot' string in the HTTP C<User-Agent>
header will be declined. Also is possible to use regex:

   PerlSetVar SessionManagerHeaderExclude "User-Agent => SomeBot\s*/\*\d+\.\d+"

All HTTP headers are available (case sensitive) to use in the exclusion rules.

In order to set more than one rule you must use C<PerlAddVar> directive:

   PerlSetVar SessionManagerHeaderExclude "User-Agent => SomeBot\s*/\*\d+\.\d+"
   PerlAddVar SessionManagerHeaderExclude "User-Agent => GoogleBot"
   PerlAddVar SessionManagerHeaderExclude "Referer => ^http:\/\/some\.host\.com"

Why could be useful to decline request based on HTTP headers check? If you
store session ID in the URI, this prevent bot search engines to index URL with
the session ID.

=item C<SessionManagerIPExclude> IP-list

Matchs client IP addresses against IP list and declines request.
It's possible to set an IP address and optionally a bitmask:

233.76.193.0/24

233.76.193.1/32 (or simply 233.76.193.1)

For example:

   PerlSetVar SessionManagerIPExclude "127.0.0.0/8 192.168.0.0/16 195.31.218.3"

Note that since C<1.03> Apache::SessionManager version, non dotted-quad IP
will be skipped.

=item C<SessionManagerSetEnv> On|Off

Sets the C<SESSION_MANAGER_SID> environment variable with the current (valid)
session ID:

   PerlSetVar SessionManagerSetEnv On

It makes session ID available to CGI scripts for use in absolute links or
redirects. The default value is C<Off>.

To retrieve the C<SESSION_MANAGER_SID> environment variabile you can do, for
instance:

=over 



( run in 2.588 seconds using v1.01-cache-2.11-cpan-df04353d9ac )