Fixed I generation to use SHA1 instead of sequential. Added sane defaults to Middleware.
Tatsuhiko Miyagawa [Sat, 12 Dec 2009 06:34:40 +0000 (14:34 +0800)]
lib/Plack/Middleware/Session.pm
lib/Plack/Session/State.pm
lib/Plack/Session/State/Cookie.pm
t/001_basic.t [changed mode: 0644->0755]
t/middleware.t [new file with mode: 0644]

index 4a345f1..d85dd5a 100644 (file)
@@ -5,26 +5,40 @@ use warnings;
 use Plack::Session;
 use Plack::Request;
 use Plack::Response;
+use Plack::Session::State::Cookie;
+use Plack::Session::Store;
 
 use parent 'Plack::Middleware';
 
 use Plack::Util::Accessor qw( state store );
 
+sub prepare_app {
+    my $self = shift;
+    unless ($self->state) {
+        $self->state( Plack::Session::State::Cookie->new );
+    }
+
+    unless ($self->store) {
+        $self->store( Plack::Session::Store->new );
+    }
+}
+
 sub call {
     my $self = shift;
     my $env  = shift;
 
     $env->{'psgix.session'} = Plack::Session->new(
-        state   => $self->state,
+        state   => $self->state || $self->default_state,
         store   => $self->store,
         request => Plack::Request->new( $env )
     );
 
-    my $res = Plack::Response->new( @{ $self->app->( $env ) } );
-
-    $env->{'psgix.session'}->finalize( $res );
-
-    $res->finalize();
+    my $res = $self->app->($env);
+    $self->response_cb($res, sub {
+        my $res = Plack::Response->new(@{$_[0]});
+        $env->{'psgix.session'}->finalize( $res );
+        @{$_[0]} = @{$res->finalize};
+    });
 }
 
 1;
index f4141a9..f28ca40 100644 (file)
@@ -3,6 +3,7 @@ use strict;
 use warnings;
 
 use Plack::Util::Accessor qw[ session_key ];
+use Digest::SHA1;
 
 sub new {
     my ($class, %params) = @_;
@@ -37,14 +38,15 @@ sub extract {
     $self->check_expired( $request->param( $self->session_key ) );
 }
 
-{
-    my $id = 1;
-    sub generate { $id++ }
+sub generate {
+    my $self = shift;
+    return Digest::SHA1::sha1_hex(rand() . $$ . {} . time);
 }
 
+
 sub finalize {
     my ($self, $id, $response) = @_;
     ();
 }
 
-1;
\ No newline at end of file
+1;
index d1727b2..018f724 100644 (file)
@@ -28,4 +28,4 @@ sub finalize {
     };
 }
 
-1;
\ No newline at end of file
+1;
old mode 100644 (file)
new mode 100755 (executable)
index 3291b5c..a8aff22
@@ -30,6 +30,7 @@ sub request {
 my $storage = Plack::Session::Store->new;
 my $state   = Plack::Session::State->new;
 
+my @sids;
 {
     my $r = request();
 
@@ -39,21 +40,21 @@ my $state   = Plack::Session::State->new;
         request => $r,
     );
 
-    is($s->id, 1, '... got a basic session id (1)');
-
-    ok(!$s->get('foo'), '... no value stored in foo for session (1)');
+    push @sids, $s->id;
+    
+    ok(!$s->get('foo'), '... no value stored in foo for session');
 
     lives_ok {
         $s->set( foo => 'bar' );
-    } '... set the value successfully in session (1)';
+    } '... set the value successfully in session';
 
-    is($s->get('foo'), 'bar', '... got the foo value back successfully from session (1)');
+    is($s->get('foo'), 'bar', '... got the foo value back successfully from session');
 
     my $resp = $r->new_response;
 
     lives_ok {
         $s->finalize( $resp );
-    } '... finalized session (1) successfully';
+    } '... finalized sessio successfully';
 }
 
 {
@@ -65,25 +66,26 @@ my $state   = Plack::Session::State->new;
         request => $r,
     );
 
-    is($s->id, 2, '... got a basic session id (2)');
+    push @sids, $s->id;
 
-    ok(!$s->get('foo'), '... no value stored for foo in session (2)');
+    isnt($sids[0], $sids[1], "no same Session ID");
+    ok(!$s->get('foo'), '... no value stored for foo in session');
 
     lives_ok {
         $s->set( foo => 'baz' );
     } '... set the value successfully';
 
-    is($s->get('foo'), 'baz', '... got the foo value back successfully from session (2)');
+    is($s->get('foo'), 'baz', '... got the foo value back successfully from session');
 
     my $resp = $r->new_response;
 
     lives_ok {
         $s->finalize( $resp );
-    } '... finalized session (2) successfully';
+    } '... finalized session successfully';
 }
 
 {
-    my $r = request({ plack_session => 1 });
+    my $r = request({ plack_session => $sids[0] });
 
     my $s = Plack::Session->new(
         state   => $state,
@@ -91,26 +93,26 @@ my $state   = Plack::Session::State->new;
         request => $r,
     );
 
-    is($s->id, 1, '... got a basic session id (1)');
+    is($s->id, $sids[0], '... got a basic session id');
 
-    is($s->get('foo'), 'bar', '... got the value for foo back successfully from session (1)');
+    is($s->get('foo'), 'bar', '... got the value for foo back successfully from session');
 
     lives_ok {
         $s->remove( 'foo' );
-    } '... removed the foo value successfully from session (1)';
+    } '... removed the foo value successfully from session';
 
