File Coverage

blib/lib/Catalyst/Plugin/Session/Flex.pm
Criterion Covered Total %
statement 21 103 20.3
branch 0 46 0.0
condition 0 4 0.0
subroutine 7 14 50.0
pod 6 6 100.0
total 34 173 19.6


line stmt bran cond sub pod time code
1             package Catalyst::Plugin::Session::Flex;
2              
3 1     1   22200 use strict;
  1         2  
  1         46  
4 1     1   6 use base qw/Class::Data::Inheritable Class::Accessor::Fast/;
  1         2  
  1         1069  
5 1     1   9143 use NEXT;
  1         5618  
  1         38  
6 1     1   941 use Apache::Session::Flex;
  1         4244  
  1         27  
7 1     1   7 use Digest::MD5;
  1         2  
  1         46  
8 1     1   970 use URI;
  1         5376  
  1         35  
9 1     1   970 use URI::Find;
  1         2401  
  1         1384  
10              
11             our $VERSION = '0.07';
12              
13             __PACKAGE__->mk_classdata('_session');
14             __PACKAGE__->mk_accessors('sessionid');
15              
16             =head1 NAME
17              
18             Catalyst::Plugin::Session::Flex - Apache::Flex sessions for Catalyst
19              
20             =head1 SYNOPSIS
21              
22             use Catalyst 'Session::Flex';
23              
24             MyApp->config->{session} = {
25             Store => 'File',
26             Lock => 'Null',
27             Generate => 'MD5',
28             Serialize => 'Storable',
29             expires => '+1M',
30             cookie_name => 'session',
31             };
32              
33             =head1 DESCRIPTION
34              
35             Session management using Apache::Session via Apache::Session::Flex
36              
37             =head2 EXTENDED METHODS
38              
39             =head3 finalize
40              
41             =cut
42              
43             sub finalize {
44 0     0 1   my $c = shift;
45 0   0       my $cookie_name = $c->config->{session}{cookie_name} || 'session';
46              
47 0 0         if ( $c->config->{session}->{rewrite} ) {
48 0           my $redirect = $c->response->redirect;
49 0 0         $c->response->redirect( $c->uri($redirect) ) if $redirect;
50             }
51            
52 0 0         if ( my $sid = $c->sessionid ) {
53             # Always set the cookie for the session response, even if it already exists,
54             # this way we set a new expiration time.
55 0 0         $c->response->cookies->{$cookie_name} = {
56             value => $sid,
57              
58             map {
59 0           ((defined($c->config->{session}->{$_})) ? ($_ => $c->config->{session}->{$_}) : ())
60             } qw(expires domain path secure),
61             };
62              
63 0 0         if ( $c->config->{session}->{rewrite} ) {
64             my $finder = URI::Find->new(
65             sub {
66 0     0     my ( $uri, $orig ) = @_;
67 0           my $base = $c->request->base;
68 0 0         return $orig unless $orig =~ /^$base/;
69 0 0         return $orig if $uri->path =~ /\/-\//;
70 0           return $c->uri($orig);
71             }
72 0           );
73 0 0         $finder->find( \$c->res->{body} ) if $c->res->body;
74             }
75             }
76              
77 0           untie(%{$c->{session}});
  0            
78 0           delete $c->{session};
79              
80 0           return $c->NEXT::finalize(@_);
81             }
82              
83             =head3 prepare_action
84              
85             =cut
86              
87             sub prepare_action {
88 0     0 1   my $c = shift;
89 0   0       my $cookie_name = $c->config->{session}{cookie_name} || 'session';
90 0 0         if ( $c->request->path =~ /^(.*)\/\-\/(.+)$/ ) {
91 0           $c->request->path($1);
92 0           $c->sessionid($2);
93 0 0         $c->log->debug(qq/Found sessionid "$2" in path/) if $c->debug;
94             }
95 0 0         if ( my $cookie = $c->request->cookies->{$cookie_name} ) {
96 0           my $sid = $cookie->value;
97 0           $c->sessionid($sid);
98 0 0         $c->log->debug(qq/Found sessionid "$sid" in cookie/) if $c->debug;
99             }
100              
101 0           $c->NEXT::prepare_action(@_);
102             }
103              
104             =head3 session_clear
105              
106             Clear the existing session from storage and create a new session.
107              
108             =cut
109              
110             sub session_clear {
111 0     0 1   my $c = shift;
112            
113 0 0         if($c->{session}) {
114 0           tied(%{$c->{session}})->delete;
  0            
115 0           untie($c->{session});
116 0           delete $c->{session};
117             }
118              
119 0           my $session = {};
120              
121 0           eval {
122 0           my $sid;
123 0           tie %{$session}, 'Apache::Session::Flex', undef, $c->config->{session};
  0            
124 0           $c->sessionid($sid = $session->{_session_id});
125 0 0         $c->log->debug(qq/Created session "$sid"/) if $c->debug;
126             };
127 0 0         if($@) {
128 0           die("Failed to create new session");
129             }
130              
131 0           return $c->{session} = $session;
132             }
133              
134             =head3 session
135              
136             Return the session as a hash reference. If a session id was found via a URL or cookie from the client
137             it will be used to retrieve the data previously stored. If the previous session id was invalid or
138             otherwise unretrievable, create a new session.
139              
140             =cut
141              
142              
143             sub session {
144 0     0 1   my $c = shift;
145              
146 0 0         return $c->{session} if $c->{session};
147 0           my $sid = $c->sessionid;
148              
149              
150 0           my $session = {};
151 0 0         if($sid) {
152             # Load the session.
153 0           eval {
154 0           tie %{$session}, 'Apache::Session::Flex', $sid, $c->config->{session};
  0            
155             };
156 0 0         if($@) {
157             # Handle the error where the session couldn't be retrieved.
158 0           $c->sessionid(undef);
159 0           return $c->session();
160             }
161 0           return $c->{session} = $session;
162             }
163            
164 0           eval {
165 0           tie %{$session}, 'Apache::Session::Flex', undef, $c->config->{session};
  0            
166 0           $c->sessionid($sid = $session->{_session_id});
167 0 0         $c->log->debug(qq/Created session "$sid"/) if $c->debug;
168             };
169 0 0         if($@) {
170 0           die("Failed to create new session");
171             }
172             # Load in the session id.
173 0           $c->{session} = $session;
174              
175 0           return $c->{session};
176             }
177              
178              
179             =head3 setup
180              
181             =cut
182              
183             sub setup {
184 0     0 1   my $self = shift;
185            
186             # Load in the sensible defaults for session storage.
187 0           my %defaults = (
188             Store => 'File',
189             Lock => 'Null',
190             Generate => 'MD5',
191             Serialize => 'Storable',
192              
193             # Defaults for the defaults.
194             Directory => '/tmp/session',
195             LockDirectory => '/var/lock/sessions',
196             );
197              
198 0           while(my ($k, $v) = each %defaults) {
199 0 0         if(!exists($self->config->{session}->{$k})) {
200 0           $self->config->{session}->{$k} = $v;
201             }
202             }
203            
204 0           return $self->NEXT::setup(@_);
205             }
206              
207             =head2 METHODS
208              
209             =head3 session
210              
211             =head3 uri
212              
213             Extends an uri with session id if needed.
214              
215             my $uri = $c->uri('http://localhost/foo');
216              
217             =cut
218              
219             sub uri {
220 0     0 1   my ( $c, $uri ) = @_;
221 0 0         if ( my $sid = $c->sessionid ) {
222 0           $uri = URI->new($uri);
223 0           my $path = $uri->path;
224 0 0         $path .= '/' unless $path =~ /\/$/;
225 0           $uri->path( $path . "-/$sid" );
226 0           return $uri->as_string;
227             }
228 0           return $uri;
229             }
230              
231              
232             =head2 CONFIG OPTIONS
233              
234             All of the options are inheritied from L<Apache::Session::Flex> and
235             various L<Apache::Session> modules such as L<Apache::Session::File>.
236              
237             =head3 rewrite
238              
239             To enable automatic storing of sessions in the url set this to a true value.
240              
241             =head3 expires
242              
243             By default, the session cookie expires when the user closes their browser.
244             To keep a persistent cookie, set an expires config option. Valid values
245             for this option are the same as in L<CGI>, i.e. +1d, +3M, and so on.
246              
247             =head3 domain
248              
249             Set the domain of the session cookie
250              
251             =head3 path
252              
253             Set the path of the session cookie
254              
255             =head3 secure
256              
257             If true only set the session cookie if the request was retrieved via HTTPS.
258              
259             =head3 cookie_name
260              
261             Specify the name of the session cookie
262              
263             =head1 SEE ALSO
264              
265             L<Catalyst> L<Apache::Session> L<Apache::Session::Flex> L<CGI::Cookie>
266              
267             =head1 AUTHOR
268              
269             Rusty Conover C<rconover@infogears.com>
270              
271             Patched by:
272              
273             Andy Grundman C<andy@hybridized.org>
274              
275             John Beppu C<beppu@somebox.com>
276              
277             Based off of L<Catalyst::Plugin::Session::FastMmap> by:
278              
279             Sebastian Riedel, C<sri@cpan.org>
280             Marcus Ramberg C<mramberg@cpan.org>
281              
282             =head1 COPYRIGHT
283              
284             This program is free software, you can redistribute it and/or modify it
285             under the same terms as Perl itself.
286              
287             =cut
288              
289             1;