Refactored Middleware::Session to call ->state and ->store inside more
Tatsuhiko Miyagawa [Sat, 9 Jan 2010 20:02:37 +0000 (12:02 -0800)]
abstract methods so Cookie can override them easily without creating
an inline state/store objects.

lib/Plack/Middleware/Session.pm
lib/Plack/Middleware/Session/Cookie.pm

index 15c4d6e..2d11bbc 100644 (file)
@@ -46,12 +46,11 @@ sub call {
 
     my $request = Plack::Request->new($env);
 
-    my($id, $session);
-    if ($id = $self->state->extract($request) and
-        $session = $self->store->fetch($id)) {
+    my($id, $session) = $self->get_session($request);
+    if ($id && $session) {
         $env->{'psgix.session'} = $session;
     } else {
-        $id = $self->state->generate($request);
+        $id = $self->generate_id($request);
         $env->{'psgix.session'} = {};
     }
 
@@ -64,13 +63,27 @@ sub call {
     my $res = $self->app->($env);
     $self->response_cb($res, sub {
         my $res = Plack::Response->new(@{$_[0]});
-        $self->finalize($env->{'psgix.session'}, $env->{'psgix.session.options'}, $res);
+        $self->finalize($request, $res);
         $res = $res->finalize;
         $_[0]->[0] = $res->[0];
         $_[0]->[1] = $res->[1];
     });
 }
 
+sub get_session {
+    my($self, $request) = @_;
+
+    my $id = $self->state->extract($request) or return;
+    my $session = $self->store->fetch($id)   or return;
+
+    return ($id, $session);
+}
+
+sub generate_id {
+    my($self, $request) = @_;
+    $self->state->generate($request);
+}
+
 sub commit {
     my($self, $session, $options) = @_;
     if ($options->{expire}) {
@@ -81,16 +94,29 @@ sub commit {
 }
 
 sub finalize {
-    my($self, $session, $options, $response) = @_;
+    my($self, $request, $response) = @_;
+
+    my $session = $request->env->{'psgix.session'};
+    my $options = $request->env->{'psgix.session.options'};
 
     $self->commit($session, $options) unless $options->{no_store};
     if ($options->{expire}) {
-        $self->state->expire_session_id($options->{id}, $response);
+        $self->expire_session($options->{id}, $response, $session, $options);
     } else {
-        $self->state->finalize($options->{id}, $response, $options);
+        $self->save_state($options->{id}, $response, $session, $options);
     }
 }
 
+sub expire_session {
+    my($self, $id, $res, $session, $options) = @_;
+    $self->state->expire_session_id($options->{id}, $res, $options);
+}
+
+sub save_state {
+    my($self, $id, $res, $session, $options) = @_;
+    $self->state->finalize($id, $res, $options);
+}
+
 1;
 
 __END__
index 2385101..3351d1d 100644 (file)
@@ -18,54 +18,43 @@ sub prepare_app {
     Plack::Util::load_class($self->session_class) if $self->session_class;
     $self->session_key("plack_session") unless $self->session_key;
 
-    my $state_cookie = Plack::Session::State::Cookie->new;
+    $self->state( Plack::Session::State::Cookie->new );
     for my $attr (qw(session_key path domain expires secure)) {
-        $state_cookie->$attr($self->$attr);
+        $self->state->$attr($self->$attr);
     }
+}
+
+sub get_session {
+    my($self, $request) = @_;
+
+    my $cookie = $self->state->get_session_id($request) or return;
 
-    my $state = Plack::Util::inline_object
-        generate => sub { $self->_serialize({}) },
-        extract  => sub {
-            my $cookie = $state_cookie->get_session_id(@_) or return;
-
-            my($time, $b64, $sig) = split /:/, $cookie, 3;
-            $self->sig($b64) eq $sig or return;
-
-            return $cookie;
-        },
-        expire_session_id => sub { $state_cookie->expire_session_id(@_) },
-        finalize => sub { $state_cookie->finalize(@_) };
-
-    my $store = Plack::Util::inline_object
-        fetch => sub {
-            my $id = shift;
-            my($time, $b64, $sig) = split /:/, $id, 3;
-            Storable::thaw(MIME::Base64::decode($b64));
-        },
-        store => sub { },
-        cleanup => sub { };
-
-    $self->state($state);
-    $self->store($store);
+    my($time, $b64, $sig) = split /:/, $cookie, 3;
+    $self->sig($b64) eq $sig or return;
+
+    my $session = Storable::thaw(MIME::Base64::decode($b64));
+    return ($time, $session);
 }
 
-sub finalize {
-    my($self, $session, $options, $response) = @_;
+sub generate_id {
+    my $self = shift;
+    return Time::HiRes::gettimeofday;
+}
 
-    if ($options->{expire}) {
-        $self->state->expire_session_id($options->{id}, $response);
-    } else {
-        my $cookie = $self->_serialize($session);
-        $self->state->finalize($cookie, $response, $options);
-    }
+sub commit { }
+
+sub save_state {
+    my($self, $id, $res, $session, $options) = @_;
+
+    my $cookie = $self->_serialize($id, $session);
+    $self->state->finalize($cookie, $res, $options);
 }
 
 sub _serialize {
-    my($self, $session) = @_;
+    my($self, $id, $session) = @_;
 
-    my $now = Time::HiRes::gettimeofday;
     my $b64 = MIME::Base64::encode( Storable::freeze($session), '' );
-    join ":", $now, $b64, $self->sig($b64);
+    join ":", $id, $b64, $self->sig($b64);
 }
 
 sub sig {