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