File Coverage

blib/lib/Plack/Middleware/Session.pm
Criterion Covered Total %
statement 69 76 90.7
branch 17 22 77.2
condition 5 6 83.3
subroutine 18 19 94.7
pod 3 10 30.0
total 112 133 84.2


line stmt bran cond sub pod time code
1             package Plack::Middleware::Session;
2 14     14   545611 use strict;
  14         1999  
  14         563  
3 14     14   77 use warnings;
  14         34  
  14         1117  
4              
5             our $VERSION = '0.36';
6             our $AUTHORITY = 'cpan:STEVAN';
7              
8 14     14   5070 use Plack::Util;
  14         86821  
  14         511  
9 14     14   107 use Scalar::Util;
  14         29  
  14         666  
10 14     14   11020 use Plack::Session::Cleanup;
  14         49  
  14         593  
11              
12 14     14   107 use parent 'Plack::Middleware';
  14         26  
  14         133  
13              
14 14         83 use Plack::Util::Accessor qw(
15             state
16             store
17 14     14   37556 );
  14         32  
18              
19             sub prepare_app {
20 75     75 1 689824 my $self = shift;
21              
22 75 100       280 $self->state( 'Cookie' ) unless $self->state;
23 75         1256 $self->state( $self->inflate_backend('Plack::Session::State', $self->state) );
24 75         591 $self->store( $self->inflate_backend('Plack::Session::Store', $self->store) );
25             }
26              
27             sub inflate_backend {
28 150     150 0 838 my($self, $prefix, $backend) = @_;
29              
30 150 100 100     1039 return $backend if defined $backend && Scalar::Util::blessed $backend;
31              
32 5         10 my @class;
33 5 100       16 push @class, $backend if defined $backend; # undef means the root class
34 5         11 push @class, $prefix;
35              
36 5         27 Plack::Util::load_class(@class)->new();
37             }
38              
39             sub call {
40 82     82 1 89535 my $self = shift;
41 82         165 my $env = shift;
42              
43 82         284 my($id, $session) = $self->get_session($env);
44 82 100 66     615 if ($id && $session) {
45 42         135 $env->{'psgix.session'} = $session;
46             } else {
47 40         146 $id = $self->generate_id($env);
48 40         182 $env->{'psgix.session'} = {};
49             }
50              
51 82         358 $env->{'psgix.session.options'} = { id => $id };
52              
53 82         435 my $res = $self->app->($env);
54 82     82   1586 $self->response_cb($res, sub { $self->finalize($env, $_[0]) });
  82         150839  
55             }
56              
57             sub get_session {
58 76     76 0 197 my($self, $env) = @_;
59              
60 76 100       216 my $id = $self->state->extract($env) or return;
61 50 100       1113 my $session = $self->store->fetch($id) or return;
62              
63 42         1742 return ($id, $session);
64             }
65              
66             sub generate_id {
67 34     34 0 121 my($self, $env) = @_;
68 34         114 $self->state->generate($env);
69             }
70              
71             sub commit {
72 68     68 0 195 my($self, $env) = @_;
73              
74 68         165 my $session = $env->{'psgix.session'};
75 68         132 my $options = $env->{'psgix.session.options'};
76              
77             my $end = sub {
78 68 50   68   236 return if $options->{no_store};
79 68         303 $self->store->store($options->{id}, $session);
80 68         361 };
81              
82 68 50       289 if (not $options->{late_store}) {
    0          
83 68         156 $end->();
84             } elsif ($env->{'psgix.cleanup'}) {
85 0         0 push @{$env->{'psgix.cleanup.handlers'}}, $end;
  0         0  
86             } else {
87 0         0 $env->{'psgix.session.cleanup'}
88             = Plack::Session::Cleanup->new($end);
89             }
90             }
91              
92             sub finalize {
93 82     82 0 263 my($self, $env, $res) = @_;
94              
95 82         250 my $session = $env->{'psgix.session'};
96 82         176 my $options = $env->{'psgix.session.options'};
97              
98 82 100       303 if ($options->{expire}) {
99 8         48 $self->expire_session($options->{id}, $res, $env);
100             } else {
101 74 50       251 $self->change_id($env) if $options->{change_id};
102 74         300 $self->commit($env);
103 74         8407 $self->save_state($options->{id}, $res, $env);
104             }
105             }
106              
107             sub change_id {
108 0     0 1 0 my($self, $env) = @_;
109              
110 0         0 my $options = $env->{'psgix.session.options'};
111              
112 0         0 $self->store->remove($options->{id});
113 0         0 $options->{id} = $self->generate_id($env);
114             }
115              
116             sub expire_session {
117 8     8 0 34 my($self, $id, $res, $env) = @_;
118 8         41 $self->store->remove($id);
119 8         368 $self->state->expire_session_id($id, $res, $env->{'psgix.session.options'});
120             }
121              
122             sub save_state {
123 68     68 0 217 my($self, $id, $res, $env) = @_;
124 68         349 $self->state->finalize($id, $res, $env->{'psgix.session.options'});
125             }
126              
127             1;
128              
129             __END__