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