-    ok(!$s->get('foo'), '... no value stored for foo in session (1)');
+    ok(!$s->get('foo'), '... no value stored for foo in session');
 
     my $resp = $r->new_response;
 
     lives_ok {
         $s->finalize( $resp );
-    } '... finalized session (1) successfully';
+    } '... finalized session successfully';
 }
 
 
 {
-    my $r = request({ plack_session => 2 });
+    my $r = request({ plack_session => $sids[1] });
 
     my $s = Plack::Session->new(
         state   => $state,
@@ -118,19 +120,19 @@ my $state   = Plack::Session::State->new;
         request => $r,
     );
 
-    is($s->id, 2, '... got a basic session id (2)');
+    is($s->id, $sids[1], '... got a basic session id');
 
-    is($s->get('foo'), 'baz', '... got the foo value back successfully from session (2)');
+    is($s->get('foo'), 'baz', '... got the foo value back successfully from session');
 
     my $resp = $r->new_response;
 
     lives_ok {
         $s->finalize( $resp );
-    } '... finalized session (2) successfully';
+    } '... finalized session successfully';
 }
 
 {
-    my $r = request({ plack_session => 1 });
+    my $r = request({ plack_session => $sids[0] });
 
     my $s = Plack::Session->new(
         state   => $state,
@@ -138,23 +140,23 @@ my $state   = Plack::Session::State->new;
         request => $r,
     );
 
-    is($s->id, 1, '... got a basic session id (1)');
+    is($s->id, $sids[0], '... got a basic session id');
 
-    ok(!$s->get('foo'), '... no value stored for foo in session (1)');
+    ok(!$s->get('foo'), '... no value stored for foo in session');
 
     lives_ok {
         $s->set( bar => 'baz' );
-    } '... set the bar value successfully in session (1)';
+    } '... set the bar value successfully in session';
 
     my $resp = $r->new_response;
 
     lives_ok {
         $s->finalize( $resp );
-    } '... finalized session (1) successfully';
+    } '... finalized session successfully';
 }
 
 {
-    my $r = request({ plack_session => 1 });
+    my $r = request({ plack_session => $sids[0] });
 
     my $s = Plack::Session->new(
         state   => $state,
@@ -162,17 +164,15 @@ my $state   = Plack::Session::State->new;
         request => $r,
     );
 
-    is($s->id, 1, '... got a basic session id (1)');
-
-    is($s->get('bar'), 'baz', '... got the bar value back successfully from session (1)');
+    is($s->get('bar'), 'baz', '... got the bar value back successfully from session');
 
     lives_ok {
         $s->expire;
-    } '... expired session (1) successfully';
+    } '... expired session successfully';
 }
 
 {
-    my $r = request({ plack_session => 1 });
+    my $r = request({ plack_session => $sids[0] });
 
     my $s = Plack::Session->new(
         state   => $state,
@@ -180,13 +180,14 @@ my $state   = Plack::Session::State->new;
         request => $r,
     );
 
-    is($s->id, 3, '... got a new session id (3)');
+    push @sids, $s->id;
+    isnt($s->id, $sids[0], 'expired ... got a new session id');
 
-    ok(!$s->get('bar'), '... no bar value stored (from session (1)) in session (3)');
+    ok(!$s->get('bar'), '... no bar value stored');
 }
 
 {
-    my $r = request({ plack_session => 2 });
+    my $r = request({ plack_session => $sids[1] });
 
     my $s = Plack::Session->new(
         state   => $state,
@@ -194,15 +195,15 @@ my $state   = Plack::Session::State->new;
         request => $r,
     );
 
-    is($s->id, 2, '... got a basic session id (2)');
+    is($s->id, $sids[1], '... got a basic session id');
 
-    is($s->get('foo'), 'baz', '... got the foo value back successfully from session (2)');
+    is($s->get('foo'), 'baz', '... got the foo value back successfully from session');
 
     my $resp = $r->new_response;
 
     lives_ok {
         $s->finalize( $resp );
-    } '... finalized session (2) successfully';
+    } '... finalized session successfully';
 }
 
-done_testing;
\ No newline at end of file
+done_testing;
diff --git a/t/middleware.t b/t/middleware.t
new file mode 100644 (file)
index 0000000..7fd5962
--- /dev/null
@@ -0,0 +1,37 @@
+use Plack::Test;
+use Plack::Middleware::Session;
+use Test::More;
+use HTTP::Request::Common;
+use HTTP::Cookies;
+
+my $app = sub {
+    my $env = shift;
+    my $counter = $env->{'psgix.session'}->get('counter') || 0;
+
+    my $body = "Counter=$counter";
+    $counter++;
+    $env->{'psgix.session'}->set(counter => $counter);
+
+    return [ 200, [], [ $body ] ];
+};
+
+$app = Plack::Middleware::Session->wrap($app);
+
+test_psgi $app, sub {
+    my $cb = shift;
+
+    my $jar = HTTP::Cookies->new;
+
+    my $res = $cb->(GET "http://localhost/");
+    is $res->content, "Counter=0";
+    $jar->extract_cookies($res);
+
+    my $req = GET "http://localhost/";
+    $jar->add_cookie_header($req);
+    use XXX;
+    $res = $cb->($req);
+    is $res->content, "Counter=1";
+};
+
+done_testing;
+