--- /dev/null
+#!/usr/bin/perl
+
+use Plack::Session;
+use Plack::Session::State;
+use Plack::Session::State::Cookie;
+use Plack::Session::Store;
+use Plack::Middleware::Session;
+
+my $app = Plack::Middleware::Session->wrap(
+ sub {
+ my $env = shift;
+ my $r = Plack::Request->new( $env );
+
+ return [ 404, [], [] ] if $r->path_info =~ /favicon.ico/;
+
+ my $session = $env->{'psgix.session'};
+
+ my $id = $session->id;
+ my $counter = $session->get('counter') || 0;
+
+ $session->set( 'counter' => $counter + 1 );
+
+ my $resp;
+
+ if ( $r->param( 'logout' ) ) {
+ $session->expire;
+ $resp = $r->new_response;
+ $resp->redirect( $r->path_info );
+ }
+ else {
+ $resp = $r->new_response(
+ 200,
+ [ 'Content-Type' => 'text/html' ],
+ [
+ qq{
+ <html>
+ <head>
+ <title>Plack::Middleware::Session Example</title>
+ </head>
+ <body>
+ <h1>Session Id: ${id}</h1>
+ <h2>Counter: ${counter}</h2>
+ <hr/>
+ <a href="/?logout=1">Logout</a>
+ </body>
+ </html>
+ }
+ ]
+ );
+ }
+
+ $resp->finalize;
+ },
+ state => Plack::Session::State::Cookie->new,
+ store => Plack::Session::Store->new,
+);
\ No newline at end of file
--- /dev/null
+package Plack::Middleware::Session;
+use strict;
+use warnings;
+
+use Plack::Session;
+use Plack::Request;
+use Plack::Response;
+
+use parent 'Plack::Middleware';
+
+use Plack::Util::Accessor qw( state store );
+
+sub call {
+ my $self = shift;
+ my $env = shift;
+
+ $env->{'psgix.session'} = Plack::Session->new(
+ state => $self->state,
+ store => $self->store,
+ request => Plack::Request->new( $env )
+ );
+
+ my $res = Plack::Response->new( @{ $self->app->( $env ) } );
+
+ $env->{'psgix.session'}->finalize( $res );
+
+ $res->finalize();
+}
+
+1;
+
+__END__
}
sub finalize {
- my $self = shift;
- $self->store->persist( $self->id )
+ my ($self, $response) = @_;
+ $self->store->persist( $self->id, $response );
+ $self->state->finalize( $self->id, $response );
}
1;
\ No newline at end of file
use strict;
use warnings;
-use Plack::Util::Accessor qw[
- generator
- extractor
- session_key
-];
+use Plack::Util::Accessor qw[ session_key ];
sub new {
my ($class, %params) = @_;
bless {
session_key => $params{ session_key } || 'plack_session',
- generator => do { my $id = 1; sub { $id++ } },
- extractor => sub { $_[0]->param( $_[1] ) },
expired => {}
} => $class;
}
$self->{expired}->{ $id }++;
}
-sub extract {
- my ($self, $request) = @_;
- my $id = $self->extractor->( $request, $self->session_key );
+sub check_expired {
+ my ($self, $id) = @_;
return unless $id && not exists $self->{expired}->{ $id };
return $id;
}
-sub generate {
- my $self = shift;
- $self->generator->()
-}
-
# given a request, get the
# session id from it
sub get_session_id {
my ($self, $request) = @_;
$self->extract( $request )
||
- $self->generate
+ $self->generate( $request )
+}
+
+sub extract {
+ my ($self, $request) = @_;
+ $self->check_expired( $request->param( $self->session_key ) );
+}
+
+{
+ my $id = 1;
+ sub generate { $id++ }
+}
+
+sub finalize {
+ my ($self, $id, $response) = @_;
+ ();
}
1;
\ No newline at end of file
--- /dev/null
+package Plack::Session::State::Cookie;
+use strict;
+use warnings;
+
+use parent 'Plack::Session::State';
+
+use Plack::Util::Accessor qw[ path domain expires secure ];
+
+sub expire_session_id {
+ my ($self, $id) = @_;
+ $self->SUPER::expire_session_id( $id );
+ $self->expires( 0 );
+}
+
+sub extract {
+ my ($self, $request) = @_;
+ $self->check_expired( ( $request->cookie( $self->session_key ) || return )->value );
+}
+
+sub finalize {
+ my ($self, $id, $response) = @_;
+ $response->cookies->{ $self->session_key } = +{
+ value => $id,
+ path => ($self->path || '/'),
+ ( $self->domain ? ( domain => $self->domain ) : () ),
+ ( $self->expires ? ( expires => $self->expires ) : () ),
+ ( $self->secure ? ( secure => $self->secure ) : () ),
+ };
+}
+
+1;
\ No newline at end of file
my $state = Plack::Session::State->new;
{
+ my $r = request();
+
my $s = Plack::Session->new(
state => $state,
store => $storage,
- request => request(),
+ request => $r,
);
is($s->id, 1, '... got a basic session id (1)');
is($s->get('foo'), 'bar', '... got the foo value back successfully from session (1)');
+ my $resp = $r->new_response;
+
lives_ok {
- $s->finalize;
+ $s->finalize( $resp );
} '... finalized session (1) successfully';
}
{
+ my $r = request();
+
my $s = Plack::Session->new(
state => $state,
store => $storage,
- request => request(),
+ request => $r,
);
is($s->id, 2, '... got a basic session id (2)');
is($s->get('foo'), 'baz', '... got the foo value back successfully from session (2)');
+ my $resp = $r->new_response;
+
lives_ok {
- $s->finalize;
+ $s->finalize( $resp );
} '... finalized session (2) successfully';
}
{
+ my $r = request({ plack_session => 1 });
+
my $s = Plack::Session->new(
state => $state,
store => $storage,
- request => request({ plack_session => 1 }),
+ request => $r,
);
is($s->id, 1, '... got a basic session id (1)');
ok(!$s->get('foo'), '... no value stored for foo in session (1)');
+ my $resp = $r->new_response;
+
lives_ok {
- $s->finalize;
+ $s->finalize( $resp );
} '... finalized session (1) successfully';
}
{
+ my $r = request({ plack_session => 2 });
+
my $s = Plack::Session->new(
state => $state,
store => $storage,
- request => request({ plack_session => 2 }),
+ request => $r,
);
is($s->id, 2, '... got a basic session id (2)');
is($s->get('foo'), 'baz', '... got the foo value back successfully from session (2)');
+ my $resp = $r->new_response;
+
lives_ok {
- $s->finalize;
+ $s->finalize( $resp );
} '... finalized session (2) successfully';
}
{
+ my $r = request({ plack_session => 1 });
+
my $s = Plack::Session->new(
state => $state,
store => $storage,
- request => request({ plack_session => 1 }),
+ request => $r,
);
is($s->id, 1, '... got a basic session id (1)');
$s->set( bar => 'baz' );
} '... set the bar value successfully in session (1)';
+ my $resp = $r->new_response;
+
lives_ok {
- $s->finalize;
+ $s->finalize( $resp );
} '... finalized session (1) successfully';
}
{
+ my $r = request({ plack_session => 1 });
+
my $s = Plack::Session->new(
state => $state,
store => $storage,
- request => request({ plack_session => 1 }),
+ request => $r,
);
is($s->id, 1, '... got a basic session id (1)');
}
{
+ my $r = request({ plack_session => 1 });
+
my $s = Plack::Session->new(
state => $state,
store => $storage,
- request => request({ plack_session => 1 }),
+ request => $r,
);
is($s->id, 3, '... got a new session id (3)');
}
{
+ my $r = request({ plack_session => 2 });
+
my $s = Plack::Session->new(
state => $state,
store => $storage,
- request => request({ plack_session => 2 }),
+ request => $r,
);
is($s->id, 2, '... got a basic session id (2)');
is($s->get('foo'), 'baz', '... got the foo value back successfully from session (2)');
+ my $resp = $r->new_response;
+
lives_ok {
- $s->finalize;
+ $s->finalize( $resp );
} '... finalized session (2) successfully';
}