6a8fac372e70554ade221a433f2348f720992215
[catagits/Web-Session.git] / lib / Plack / Middleware / Session.pm
1 package Plack::Middleware::Session;
2 use strict;
3 use warnings;
4
5 our $VERSION   = '0.03';
6 our $AUTHORITY = 'cpan:STEVAN';
7
8 use Plack::Session;
9 use Plack::Request;
10 use Plack::Response;
11 use Plack::Util;
12 use Scalar::Util;
13
14 use parent 'Plack::Middleware';
15
16 use Plack::Util::Accessor qw(
17     state
18     store
19     session_class
20 );
21
22 sub prepare_app {
23     my $self = shift;
24
25     $self->session_class( 'Plack::Session' ) unless $self->session_class;
26     $self->state( 'Cookie' )                 unless $self->state;
27
28     $self->state( $self->inflate_backend('Plack::Session::State', $self->state) );
29     $self->store( $self->inflate_backend('Plack::Session::Store', $self->store) );
30 }
31
32 sub inflate_backend {
33     my($self, $prefix, $backend) = @_;
34
35     return $backend if defined $backend && Scalar::Util::blessed $backend;
36
37     my @class;
38     push @class, $backend if defined $backend; # undef means the root class
39     push @class, $prefix;
40
41     Plack::Util::load_class(@class)->new();
42 }
43
44 sub fetch_or_create_session {
45     my($self, $req) = @_;
46     $self->session_class->fetch_or_create($req, $self);
47 }
48
49 sub call {
50     my $self = shift;
51     my $env  = shift;
52
53     my $session = $self->fetch_or_create_session(Plack::Request->new($env));
54
55     $env->{'psgix.session'} = $env->{'plack.session'} = $session;
56
57     my $res = $self->app->($env);
58     $self->response_cb($res, sub {
59         my $res = Plack::Response->new(@{$_[0]});
60         $env->{'psgix.session'}->finalize($res);
61         $res = $res->finalize;
62         $_[0]->[0] = $res->[0];
63         $_[0]->[1] = $res->[1];
64     });
65 }
66
67 1;
68
69 __END__
70
71 =pod
72
73 =head1 NAME
74
75 Plack::Middleware::Session - Middleware for session management
76
77 =head1 SYNOPSIS
78
79   use Plack::Builder;
80
81   my $app = sub {
82       my $env = shift;
83       return [
84           200,
85           [ 'Content-Type' => 'text/plain' ],
86           [ 'Hello, your Session ID is ' . $env->{'psgix.session'}->id ]
87       ];
88   };
89
90   builder {
91       enable 'Session';
92       $app;
93   };
94
95   # Or, use the File store backend (great if you use multiprocess server)
96   # For more options, see perldoc Plack::Session::Store::File
97   builder {
98       enable 'Session', store => 'File';
99       $app;
100   };
101
102 =head1 DESCRIPTION
103
104 This is a Plack Middleware component for session management. By
105 default it will use cookies to keep session state and store data in
106 memory. This distribution also comes with other state and store
107 solutions. See perldoc for these backends how to use them.
108
109 It should be noted that we store the current session in the
110 C<psgix.session> key inside the C<$env> where you can access it
111 as needed. Additionally, as of version 0.09, you can call the
112 C<session> method of a L<Plack::Request> instance to fetch
113 whatever is stored in C<psgix.session>.
114
115 B<NOTE:> As of version 0.02 the session is stored in C<psgix.session>
116 instead of C<plack.session>. We still keep a copy of it in
117 C<plack.session>, but this is deprecated and will be removed
118 in future versions.
119
120 =head2 State
121
122 =over 4
123
124 =item L<Plack::Session::State>
125
126 This will maintain session state by passing the session through
127 the request params. It does not do this automatically though,
128 you are responsible for passing the session param.
129
130 =item L<Plack::Session::State::Cookie>
131
132 This will maintain session state using browser cookies.
133
134 =back
135
136 =head2 Store
137
138 =over 4
139
140 =item L<Plack::Session::Store>
141
142 This is your basic in-memory session data store. It is volatile storage
143 and not recommended for multiprocessing environments. However it is
144 very useful for development and testing.
145
146 =item L<Plack::Session::Store::File>
147
148 This will persist session data in a file. By default it uses
149 L<Storable> but it can be configured to have a custom serializer and
150 deserializer.
151
152 =item L<Plack::Session::Store::Cache>
153
154 This will persist session data using the L<Cache> interface.
155
156 =item L<Plack::Session::Store::Null>
157
158 Sometimes you don't care about storing session data, in that case
159 you can use this noop module.
160
161 =back
162
163 =head1 OPTIONS
164
165 The following are options that can be passed to this mdoule.
166
167 =over 4
168
169 =item I<state>
170
171 This is expected to be an instance of L<Plack::Session::State> or an
172 object that implements the same interface. If no option is provided
173 the default L<Plack::Session::State::Cookie> will be used.
174
175 =item I<store>
176
177 This is expected to be an instance of L<Plack::Session::Store> or an
178 object that implements the same interface. If no option is provided
179 the default L<Plack::Session::Store> will be used.
180
181 It should be noted that this default is an in-memory volatile store
182 is only suitable for development (or single process servers). For a
183 more robust solution see L<Plack::Session::Store::File> or
184 L<Plack::Session::Store::Cache>.
185
186 =item I<session_class>
187
188 This can be used to override the actual session class. It currently
189 defaults to L<Plack::Session> but you can substitute any class which
190 implements the same interface.
191
192 =back
193
194 =head1 BUGS
195
196 All complex software has bugs lurking in it, and this module is no
197 exception. If you find a bug please either email me, or add the bug
198 to cpan-RT.
199
200 =head1 AUTHOR
201
202 Tatsuhiko Miyagawa
203
204 Stevan Little E<lt>stevan.little@iinteractive.comE<gt>
205
206 =head1 COPYRIGHT AND LICENSE
207
208 Copyright 2009, 2010 Infinity Interactive, Inc.
209
210 L<http://www.iinteractive.com>
211
212 This library is free software; you can redistribute it and/or modify
213 it under the same terms as Perl itself.
214
215 =cut
216
217