File Coverage

blib/lib/Net/HTTPServer/Session.pm
Criterion Covered Total %
statement 80 80 100.0
branch 18 30 60.0
condition 7 12 58.3
subroutine 16 16 100.0
pod 5 6 83.3
total 126 144 87.5


line stmt bran cond sub pod time code
1             ##############################################################################
2             #
3             # This library is free software; you can redistribute it and/or
4             # modify it under the terms of the GNU Library General Public
5             # License as published by the Free Software Foundation; either
6             # version 2 of the License, or (at your option) any later version.
7             #
8             # This library is distributed in the hope that it will be useful,
9             # but WITHOUT ANY WARRANTY; without even the implied warranty of
10             # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11             # Library General Public License for more details.
12             #
13             # You should have received a copy of the GNU Library General Public
14             # License along with this library; if not, write to the
15             # Free Software Foundation, Inc., 59 Temple Place - Suite 330,
16             # Boston, MA 02111-1307, USA.
17             #
18             # Copyright (C) 2003-2005 Ryan Eatmon
19             #
20             ##############################################################################
21             package Net::HTTPServer::Session;
22              
23             =head1 NAME
24              
25             Net::HTTPServer::Session
26              
27             =head1 SYNOPSIS
28              
29             Net::HTTPServer::Session handles server side client sessions
30            
31             =head1 DESCRIPTION
32              
33             Net::HTTPServer::Session provides a server side data store for client
34             specific sessions. It uses a cookie stored on the browser to tell
35             the server which session to restore to the user. This is modelled
36             after the PHP session concept. The session is valid for 4 hours from
37             the last time the cookie was sent.
38              
39             =head1 EXAMPLES
40              
41             sub pageHandler
42             {
43             my $request = shift;
44            
45             my $session = $request->Session();
46              
47             my $response = $request->Response();
48              
49             # Logout
50             $session->Destroy() if $request->Env("logout");
51              
52             $response->Print("Hi there");
53            
54             # If the user specified a username on the URL, then save it.
55             if ($request->Env("username"))
56             {
57             $session->Set("username",$request->Env("username"));
58             }
59            
60             # If there is a saved username, then use it.
61             if ($session->Get("username"))
62             {
63             $response->Print("Hello, ",$session->Get("username"),"!");
64             }
65             else
66             {
67             $response->Print("Hello, stranger!");
68             }
69              
70             $response->Print("");
71              
72             return $response;
73             }
74              
75             The above would behave as follows:
76              
77             http://server/page - Hello, stranger!
78             http://server/page?username=Bob - Hello, Bob!
79             http://server/page - Hello, Bob!
80             http://server/page?username=Fred - Hello, Fred!
81             http://server/page - Hello, Fred!
82             http://server/page?logout=1 - Hello, stranger!
83             http://server/page - Hello, stranger!
84              
85             =head1 METHODS
86              
87             =head2 Delete(var)
88              
89             Delete the specified variable from the session.
90              
91             =head2 Destroy()
92              
93             Destroy the session. The server side data is deleted and the cookie
94             will be expired.
95              
96             =head2 Exists(var)
97              
98             Returns if the specified variable exists in the sesion.
99              
100             =head2 Get(var)
101              
102             Return the value of the specified variable from the session if it
103             exists, undef otherwise.
104              
105             =head2 Set(var,value)
106              
107             Store the specified value (scalar or reference to any Perl data
108             structure) in the session.
109              
110             =head1 AUTHOR
111              
112             Ryan Eatmon
113              
114             =head1 COPYRIGHT
115              
116             Copyright (c) 2003-2005 Ryan Eatmon . All rights
117             reserved. This program is free software; you can redistribute it
118             and/or modify it under the same terms as Perl itself.
119              
120             =cut
121            
122 4     4   27 use strict;
  4         9  
  4         204  
123 4     4   26 use Carp;
  4         9  
  4         452  
124 4     4   5052 use Data::Dumper;
  4         47063  
  4         378  
125              
126 4     4   37 use vars qw ( $VERSION $SESSION_COUNT %data );
  4         9  
  4         3691  
