Commit | Line | Data |
bf2bce67 |
1 | package Catalyst::Plugin::Session::FastMmap; |
2 | |
3 | use strict; |
4 | use base qw/Class::Data::Inheritable Class::Accessor::Fast/; |
5 | use NEXT; |
6 | use Cache::FastMmap; |
7 | use Digest::MD5; |
8 | use URI; |
9 | use URI::Find; |
10 | use File::Temp 'tempdir'; |
11 | |
c4390601 |
12 | our $VERSION = '0.13'; |
bf2bce67 |
13 | |
14 | __PACKAGE__->mk_classdata('_session'); |
15 | __PACKAGE__->mk_accessors('sessionid'); |
16 | |
17 | =head1 NAME |
18 | |
19 | Catalyst::Plugin::Session::FastMmap - FastMmap sessions for Catalyst |
20 | |
21 | =head1 SYNOPSIS |
22 | |
23 | use Catalyst 'Session::FastMmap'; |
b2f8df5e |
24 | |
25 | MyApp->config->{session} = { |
26 | expires => 3600, |
27 | rewrite => 1, |
28 | storage => '/tmp/session' |
29 | }; |
bf2bce67 |
30 | |
31 | $c->session->{foo} = 'bar'; |
32 | print $c->sessionid; |
33 | |
34 | =head1 DESCRIPTION |
35 | |
57dbf608 |
36 | C<Catalyst::Plugin::Session::FastMmap> is a fast session plugin for |
37 | Catalyst that uses an mmap'ed file to act as a shared memory |
38 | interprocess cache. It is based on C<Cache::FastMMap>. |
39 | |
bf2bce67 |
40 | |
41 | =head2 EXTENDED METHODS |
42 | |
57dbf608 |
43 | =over 4 |
44 | |
45 | =item finalize |
bf2bce67 |
46 | |
47 | =cut |
48 | |
49 | sub finalize { |
b2f8df5e |
50 | my $c = shift; |
51 | if ( $c->config->{session}->{rewrite} ) { |
ad142f4c |
52 | my $redirect = $c->response->redirect; |
53 | $c->response->redirect( $c->uri($redirect) ) if $redirect; |
54 | } |
bf2bce67 |
55 | if ( my $sid = $c->sessionid ) { |
56 | $c->_session->set( $sid, $c->session ); |
57 | my $set = 1; |
58 | if ( my $cookie = $c->request->cookies->{session} ) { |
59 | $set = 0 if $cookie->value eq $sid; |
60 | } |
c9fb61f3 |
61 | if ( $set ) { |
62 | $c->response->cookies->{session} = { |
c4390601 |
63 | value => $sid |
c9fb61f3 |
64 | }; |
65 | } |
b2f8df5e |
66 | if ( $c->config->{session}->{rewrite} ) { |
67 | my $finder = URI::Find->new( |
68 | sub { |
69 | my ( $uri, $orig ) = @_; |
70 | my $base = $c->request->base; |
71 | return $orig unless $orig =~ /^$base/; |
72 | return $orig if $uri->path =~ /\/-\//; |
73 | return $c->uri($orig); |
74 | } |
75 | ); |
0850f14b |
76 | $finder->find( \$c->res->{body} ) if $c->res->body; |
58c05d1a |
77 | } |
bf2bce67 |
78 | } |
79 | return $c->NEXT::finalize(@_); |
80 | } |
81 | |
57dbf608 |
82 | =item prepare_action |
bf2bce67 |
83 | |
84 | =cut |
85 | |
86 | sub prepare_action { |
87 | my $c = shift; |
88 | if ( $c->request->path =~ /^(.*)\/\-\/(.+)$/ ) { |
89 | $c->request->path($1); |
90 | $c->sessionid($2); |
91 | $c->log->debug(qq/Found sessionid "$2" in path/) if $c->debug; |
92 | } |
93 | if ( my $cookie = $c->request->cookies->{session} ) { |
94 | my $sid = $cookie->value; |
95 | $c->sessionid($sid); |
96 | $c->log->debug(qq/Found sessionid "$sid" in cookie/) if $c->debug; |
97 | } |
98 | $c->NEXT::prepare_action(@_); |
99 | } |
100 | |
101 | sub session { |
102 | my $c = shift; |
103 | return $c->{session} if $c->{session}; |
104 | my $sid = $c->sessionid; |
617a86d6 |
105 | if ( $sid |
106 | && $c->_session |
107 | && ( $c->{session} = $c->_session->get($sid) ) ) |
108 | { |
bf2bce67 |
109 | $c->log->debug(qq/Found session "$sid"/) if $c->debug; |
110 | return $c->{session}; |
111 | } |
112 | else { |
113 | my $sid = Digest::MD5::md5_hex( time, rand, $$, 'catalyst' ); |
114 | $c->sessionid($sid); |
115 | $c->log->debug(qq/Created session "$sid"/) if $c->debug; |
116 | return $c->{session} = {}; |
117 | } |
118 | } |
119 | |
57dbf608 |
120 | =item setup |
121 | |
122 | Sets up the session cache file. |
bf2bce67 |
123 | |
124 | =cut |
125 | |
126 | sub setup { |
b2f8df5e |
127 | my $self = shift; |
128 | $self->config->{session}->{storage} ||= '/tmp/session'; |
6f9d2cbb |
129 | $self->config->{session}->{expires} ||= 60 * 60 * 24; |
b2f8df5e |
130 | $self->config->{session}->{rewrite} ||= 0; |
131 | |
bf2bce67 |
132 | $self->_session( |
133 | Cache::FastMmap->new( |
b2f8df5e |
134 | share_file => $self->config->{session}->{storage}, |
135 | expire_time => $self->config->{session}->{expires} |
bf2bce67 |
136 | ) |
137 | ); |
b2f8df5e |
138 | |
bf2bce67 |
139 | return $self->NEXT::setup(@_); |
140 | } |
141 | |
57dbf608 |
142 | =back |
143 | |
bf2bce67 |
144 | =head2 METHODS |
145 | |
57dbf608 |
146 | =over 4 |
147 | |
148 | =item session |
bf2bce67 |
149 | |
57dbf608 |
150 | =item uri |
bf2bce67 |
151 | |
152 | Extends an uri with session id if needed. |
153 | |
154 | my $uri = $c->uri('http://localhost/foo'); |
155 | |
156 | =cut |
157 | |
158 | sub uri { |
159 | my ( $c, $uri ) = @_; |
160 | if ( my $sid = $c->sessionid ) { |
161 | $uri = URI->new($uri); |
162 | my $path = $uri->path; |
163 | $path .= '/' unless $path =~ /\/$/; |
164 | $uri->path( $path . "-/$sid" ); |
165 | return $uri->as_string; |
166 | } |
167 | return $uri; |
168 | } |
169 | |
57dbf608 |
170 | =back |
171 | |
58c05d1a |
172 | =head2 CONFIG OPTIONS |
173 | |
57dbf608 |
174 | =over 4 |
175 | |
176 | =item rewrite |
177 | |
178 | If set to a true value sessions are automatically stored in the url; |
179 | defaults to false. |
180 | |
181 | =item storage |
182 | |
183 | Specifies the file to be used for the sharing of session data; |
184 | defaults to C</tmp/session>. |
58c05d1a |
185 | |
57dbf608 |
186 | Note that the file will be created with mode 0640, which means that it |
187 | will only be writeable by processes running with the same uid as the |
188 | process that creates the file. If this may be a problem, for example |
189 | if you may try to debug the program as one user and run it as another, |
190 | specify a filename like C<< /tmp/session-$> >>, which includes the |
191 | UID of the process in the filename. |
58c05d1a |
192 | |
58c05d1a |
193 | |
57dbf608 |
194 | =item expires |
58c05d1a |
195 | |
57dbf608 |
196 | Specifies the session expiry time in seconds; defaults to 86,400, |
197 | i.e. one day. |
58c05d1a |
198 | |
57dbf608 |
199 | =back |
58c05d1a |
200 | |
bf2bce67 |
201 | =head1 SEE ALSO |
202 | |
57dbf608 |
203 | L<Catalyst>, L<Cache::FastMmap>. |
bf2bce67 |
204 | |
205 | =head1 AUTHOR |
206 | |
57dbf608 |
207 | Sebastian Riedel E<lt>C<sri@cpan.org>E<gt>, |
208 | Marcus Ramberg E<lt>C<mramberg@cpan.org>E<gt>, |
209 | Andrew Ford E<lt>C<andrewf@cpan.org>E<gt> |
bf2bce67 |
210 | |
211 | =head1 COPYRIGHT |
212 | |
bfeb5ca0 |
213 | This program is free software, you can redistribute it and/or modify it |
214 | under the same terms as Perl itself. |
bf2bce67 |
215 | |
216 | =cut |
217 | |
218 | 1; |