Apache-Session-Wrapper
view release on metacpan or search on metacpan
lib/Apache/Session/Wrapper.pm view on Meta::CPAN
package Apache::Session::Wrapper;
use strict;
use vars qw($VERSION);
$VERSION = '0.34';
$VERSION = eval $VERSION;
use base qw(Class::Container);
use Apache::Session 1.81;
use Exception::Class ( 'Apache::Session::Wrapper::Exception::NonExistentSessionID' =>
{ description => 'A non-existent session id was used',
fields => [ 'session_id' ] },
'Apache::Session::Wrapper::Exception::Params' =>
{ description => 'An invalid parameter or set of parameters was given',
alias => 'param_error' },
);
use Params::Validate 0.70;
use Params::Validate qw( validate SCALAR UNDEF BOOLEAN ARRAYREF OBJECT );
Params::Validate::validation_options( on_fail => sub { param_error( join '', @_ ) } );
use Scalar::Util ();
my $MOD_PERL = _find_mp_version();
sub _find_mp_version
{
return 0 unless $ENV{MOD_PERL};
return
( $ENV{MOD_PERL} =~ /(?:1\.9|2\.\d)/
? 2
: 1
);
}
my @HeaderMethods = qw( err_headers_out headers_out );
my %params =
( always_write =>
{ type => BOOLEAN,
default => 1,
descr => 'Whether or not to force a write before the session goes out of scope' },
allow_invalid_id =>
{ type => BOOLEAN,
default => 1,
descr => 'Whether or not to allow a failure to find an existing session id' },
param_name =>
{ type => SCALAR,
optional => 1,
depends => 'param_object',
descr => 'Name of the parameter to use for session tracking' },
param_object =>
{ type => OBJECT,
optional => 1,
can => 'param',
descr => 'Object which has a "param" method, to be used for getting the session id from a query string or POST argument' },
use_cookie =>
{ type => BOOLEAN,
default => 0,
descr => 'Whether or not to use a cookie to track the session' },
cookie_name =>
{ type => SCALAR,
default => 'Apache-Session-Wrapper-cookie',
descr => 'Name of cookie used by this module' },
cookie_expires =>
{ type => UNDEF | SCALAR,
default => '+1d',
descr => 'Expiration time for cookies' },
cookie_domain =>
{ type => UNDEF | SCALAR,
optional => 1,
lib/Apache/Session/Wrapper.pm view on Meta::CPAN
for my $hash ( \%ApacheSessionParams,
\%OptionalApacheSessionParams,
@ApacheSessionFlexParams{ qw( store lock generate serialize ) },
@OptionalApacheSessionFlexParams{ qw( store lock generate serialize ) },
)
{
for my $p ( map { @$_ } map { @$_ } values %$hash )
{
my $h;
if ( ref $p ) {
# we assume its a hash of names/parameter specifications
$h = $p;
} elsif (!$params{$p}) {
# its a new parameter defined by a scalar, default to SCALAR value
$h = { $p => { optional => 1, type => SCALAR } };
} else {
# its a scalar option we already know.
next;
}
# now expand the options
foreach my $name (keys %$h) {
next if $params{$name};
$extra{$p} = $h->{$name};
}
}
}
$class->valid_params( %extra, %params );
$class->SetStudlyForms();
}
__PACKAGE__->_SetValidParams();
my %StudlyForm;
sub SetStudlyForms
{
%StudlyForm =
( map { $_ => _studly_form($_) }
map { ref $_ ? @$_ :$_ }
map { @$_ }
( values %ApacheSessionParams ),
( values %OptionalApacheSessionParams ),
( map { values %{ $ApacheSessionFlexParams{$_} } }
keys %ApacheSessionFlexParams ),
( map { values %{ $OptionalApacheSessionFlexParams{$_} } }
keys %OptionalApacheSessionFlexParams ),
);
# why Apache::Session does this I do not know
$StudlyForm{textsize} = 'textsize';
}
sub _studly_form
{
my $string = shift;
$string =~ s/(?:^|_)(\w)/\U$1/g;
return $string;
}
sub RegisterClass {
my $class = shift;
my %p = validate( @_, { name => { type => SCALAR },
required => { type => SCALAR | ARRAYREF, default => [ [ ] ] },
optional => { type => SCALAR | ARRAYREF, default => [ ] },
},
);
$p{name} =~ s/^Apache::Session:://;
$ApacheSessionParams{ $p{name} } =
( ref $p{required}
? $p{required}
: $ApacheSessionParams{ $p{required} }
);
$OptionalApacheSessionParams{ $p{name} } =
( ref $p{optional}
? [ $p{optional} ]
: $OptionalApacheSessionParams{ $p{optional} }
);
$class->_SetValidParams();
}
sub RegisterFlexClass {
my $class = shift;
my %p = validate( @_, { type => { type => SCALAR,
regex => qr/^(?:store|lock|generate|serialize)/,
},
name => { type => SCALAR },
required => { type => SCALAR | ARRAYREF, default => [ [ ] ] },
optional => { type => SCALAR | ARRAYREF, default => [ ] },
},
);
$p{name} =~ s/^Apache::Session:://;
$p{name} =~ s/^\Q$p{type}\E:://i;
$ApacheSessionFlexParams{ $p{type} }{ $p{name} } =
( ref $p{required}
? $p{required}
: $ApacheSessionFlexParams{ $p{type} }{ $p{required} }
);
$OptionalApacheSessionFlexParams{ $p{type} }{ $p{name} } =
( ref $p{optional}
? [ $p{optional} ]
: $OptionalApacheSessionFlexParams{ $p{type} }{ $p{optional} }
);
$class->_SetValidParams();
}
sub new
{
my $class = shift;
my %p = @_;
my $self = $class->SUPER::new(%p);
$self->_check_session_params;
$self->_set_session_params;
if ( $self->{use_cookie} && ! ( $ENV{MOD_PERL} || $self->{header_object} ) )
{
param_error
"The header_object parameter is required in order to use cookies outside of mod_perl";
}
my $session_class = "Apache::Session::$self->{session_class_piece}";
unless ( $session_class->can('TIEHASH') )
{
eval "require $session_class";
die $@ if $@;
}
$self->_make_session( $p{session_id} );
$self->_bake_cookie
if $self->{use_cookie} && ! $self->{cookie_is_baked};
return $self;
}
sub _check_session_params
{
my $self = shift;
lib/Apache/Session/Wrapper.pm view on Meta::CPAN
}
sub _bake_cookie
{
my $self = shift;
my $expires = shift || $self->{cookie_expires};
$expires = undef if defined $expires && $expires =~ /^session$/i;
my $domain = $self->{cookie_domain};
my $cookie =
$self->{cookie_class}->new
( @{ $self->{new_cookie_args} },
-name => $self->{cookie_name},
# Apache2::Cookie will return undef if we pass undef for
# -value.
-value => ( $self->{session_id} || '' ),
( defined $expires
? ( -expires => $expires )
: ()
),
( defined $domain
? ( -domain => $domain )
: ()
),
-path => $self->{cookie_path},
-secure => $self->{cookie_secure},
);
# If not running under mod_perl, CGI::Cookie->bake() will call
# print() to send a cookie header right now, which may not be what
# the user wants.
if ( $cookie->can('bake') && ! $cookie->isa('CGI::Cookie') )
{
$cookie->bake( @{ $self->{bake_cookie_args} } );
}
else
{
my $header_object = $self->{header_object};
for my $meth (@HeaderMethods)
{
if ( $header_object->can($meth) )
{
$header_object->$meth->add( 'Set-Cookie' => $cookie );
last;
}
}
}
# always set this even if we skipped actually setting the cookie
# to avoid resending it. this keeps us from entering this method
# over and over
$self->{cookie_is_baked} = 1
unless $self->{cookie_resend};
}
sub session
{
my $self = shift;
my %p = validate( @_,
{ session_id =>
{ type => SCALAR,
optional => 1,
},
} );
if ( ! $self->{session} || %p )
{
$self->_make_session( $p{session_id} );
$self->_bake_cookie
if $self->{use_cookie} && ! $self->{cookie_is_baked};
}
return $self->{session};
}
sub delete_session
{
my $self = shift;
return unless $self->{session};
my $session = delete $self->{session};
(tied %$session)->delete;
delete $self->{session_id};
$self->_bake_cookie('-1d') if $self->{use_cookie};
}
sub cleanup_session
{
my $self = shift;
if ( $self->{always_write} )
{
if ( $self->{session}->{___force_a_write___} )
{
$self->{session}{___force_a_write___} = 0;
}
else
{
$self->{session}{___force_a_write___} = 1;
}
}
undef $self->{session};
}
sub DESTROY { $_[0]->cleanup_session }
1;
__END__
=head1 NAME
( run in 0.420 second using v1.01-cache-2.11-cpan-13bb782fe5a )