127              
128             $VERSION = "1.0.3";
129              
130             $SESSION_COUNT = 0;
131              
132             sub new
133             {
134 3     3 0 1065 my $proto = shift;
135 3   33     24 my $class = ref($proto) || $proto;
136 3         9 my $self = { };
137            
138 3         11 bless($self, $proto);
139              
140 3         15 my (%args) = @_;
141            
142 3         18 $self->{ARGS} = \%args;
143              
144 3         19 $self->{KEY} = $self->_arg("key",undef);
145 3         10 $self->{SERVER} = $self->_arg("server",undef);
146              
147 3 50       14 return unless $self->{SERVER}->{CFG}->{SESSIONS};
148              
149 3 50 66     53 $self->{KEY} = $self->_genkey()
      66        
150             if (!defined($self->{KEY}) ||
151             ($self->{KEY} eq "") ||
152             ($self->{KEY} =~ /\//)
153             );
154              
155 3         17 $self->{FILE} = $self->{SERVER}->{CFG}->{DATADIR}."/".$self->{KEY};
156            
157             #XXX Check that server (Net::HTTPServer object) is defined
158            
159 3         9 $self->{VALID} = 1;
160 3         7 $self->{DATA} = {};
161 3         14 $self->_load();
162              
163 3         12 return $self;
164             }
165              
166              
167             sub Delete
168             {
169 1     1 1 4 my $self = shift;
170 1         3 my $var = shift;
171              
172 1 50       3 return unless $self->Exists($var);
173 1         4 delete($self->{DATA}->{$var});
174             }
175              
176              
177             sub Destroy
178             {
179 1     1 1 4 my $self = shift;
180              
181 1         3 $self->{VALID} = 0;
182             }
183              
184              
185             sub Exists
186             {
187 25     25 1 2093 my $self = shift;
188 25         36 my $var = shift;
189              
190 25 50       53 return unless $self->_valid();
191 25         127 return exists($self->{DATA}->{$var});
192             }
193              
194              
195             sub Get
196             {
197 11     11 1 25 my $self = shift;
198 11         20 my $var = shift;
199              
200 11 50       29 return unless $self->Exists($var);
201 11         75 return $self->{DATA}->{$var};
202             }
203              
204              
205             sub Set
206             {
207 3     3 1 7 my $self = shift;
208 3         6 my $var = shift;
209 3         4 my $value = shift;
210              
211 3 50       10 return unless $self->_valid();
212 3 50       19 $self->{DATA}->{$var} = $value if defined($value);
213             }
214              
215              
216             ###############################################################################
217             #
218             # _arg - if the arg exists then use it, else use the default.
219             #
220             ###############################################################################
221             sub _arg
222             {
223 6     6   9 my $self = shift;
224 6         11 my $arg = shift;
225 6         10 my $default = shift;
226              
227 6 100       36 return (exists($self->{ARGS}->{$arg}) ? $self->{ARGS}->{$arg} : $default);
228             }
229              
230              
231             sub _genkey
232             {
233 1     1   2 my $self = shift;
234              
235 1         2 $SESSION_COUNT++;
236 1         6 my $key = "NetHTTPServerSession".$SESSION_COUNT.$$.time;
237              
238 1 50       5 if ($Net::HTTPServer::DigestMD5 == 1)
239             {
240 1         5 $key = Digest::MD5::md5_hex($key);
241             }
242              
243 1         5 return $key;
244             }
245              
246              
247             sub _key
248             {
249 6     6   14 my $self = shift;
250              
251 6         305 return $self->{KEY};
252             }
253              
254              
255             sub _load
256             {
257 3     3   6 my $self = shift;
258              
259 3 50       12 return unless $self->_valid();
260              
261 3 100       71 return unless (-f $self->{FILE});
262              
263 2         8 undef(%data);
264            
265 2         4 my $data;
266 2 50       82 open(DATA,$self->{FILE}) || return;
267 2         54 read(DATA, $data, (-s DATA));
268 2         21 close(DATA);
269              
270 2         163 eval $data;
271            
272 2 50       12 if (!$@)
273             {
274 2         8 $self->{DATA} = \%data;
275             }
276             }
277              
278              
279             sub _save
280             {
281 2     2   5 my $self = shift;
282              
283 2 100       6 if (!$self->_valid())
284             {
285 1 50       17 unlink($self->{FILE}) if (-f $self->{FILE});
286 1         3 return;
287             }
288              
289 1         14 my $dumper = new Data::Dumper([$self->{DATA}],["*data"]);
290 1         50 $dumper->Purity(1);
291              
292 1         115 open(DATA,">".$self->{FILE});
293 1         7 print DATA $dumper->Dump();
294 1         139 close(DATA);
295             }
296              
297              
298             sub _valid
299             {
300 35     35   49 my $self = shift;
301              
302 35   66     260 return (exists($self->{VALID}) && ($self->{VALID} == 1));
303             }
304              
305              
306             1;
307