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