use
vars
qw(@ISA $VERSION)
;
$VERSION
=
'3.0.1'
;
@ISA
=
qw(Apache::Session)
;
no
warnings
"uninitialized"
;
use
constant
NEW
=> Apache::Session::NEW () ;
use
constant
MODIFIED
=> Apache::Session::MODIFIED () ;
use
constant
DELETED
=> Apache::Session::DELETED () ;
use
constant
SYNCED
=> Apache::Session::SYNCED () ;
sub
TIEHASH {
my
$class
=
shift
;
my
$session_id
=
shift
;
my
$args
=
shift
|| {};
if
(
ref
$args
ne
"HASH"
)
{
die
"Additional arguments should be in the form of a hash reference"
;
}
my
$self
=
{
args
=>
$args
,
data
=> {
_session_id
=>
$session_id
},
initial_session_id
=>
$session_id
,
lock
=> 0,
lock_manager
=>
undef
,
object_store
=>
undef
,
status
=> 0,
serialized
=>
undef
,
};
bless
$self
,
$class
;
$self
-> require_modules (
$args
) ;
$self
-> init
if
(!
$args
-> {
'lazy'
}) ;
return
$self
;
}
sub
require_modules
{
my
$self
=
shift
;
my
$args
=
shift
;
if
(
$args
-> {
'object_store'
})
{
$args
-> {
'object_store'
} =
"Apache::Session::$args->{'object_store'}"
if
(!(
$args
-> {
'object_store'
} =~ /::/)) ;
eval
"require $args->{'object_store'}"
;
die
"Cannot require $args->{'object_store'}"
if
($@) ;
}
if
(
$args
-> {
'lock_manager'
})
{
$args
-> {
'lock_manager'
} =
"Apache::Session::$args->{'lock_manager'}"
if
(!(
$args
-> {
'lock_manager'
} =~ /::/)) ;
eval
"require $args->{'lock_manager'}"
;
die
"Cannot require $args->{'lock_manager'}"
if
($@) ;
}
if
(
$args
-> {
'Store'
})
{
$args
-> {
'Store'
} =
"Apache::Session::Store::$args->{'Store'}"
if
(!(
$args
-> {
'Store'
} =~ /::/)) ;
eval
"require $args->{'Store'}"
;
die
"Cannot require $args->{'Store'}"
if
($@) ;
}
if
(
$args
-> {
'Lock'
})
{
$args
-> {
'Lock'
} =
"Apache::Session::Lock::$args->{'Lock'}"
if
(!(
$args
-> {
'Lock'
} =~ /::/)) ;
eval
"require $args->{'Lock'}"
;
die
"Cannot require $args->{'Lock'}"
if
($@) ;
}
if
(
$args
-> {
'Generate'
})
{
$args
-> {
'Generate'
} =
"Apache::Session::Generate::$args->{'Generate'}"
if
(!(
$args
-> {
'Generate'
} =~ /::/)) ;
eval
"require $args->{'Generate'}"
;
die
"Cannot require $args->{'Generate'}"
if
($@) ;
}
if
(
$args
-> {
'Serialize'
})
{
$args
-> {
'Serialize'
} =
"Apache::Session::Serialize::$args->{'Serialize'}"
if
(!(
$args
-> {
'Serialize'
} =~ /::/)) ;
eval
"require $args->{'Serialize'}"
;
die
"Cannot require $args->{'Serialize'}"
if
($@) ;
}
}
sub
init
{
my
$self
=
shift
;
my
$session_id
=
$self
->{data}->{_session_id} ;
if
(!
$session_id
&&
$self
-> {idfrom})
{
$session_id
=
$self
->{data}->{_session_id} = &{
$self
->{generate}}(
$self
,
$self
-> {idfrom}) ;
}
$self
->{initial_session_id} ||=
$session_id
;
$self
->populate;
if
(
defined
$session_id
&&
$session_id
)
{
eval
{ &{
$self
->{validate}}(
$self
); } ;
if
(!$@)
{
if
(
exists
$self
-> {
'args'
}->{Transaction} &&
$self
-> {
'args'
}->{Transaction})
{
$self
->acquire_write_lock;
}
$self
->{status} &= (
$self
->{status} ^ NEW);
if
(
$self
-> {
'args'
}{
'create_unknown'
})
{
eval
{
$self
-> restore } ;
$@ =
""
;
$session_id
=
$self
->{data}->{_session_id} ;
}
else
{
$self
->restore;
}
}
}
$@ =
''
;
if
(!(
$self
->{status} & SYNCED))
{
$self
->{status} |= NEW();
if
(!
$self
->{data}->{_session_id} ||
$self
-> {
'args'
}{
'recreate_id'
})
{
if
(
exists
(
$self
->{generate}))
{
$self
->{data}->{_session_id} = &{
$self
->{generate}}(
$self
) ;
}
else
{
$self
->{data}->{_session_id} =
$self
-> generate_id() ;
}
}
$self
->save;
}
return
$self
;
}
sub
FETCH {
my
$self
=
shift
;
my
$key
=
shift
;
$self
-> init
if
(!
$self
-> {
'status'
}) ;
return
$self
->{data}->{
$key
};
}
sub
STORE {
my
$self
=
shift
;
my
$key
=
shift
;
my
$value
=
shift
;
$self
-> init
if
(!
$self
-> {
'status'
}) ;
$self
->{data}->{
$key
} =
$value
;
$self
->{status} |= MODIFIED;
return
$self
->{data}->{
$key
};
}
sub
DELETE {
my
$self
=
shift
;
my
$key
=
shift
;
$self
-> init
if
(!
$self
-> {
'status'
}) ;
$self
->{status} |= MODIFIED;
delete
$self
->{data}->{
$key
};
}
sub
CLEAR {
my
$self
=
shift
;
$self
-> init
if
(!
$self
-> {
'status'
}) ;
$self
->{status} |= MODIFIED;
$self
->{data} = {};
}
sub
EXISTS {
my
$self
=
shift
;
my
$key
=
shift
;
$self
-> init
if
(!
$self
-> {
'status'
}) ;
return
exists
$self
->{data}->{
$key
};
}
sub
FIRSTKEY {
my
$self
=
shift
;
$self
-> init
if
(!
$self
-> {
'status'
}) ;
my
$reset
=
keys
%{
$self
->{data}};
return
each
%{
$self
->{data}};
}
sub
NEXTKEY {
my
$self
=
shift
;
$self
-> init
if
(!
$self
-> {
'status'
}) ;
return
each
%{
$self
->{data}};
}
sub
DESTROY {
my
$self
=
shift
;
return
if
(!
$self
-> {
'status'
}) ;
$self
->save;
$self
->release_all_locks;
}
sub
cleanup
{
my
$self
=
shift
;
$self
->{initial_session_id} =
undef
;
if
(!
$self
-> {
'status'
})
{
$self
->{data} = {} ;
$self
->{serialized} =
undef
;
return
;
}
$self
->save;
{
local
$SIG
{__WARN__} =
'IGNORE'
;
local
$SIG
{__DIE__} =
'IGNORE'
;
eval
{
$self
-> {object_store} ->
close
} ;
$@ =
""
;
}
$self
->release_all_locks;
$self
->{
'status'
} = 0 ;
$self
->{data} = {} ;
$self
->{serialized} =
undef
;
}
sub
setid {
my
$self
=
shift
;
$self
->{
'status'
} = 0 ;
$self
->{data}->{_session_id} =
$self
->{initial_session_id} =
shift
;
}
sub
setidfrom {
my
$self
=
shift
;
$self
->{
'status'
} = 0 ;
$self
->{data}->{_session_id} =
$self
->{initial_session_id} =
undef
;
$self
->{idfrom} =
shift
;
}
sub
getid {
my
$self
=
shift
;
return
$self
->{data}->{_session_id} ||
$self
->{
'ID'
} ;
}
sub
getids {
my
$self
=
shift
;
return
(
$self
->{initial_session_id},
$self
->{data}->{_session_id} ||
$self
->{
'ID'
},
$self
->{status} & MODIFIED) ;
}
sub
delete
{
my
$self
=
shift
;
return
if
(
$self
->{status} & NEW);
$self
->{initial_session_id} =
"!DELETE"
;
$self
-> init
if
(!
$self
-> {
'status'
}) ;
$self
->{status} |= DELETED;
$self
->save;
$self
->{data} = {} ;
}
sub
get_object_store {
my
$self
=
shift
;
return
new {
$self
-> {
'args'
}{
'object_store'
}}
$self
;
}
sub
get_lock_manager {
my
$self
=
shift
;
return
new {
$self
-> {
'args'
}{
'lock_manager'
}}
$self
;
}
sub
validate {
my
$session
=
shift
;
if
(
$session
->{data}->{_session_id} !~ /^[a-fA-F0-9]+$/) {
die
;
}
}
sub
populate
{
my
$self
=
shift
;
my
$store
=
$self
->{args}->{Store};
my
$lock
=
$self
->{args}->{Lock};
my
$gen
=
$self
->{args}->{Generate};
my
$ser
=
$self
->{args}->{Serialize};
$self
->{object_store} = new
$store
$self
if
(
$store
) ;
$self
->{lock_manager} = new
$lock
$self
if
(
$lock
);
$self
->{generate} = \&{
$gen
.
'::generate'
}
if
(
$gen
);
$self
->{
'validate'
} = \&{
$gen
.
'::validate'
}
if
(
$gen
&&
defined
(&{
$gen
.
'::validate'
}));
$self
->{serialize} = \&{
$ser
.
'::serialize'
}
if
(
$ser
);
$self
->{unserialize} = \&{
$ser
.
'::unserialize'
}
if
(
$ser
) ;
if
(!
defined
(
$self
->{
'validate'
}))
{
$self
->{
'validate'
} = \
&validate
;
}
return
$self
;
}
1 ;