← Index
NYTProf Performance Profile   « line view »
For ./view
  Run on Fri Jul 31 18:42:36 2015
Reported on Fri Jul 31 18:48:14 2015

Filename/usr/share/perl5/vendor_perl/CGI/Session.pm
StatementsExecuted 17 statements in 3.49ms
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
111270µs331µsCGI::Session::::BEGIN@7CGI::Session::BEGIN@7
11112µs25µsCGI::Session::::BEGIN@5CGI::Session::BEGIN@5
1118µs31µsCGI::Session::::BEGIN@6CGI::Session::BEGIN@6
0000s0sCGI::Session::::DESTROYCGI::Session::DESTROY
0000s0sCGI::Session::::__ANON__[:448]CGI::Session::__ANON__[:448]
0000s0sCGI::Session::::_driverCGI::Session::_driver
0000s0sCGI::Session::::_id_generatorCGI::Session::_id_generator
0000s0sCGI::Session::::_ip_matchesCGI::Session::_ip_matches
0000s0sCGI::Session::::_load_pluggablesCGI::Session::_load_pluggables
0000s0sCGI::Session::::_reset_statusCGI::Session::_reset_status
0000s0sCGI::Session::::_serializerCGI::Session::_serializer
0000s0sCGI::Session::::_set_query_or_sidCGI::Session::_set_query_or_sid
0000s0sCGI::Session::::_set_statusCGI::Session::_set_status
0000s0sCGI::Session::::_str2secondsCGI::Session::_str2seconds
0000s0sCGI::Session::::_test_statusCGI::Session::_test_status
0000s0sCGI::Session::::_unset_statusCGI::Session::_unset_status
0000s0sCGI::Session::::atimeCGI::Session::atime
0000s0sCGI::Session::::clearCGI::Session::clear
0000s0sCGI::Session::::closeCGI::Session::close
0000s0sCGI::Session::::cookieCGI::Session::cookie
0000s0sCGI::Session::::ctimeCGI::Session::ctime
0000s0sCGI::Session::::datarefCGI::Session::dataref
0000s0sCGI::Session::::deleteCGI::Session::delete
0000s0sCGI::Session::::dumpCGI::Session::dump
0000s0sCGI::Session::::etimeCGI::Session::etime
0000s0sCGI::Session::::expireCGI::Session::expire
0000s0sCGI::Session::::findCGI::Session::find
0000s0sCGI::Session::::flushCGI::Session::flush
0000s0sCGI::Session::::http_headerCGI::Session::http_header
0000s0sCGI::Session::::idCGI::Session::id
0000s0sCGI::Session::::importCGI::Session::import
0000s0sCGI::Session::::is_emptyCGI::Session::is_empty
0000s0sCGI::Session::::is_expiredCGI::Session::is_expired
0000s0sCGI::Session::::is_newCGI::Session::is_new
0000s0sCGI::Session::::loadCGI::Session::load
0000s0sCGI::Session::::load_paramCGI::Session::load_param
0000s0sCGI::Session::::nameCGI::Session::name
0000s0sCGI::Session::::newCGI::Session::new
0000s0sCGI::Session::::paramCGI::Session::param
0000s0sCGI::Session::::parse_dsnCGI::Session::parse_dsn
0000s0sCGI::Session::::queryCGI::Session::query
0000s0sCGI::Session::::remote_addrCGI::Session::remote_addr
0000s0sCGI::Session::::save_paramCGI::Session::save_param
0000s0sCGI::Session::::traceCGI::Session::trace
0000s0sCGI::Session::::tracemsgCGI::Session::tracemsg
Call graph for these subroutines as a Graphviz dot language file.
Line State
ments
Time
on line
Calls Time
in subs
Code
1package CGI::Session;
2
3# $Id: Session.pm 430 2008-07-16 00:36:15Z markstos $
4
5226µs238µs
# spent 25µs (12+13) within CGI::Session::BEGIN@5 which was called: # once (12µs+13µs) by Foswiki::LoginManager::BEGIN@57 at line 5
use strict;
# spent 25µs making 1 call to CGI::Session::BEGIN@5 # spent 13µs making 1 call to strict::import
6233µs254µs
# spent 31µs (8+23) within CGI::Session::BEGIN@6 which was called: # once (8µs+23µs) by Foswiki::LoginManager::BEGIN@57 at line 6
use Carp;
# spent 31µs making 1 call to CGI::Session::BEGIN@6 # spent 23µs making 1 call to Exporter::import
723.42ms1331µs
# spent 331µs (270+61) within CGI::Session::BEGIN@7 which was called: # once (270µs+61µs) by Foswiki::LoginManager::BEGIN@57 at line 7
use CGI::Session::ErrorHandler;
# spent 331µs making 1 call to CGI::Session::BEGIN@7
8
917µs@CGI::Session::ISA = qw( CGI::Session::ErrorHandler );
101300ns$CGI::Session::VERSION = '4.35';
111100ns$CGI::Session::NAME = 'CGISESSID';
121200ns$CGI::Session::IP_MATCH = 0;
13
14sub STATUS_NEW () { 1 } # denotes session that's just created
15sub STATUS_MODIFIED () { 2 } # denotes session that needs synchronization
16sub STATUS_DELETED () { 4 } # denotes session that needs deletion
17sub STATUS_EXPIRED () { 8 } # denotes session that was expired.
18
19sub import {
20 my ($class, @args) = @_;
21
22 return unless @args;
23
24 ARG:
25 foreach my $arg (@args) {
26 if ($arg eq '-ip_match') {
27 $CGI::Session::IP_MATCH = 1;
28 last ARG;
29 }
30 }
31}
32
33sub new {
34 my ($class, @args) = @_;
35
36 my $self;
37 if (ref $class) {
38 #
39 # Called as an object method as in $session->new()...
40 #
41 $self = bless { %$class }, ref( $class );
42 $class = ref $class;
43 $self->_reset_status();
44 #
45 # Object may still have public data associated with it, but we
46 # don't care about that, since we want to leave that to the
47 # client's disposal. However, if new() was requested on an
48 # expired session, we already know that '_DATA' table is
49 # empty, since it was the job of flush() to empty '_DATA'
50 # after deleting. How do we know flush() was already called on
51 # an expired session? Because load() - constructor always
52 # calls flush() on all to-be expired sessions
53 #
54 }
55 else {
56 #
57 # Called as a class method as in CGI::Session->new()
58 #
59
60 # Start fresh with error reporting. Errors in past objects shouldn't affect this one.
61 $class->set_error('');
62
63 $self = $class->load( @args );
64 if (not defined $self) {
65 return $class->set_error( "new(): failed: " . $class->errstr );
66 }
67 }
68
69 my $dataref = $self->{_DATA};
70 unless ($dataref->{_SESSION_ID}) {
71 #
72 # Absence of '_SESSION_ID' can only signal:
73 # * Expired session: Because load() - constructor is required to
74 # empty contents of _DATA - table
75 # * Unavailable session: Such sessions are the ones that don't
76 # exist on datastore, but are requested by client
77 # * New session: When no specific session is requested to be loaded
78 #
79 my $id = $self->_id_generator()->generate_id(
80 $self->{_DRIVER_ARGS},
81 $self->{_CLAIMED_ID}
82 );
83 unless (defined $id) {
84 return $self->set_error( "Couldn't generate new SESSION-ID" );
85 }
86 $dataref->{_SESSION_ID} = $id;
87 $dataref->{_SESSION_CTIME} = $dataref->{_SESSION_ATIME} = time();
88 $dataref->{_SESSION_REMOTE_ADDR} = $ENV{REMOTE_ADDR} || "";
89 $self->_set_status( STATUS_NEW );
90 }
91 return $self;
92}
93
94sub DESTROY { $_[0]->flush() }
95sub close { $_[0]->flush() }
96
9711µs*param_hashref = \&dataref;
9811µsmy $avoid_single_use_warning = *param_hashref;
99sub dataref { $_[0]->{_DATA} }
100
101sub is_empty { !defined($_[0]->id) }
102
103sub is_expired { $_[0]->_test_status( STATUS_EXPIRED ) }
104
105sub is_new { $_[0]->_test_status( STATUS_NEW ) }
106
107sub id { return defined($_[0]->dataref) ? $_[0]->dataref->{_SESSION_ID} : undef }
108
109# Last Access Time
110sub atime { return defined($_[0]->dataref) ? $_[0]->dataref->{_SESSION_ATIME} : undef }
111
112# Creation Time
113sub ctime { return defined($_[0]->dataref) ? $_[0]->dataref->{_SESSION_CTIME} : undef }
114
115sub _driver {
116 my $self = shift;
117 defined($self->{_OBJECTS}->{driver}) and return $self->{_OBJECTS}->{driver};
118 my $pm = "CGI::Session::Driver::" . $self->{_DSN}->{driver};
119 defined($self->{_OBJECTS}->{driver} = $pm->new( $self->{_DRIVER_ARGS} ))
120 or die $pm->errstr();
121 return $self->{_OBJECTS}->{driver};
122}
123
124sub _serializer {
125 my $self = shift;
126 defined($self->{_OBJECTS}->{serializer}) and return $self->{_OBJECTS}->{serializer};
127 return $self->{_OBJECTS}->{serializer} = "CGI::Session::Serialize::" . $self->{_DSN}->{serializer};
128}
129
130
131sub _id_generator {
132 my $self = shift;
133 defined($self->{_OBJECTS}->{id}) and return $self->{_OBJECTS}->{id};
134 return $self->{_OBJECTS}->{id} = "CGI::Session::ID::" . $self->{_DSN}->{id};
135}
136
137sub _ip_matches {
138 return ( $_[0]->{_DATA}->{_SESSION_REMOTE_ADDR} eq $ENV{REMOTE_ADDR} );
139}
140
141
142# parses the DSN string and returns it as a hash.
143# Notably: Allows unique abbreviations of the keys: driver, serializer and 'id'.
144# Also, keys and values of the returned hash are lower-cased.
145sub parse_dsn {
146 my $self = shift;
147 my $dsn_str = shift;
148 croak "parse_dsn(): usage error" unless $dsn_str;
149
150 require Text::Abbrev;
151 my $abbrev = Text::Abbrev::abbrev( "driver", "serializer", "id" );
152 my %dsn_map = map { split /:/ } (split /;/, $dsn_str);
153 my %dsn = map { $abbrev->{lc $_}, lc $dsn_map{$_} } keys %dsn_map;
154 return \%dsn;
155}
156
157sub query {
158 my $self = shift;
159
160 if ( $self->{_QUERY} ) {
161 return $self->{_QUERY};
162 }
163# require CGI::Session::Query;
164# return $self->{_QUERY} = CGI::Session::Query->new();
165 require CGI;
166 return $self->{_QUERY} = CGI->new();
167}
168
169
170sub name {
171 my $self = shift;
172
173 if (ref $self) {
174 unless ( @_ ) {
175 return $self->{_NAME} || $CGI::Session::NAME;
176 }
177 return $self->{_NAME} = $_[0];
178 }
179
180 $CGI::Session::NAME = $_[0] if @_;
181 return $CGI::Session::NAME;
182}
183
184
185sub dump {
186 my $self = shift;
187
188 require Data::Dumper;
189 my $d = Data::Dumper->new([$self], [ref $self]);
190 $d->Deepcopy(1);
191 return $d->Dump();
192}
193
194
195sub _set_status {
196 my $self = shift;
197 croak "_set_status(): usage error" unless @_;
198 $self->{_STATUS} |= $_ for @_;
199}
200
201
202sub _unset_status {
203 my $self = shift;
204 croak "_unset_status(): usage error" unless @_;
205 $self->{_STATUS} &= ~$_ for @_;
206}
207
208
209sub _reset_status {
210 $_[0]->{_STATUS} = 0;
211}
212
213sub _test_status {
214 return $_[0]->{_STATUS} & $_[1];
215}
216
217
218sub flush {
219 my $self = shift;
220
221 # Would it be better to die or err if something very basic is wrong here?
222 # I'm trying to address the DESTORY related warning
223 # from: http://rt.cpan.org/Ticket/Display.html?id=17541
224 # return unless defined $self;
225
226 return unless $self->id; # <-- empty session
227 return if !defined($self->{_STATUS}) or $self->{_STATUS} == 0; # <-- neither new, nor deleted nor modified
228
229 if ( $self->_test_status(STATUS_NEW) && $self->_test_status(STATUS_DELETED) ) {
230 $self->{_DATA} = {};
231 return $self->_unset_status(STATUS_NEW, STATUS_DELETED);
232 }
233
234 my $driver = $self->_driver();
235 my $serializer = $self->_serializer();
236
237 if ( $self->_test_status(STATUS_DELETED) ) {
238 defined($driver->remove($self->id)) or
239 return $self->set_error( "flush(): couldn't remove session data: " . $driver->errstr );
240 $self->{_DATA} = {}; # <-- removing all the data, making sure
241 # it won't be accessible after flush()
242 return $self->_unset_status(STATUS_DELETED);
243 }
244
245 if ( $self->_test_status(STATUS_NEW) || $self->_test_status(STATUS_MODIFIED) ) {
246 my $datastr = $serializer->freeze( $self->dataref );
247 unless ( defined $datastr ) {
248 return $self->set_error( "flush(): couldn't freeze data: " . $serializer->errstr );
249 }
250 defined( $driver->store($self->id, $datastr) ) or
251 return $self->set_error( "flush(): couldn't store datastr: " . $driver->errstr);
252 $self->_unset_status(STATUS_NEW, STATUS_MODIFIED);
253 }
254 return 1;
255}
256
257sub trace {}
258sub tracemsg {}
259
260sub param {
261 my ($self, @args) = @_;
262
263 if ($self->_test_status( STATUS_DELETED )) {
264 carp "param(): attempt to read/write deleted session";
265 }
266
267 # USAGE: $s->param();
268 # DESC: Returns all the /public/ parameters
269 if (@args == 0) {
270 return grep { !/^_SESSION_/ } keys %{ $self->{_DATA} };
271 }
272 # USAGE: $s->param( $p );
273 # DESC: returns a specific session parameter
274 elsif (@args == 1) {
275 return $self->{_DATA}->{ $args[0] }
276 }
277
278
279 # USAGE: $s->param( -name => $n, -value => $v );
280 # DESC: Updates session data using CGI.pm's 'named param' syntax.
281 # Only public records can be set!
282 my %args = @args;
283 my ($name, $value) = @args{ qw(-name -value) };
284 if (defined $name && defined $value) {
285 if ($name =~ m/^_SESSION_/) {
286
287 carp "param(): attempt to write to private parameter";
288 return undef;
289 }
290 $self->_set_status( STATUS_MODIFIED );
291 return $self->{_DATA}->{ $name } = $value;
292 }
293
294 # USAGE: $s->param(-name=>$n);
295 # DESC: access to session data (public & private) using CGI.pm's 'named parameter' syntax.
296 return $self->{_DATA}->{ $args{'-name'} } if defined $args{'-name'};
297
298 # USAGE: $s->param($name, $value);
299 # USAGE: $s->param($name1 => $value1, $name2 => $value2 [,...]);
300 # DESC: updates one or more **public** records using simple syntax
301 if ((@args % 2) == 0) {
302 my $modified_cnt = 0;
303 ARG_PAIR:
304 while (my ($name, $val) = each %args) {
305 if ( $name =~ m/^_SESSION_/) {
306 carp "param(): attempt to write to private parameter";
307 next ARG_PAIR;
308 }
309 $self->{_DATA}->{ $name } = $val;
310 ++$modified_cnt;
311 }
312 $self->_set_status(STATUS_MODIFIED);
313 return $modified_cnt;
314 }
315
316 # If we reached this far none of the expected syntax were
317 # detected. Syntax error
318 croak "param(): usage error. Invalid syntax";
319}
320
- -
323sub delete { $_[0]->_set_status( STATUS_DELETED ) }
324
325
3261500ns*header = \&http_header;
3271300nsmy $avoid_single_use_warning_again = *header;
328sub http_header {
329 my $self = shift;
330 return $self->query->header(-cookie=>$self->cookie, -type=>'text/html', @_);
331}
332
333sub cookie {
334 my $self = shift;
335
336 my $query = $self->query();
337 my $cookie= undef;
338
339 if ( $self->is_expired ) {
340 $cookie = $query->cookie( -name=>$self->name, -value=>$self->id, -expires=> '-1d', @_ );
341 }
342 elsif ( my $t = $self->expire ) {
343 $cookie = $query->cookie( -name=>$self->name, -value=>$self->id, -expires=> '+' . $t . 's', @_ );
344 }
345 else {
346 $cookie = $query->cookie( -name=>$self->name, -value=>$self->id, @_ );
347 }
348 return $cookie;
349}
350
- -
355sub save_param {
356 my $self = shift;
357 my ($query, $params) = @_;
358
359 $query ||= $self->query();
360 $params ||= [ $query->param ];
361
362 for my $p ( @$params ) {
363 my @values = $query->param($p) or next;
364 if ( @values > 1 ) {
365 $self->param($p, \@values);
366 } else {
367 $self->param($p, $values[0]);
368 }
369 }
370 $self->_set_status( STATUS_MODIFIED );
371}
372
- -
375sub load_param {
376 my $self = shift;
377 my ($query, $params) = @_;
378
379 $query ||= $self->query();
380 $params ||= [ $self->param ];
381
382 for ( @$params ) {
383 $query->param(-name=>$_, -value=>$self->param($_));
384 }
385}
386
387
388sub clear {
389 my $self = shift;
390 my $params = shift;
391 #warn ref($params);
392 if (defined $params) {
393 $params = [ $params ] unless ref $params;
394 }
395 else {
396 $params = [ $self->param ];
397 }
398
399 for ( grep { ! /^_SESSION_/ } @$params ) {
400 delete $self->{_DATA}->{$_};
401 }
402 $self->_set_status( STATUS_MODIFIED );
403}
404
405
406sub find {
407 my $class = shift;
408 my ($dsn, $coderef, $dsn_args);
409
410 # find( \%code )
411 if ( @_ == 1 ) {
412 $coderef = $_[0];
413 }
414 # find( $dsn, \&code, \%dsn_args )
415 else {
416 ($dsn, $coderef, $dsn_args) = @_;
417 }
418
419 unless ( $coderef && ref($coderef) && (ref $coderef eq 'CODE') ) {
420 croak "find(): usage error.";
421 }
422
423 my $driver;
424 if ( $dsn ) {
425 my $hashref = $class->parse_dsn( $dsn );
426 $driver = $hashref->{driver};
427 }
428 $driver ||= "file";
429 my $pm = "CGI::Session::Driver::" . ($driver =~ /(.*)/)[0];
430 eval "require $pm";
431 if (my $errmsg = $@ ) {
432 return $class->set_error( "find(): couldn't load driver." . $errmsg );
433 }
434
435 my $driver_obj = $pm->new( $dsn_args );
436 unless ( $driver_obj ) {
437 return $class->set_error( "find(): couldn't create driver object. " . $pm->errstr );
438 }
439
440 my $dont_update_atime = 0;
441 my $driver_coderef = sub {
442 my ($sid) = @_;
443 my $session = $class->load( $dsn, $sid, $dsn_args, $dont_update_atime );
444 unless ( $session ) {
445 return $class->set_error( "find(): couldn't load session '$sid'. " . $class->errstr );
446 }
447 $coderef->( $session );
448 };
449
450 defined($driver_obj->traverse( $driver_coderef ))
451 or return $class->set_error( "find(): traverse seems to have failed. " . $driver_obj->errstr );
452 return 1;
453}
454
455# $Id: Session.pm 430 2008-07-16 00:36:15Z markstos $
456
457=pod
458
459=head1 NAME
460
461CGI::Session - persistent session data in CGI applications
462
463=head1 SYNOPSIS
464
465 # Object initialization:
466 use CGI::Session;
467 $session = new CGI::Session();
468
469 $CGISESSID = $session->id();
470
471 # Send proper HTTP header with cookies:
472 print $session->header();
473
474 # Storing data in the session:
475 $session->param('f_name', 'Sherzod');
476 # or
477 $session->param(-name=>'l_name', -value=>'Ruzmetov');
478
479 # Flush the data from memory to the storage driver at least before your
480 # program finishes since auto-flushing can be unreliable.
481 # Warning: A bug in your logic whereby the DBI handle has gone
482 # out of scope before flush() is called means flush() won't work
483 # (when the session is a database session), so don't do that.
484 $session->flush();
485
486 # Retrieving data:
487 my $f_name = $session->param('f_name');
488 # or
489 my $l_name = $session->param(-name=>'l_name');
490
491 # Clearing a certain session parameter:
492 $session->clear(["l_name", "f_name"]);
493
494 # Expire '_is_logged_in' flag after 10 idle minutes:
495 $session->expire('is_logged_in', '+10m')
496
497 # Expire the session itself after 1 idle hour:
498 $session->expire('+1h');
499
500 # Delete the session for good:
501 $session->delete();
502 $session->flush(); # Recommended practice says use flush() after delete().
503
504=head1 DESCRIPTION
505
506CGI-Session is a Perl5 library that provides an easy, reliable and modular session management system across HTTP requests.
507Persistency is a key feature for such applications as shopping carts, login/authentication routines, and application that
508need to carry data across HTTP requests. CGI::Session does that and many more.
509
510=head1 A Warning about Auto-flushing
511
512As mentioned above in the Synopsis, auto-flushing can be unreliable.
513
514Consequently, you should regard it as mandatory that sessions always need to be explicitly flushed before the
515program exits.
516
517For instance, in a C<CGI::Application>-based program, C<sub teardown()> would be the appropriate place to do this.
518
519This is all part of what might be called "Object life-cycle 'v' Program life-cycle".
520
521In the simplest case the program has one object of type CGI::Session, and that object is destroyed when the
522program exits.
523
524If, however, you wish to delete objects explicitly, then each call to C<delete()> should be followed by a call
525to C<flush()>.
526
527Warning: A bug in your logic whereby the DBI handle has gone out
528out of scope before flush() is called means flush() won't work
529(when the session is a database session), so don't do that.
530
531For more detail, see the discussion of the C<delete()> method, below.
532
533=head1 A Warning about UTF8
534
535Trying to use UTF8 in a program which uses CGI::Session has lead to problems. See RT#21981 and RT#28516.
536
537In the first case the user tried "use encoding 'utf8';" in the program, and in the second case the user tried
538"$dbh->do(qq|set names 'utf8'|);".
539
540Until this problem is understood and corrected, users are advised to avoid UTF8 in conjunction with CGI::Session.
541
542For details, see: http://rt.cpan.org/Public/Bug/Display.html?id=28516 (and ...id=21981).
543
544=head1 TRANSLATIONS
545
546This document is also available in Japanese.
547
548=over 4
549
550=item o
551
552Translation based on 4.14: http://digit.que.ne.jp/work/index.cgi?Perldoc/ja
553
554=item o
555
556Translation based on 3.11, including Cookbook and Tutorial: http://perldoc.jp/docs/modules/CGI-Session-3.11/
557
558=back
559
560=head1 TO LEARN MORE
561
562Current manual is optimized to be used as a quick reference. To learn more both about the philosophy and CGI::Session
563programming style, consider the following:
564
565=over 4
566
567=item *
568
569L<CGI::Session::Tutorial|CGI::Session::Tutorial> - extended CGI::Session manual. Also includes library architecture and driver specifications.
570
571=item *
572
573We also provide mailing lists for CGI::Session users. To subscribe to the list or browse the archives visit https://lists.sourceforge.net/lists/listinfo/cgi-session-user
574
575=item *
576
577B<RFC 2965> - "HTTP State Management Mechanism" found at ftp://ftp.isi.edu/in-notes/rfc2965.txt
578
579=item *
580
581L<CGI|CGI> - standard CGI library
582
583=item *
584
585L<Apache::Session|Apache::Session> - another fine alternative to CGI::Session.
586
587=back
588
589=head1 METHODS
590
591Following is the overview of all the available methods accessible via CGI::Session object.
592
593=head2 new()
594
595=head2 new( $sid )
596
597=head2 new( $query )
598
599=head2 new( $dsn, $query||$sid )
600
601=head2 new( $dsn, $query||$sid, \%dsn_args )
602
603=head2 new( $dsn, $query||$sid, \%dsn_args, \%session_params )
604
605Constructor. Returns new session object, or undef on failure. Error message is accessible through L<errstr() - class method|CGI::Session::ErrorHandler/errstr>. If called on an already initialized session will re-initialize the session based on already configured object. This is only useful after a call to L<load()|/"load">.
606
607Can accept up to three arguments, $dsn - Data Source Name, $query||$sid - query object OR a string representing session id, and finally, \%dsn_args, arguments used by $dsn components.
608
609If called without any arguments, $dsn defaults to I<driver:file;serializer:default;id:md5>, $query||$sid defaults to C<< CGI->new() >>, and C<\%dsn_args> defaults to I<undef>.
610
611If called with a single argument, it will be treated either as C<$query> object, or C<$sid>, depending on its type. If argument is a string , C<new()> will treat it as session id and will attempt to retrieve the session from data store. If it fails, will create a new session id, which will be accessible through L<id() method|/"id">. If argument is an object, L<cookie()|CGI/cookie> and L<param()|CGI/param> methods will be called on that object to recover a potential C<$sid> and retrieve it from data store. If it fails, C<new()> will create a new session id, which will be accessible through L<id() method|/"id">. C<name()> will define the name of the query parameter and/or cookie name to be requested, defaults to I<CGISESSID>.
612
613If called with two arguments first will be treated as $dsn, and second will be treated as $query or $sid or undef, depending on its type. Some examples of this syntax are:
614
615 $s = CGI::Session->new("driver:mysql", undef);
616 $s = CGI::Session->new("driver:sqlite", $sid);
617 $s = CGI::Session->new("driver:db_file", $query);
618 $s = CGI::Session->new("serializer:storable;id:incr", $sid);
619 # etc...
620
621Briefly, C<new()> will return an initialized session object with a valid id, whereas C<load()> may return
622an empty session object with an undefined id.
623
624Tests are provided (t/new_with_undef.t and t/load_with_undef.t) to clarify the result of calling C<new()> and C<load()>
625with undef, or with an initialized CGI object with an undefined or fake CGISESSID.
626
627You are strongly advised to run the old-fashioned 'make test TEST_FILES=t/new_with_undef.t TEST_VERBOSE=1'
628or the new-fangled 'prove -v t/new_with_undef.t', for both new*.t and load*.t, and examine the output.
629
630Following data source components are supported:
631
632=over 4
633
634=item *
635
636B<driver> - CGI::Session driver. Available drivers are L<file|CGI::Session::Driver::file>, L<db_file|CGI::Session::Driver::db_file>, L<mysql|CGI::Session::Driver::mysql> and L<sqlite|CGI::Session::Driver::sqlite>. Third party drivers are welcome. For driver specs consider L<CGI::Session::Driver|CGI::Session::Driver>
637
638=item *
639
640B<serializer> - serializer to be used to encode the data structure before saving
641in the disk. Available serializers are L<storable|CGI::Session::Serialize::storable>, L<freezethaw|CGI::Session::Serialize::freezethaw> and L<default|CGI::Session::Serialize::default>. Default serializer will use L<Data::Dumper|Data::Dumper>.
642
643=item *
644
645B<id> - ID generator to use when new session is to be created. Available ID generator is L<md5|CGI::Session::ID::md5>
646
647=back
648
649For example, to get CGI::Session store its data using DB_File and serialize data using FreezeThaw:
650
651 $s = new CGI::Session("driver:DB_File;serializer:FreezeThaw", undef);
652
653If called with three arguments, first two will be treated as in the previous example, and third argument will be C<\%dsn_args>, which will be passed to C<$dsn> components (namely, driver, serializer and id generators) for initialization purposes. Since all the $dsn components must initialize to some default value, this third argument should not be required for most drivers to operate properly.
654
655If called with four arguments, the first three match previous examples. The fourth argument must be a hash reference with parameters to be used by the CGI::Session object. (see \%session_params above )
656
657The following is a list of the current keys:
658
659=over
660
661=item *
662
663B<name> - Name to use for the cookie/query parameter name. This defaults to CGISESSID. This can be altered or accessed by the C<name> accessor.
664
665=back
666
667undef is acceptable as a valid placeholder to any of the above arguments, which will force default behavior.
668
669=head2 load()
670
671=head2 load( $query||$sid )
672
673=head2 load( $dsn, $query||$sid )
674
675=head2 load( $dsn, $query, \%dsn_args )
676
677=head2 load( $dsn, $query, \%dsn_args, \%session_params )
678
679Accepts the same arguments as new(), and also returns a new session object, or
680undef on failure. The difference is, L<new()|/"new"> can create a new session if
681it detects expired and non-existing sessions, but C<load()> does not.
682
683C<load()> is useful to detect expired or non-existing sessions without forcing the library to create new sessions. So now you can do something like this:
684
685 $s = CGI::Session->load() or die CGI::Session->errstr();
686 if ( $s->is_expired ) {
687 print $s->header(),
688 $cgi->start_html(),
689 $cgi->p("Your session timed out! Refresh the screen to start new session!")
690 $cgi->end_html();
691 exit(0);
692 }
693
694 if ( $s->is_empty ) {
695 $s = $s->new() or die $s->errstr;
696 }
697
698Notice: All I<expired> sessions are empty, but not all I<empty> sessions are expired!
699
700Briefly, C<new()> will return an initialized session object with a valid id, whereas C<load()> may return
701an empty session object with an undefined id.
702
703Tests are provided (t/new_with_undef.t and t/load_with_undef.t) to clarify the result of calling C<new()> and C<load()>
704with undef, or with an initialized CGI object with an undefined or fake CGISESSID.
705
706You are strongly advised to run the old-fashioned 'make test TEST_FILES=t/new_with_undef.t TEST_VERBOSE=1'
707or the new-fangled 'prove -v t/new_with_undef.t', for both new*.t and load*.t, and examine the output.
708
709=cut
710
711# pass a true value as the fourth parameter if you want to skip the changing of
712# access time This isn't documented more formally, because it only called by
713# find().
714sub load {
715 my $class = shift;
716 return $class->set_error( "called as instance method") if ref $class;
717 return $class->set_error( "Too many arguments provided to load()") if @_ > 5;
718
719 my $self = bless {
720 _DATA => {
721 _SESSION_ID => undef,
722 _SESSION_CTIME => undef,
723 _SESSION_ATIME => undef,
724 _SESSION_REMOTE_ADDR => $ENV{REMOTE_ADDR} || "",
725 #
726 # Following two attributes may not exist in every single session, and declaring
727 # them now will force these to get serialized into database, wasting space. But they
728 # are here to remind the coder of their purpose
729 #
730# _SESSION_ETIME => undef,
731# _SESSION_EXPIRE_LIST => {}
732 }, # session data
733 _DSN => {}, # parsed DSN params
734 _OBJECTS => {}, # keeps necessary objects
735 _DRIVER_ARGS=> {}, # arguments to be passed to driver
736 _CLAIMED_ID => undef, # id **claimed** by client
737 _STATUS => 0, # status of the session object
738 _QUERY => undef # query object
739 }, $class;
740
741 my ($dsn,$query_or_sid,$dsn_args,$update_atime,$params);
742 # load($query||$sid)
743 if ( @_ == 1 ) {
744 $self->_set_query_or_sid($_[0]);
745 }
746 # Two or more args passed:
747 # load($dsn, $query||$sid)
748 elsif ( @_ > 1 ) {
749 ($dsn, $query_or_sid, $dsn_args,$update_atime) = @_;
750
751 # Make it backwards-compatible (update_atime is an undocumented key in %$params).
752 # In fact, update_atime as a key is not used anywhere in the code as yet.
753 # This patch is part of the patch for RT#33437.
754 if ( ref $update_atime and ref $update_atime eq 'HASH' ) {
755 $params = {%$update_atime};
756 $update_atime = $params->{'update_atime'};
757
758 if ($params->{'name'}) {
759 $self->{_NAME} = $params->{'name'};
760 }
761 }
762
763 # Since $update_atime is not part of the public API
764 # we ignore any value but the one we use internally: 0.
765 if (defined $update_atime and $update_atime ne '0') {
766 return $class->set_error( "Too many arguments to load(). First extra argument was: $update_atime");
767 }
768
769 if ( defined $dsn ) { # <-- to avoid 'Uninitialized value...' warnings
770 $self->{_DSN} = $self->parse_dsn($dsn);
771 }
772 $self->_set_query_or_sid($query_or_sid);
773
774 # load($dsn, $query, \%dsn_args);
775
776 $self->{_DRIVER_ARGS} = $dsn_args if defined $dsn_args;
777
778 }
779
780 $self->_load_pluggables();
781
782 # Did load_pluggable fail? If so, return undef, just like $class->set_error() would
783 return undef if $class->errstr;
784
785 if (not defined $self->{_CLAIMED_ID}) {
786 my $query = $self->query();
787 eval {
788 $self->{_CLAIMED_ID} = $query->cookie( $self->name ) || $query->param( $self->name );
789 };
790 if ( my $errmsg = $@ ) {
791 return $class->set_error( "query object $query does not support cookie() and param() methods: " . $errmsg );
792 }
793 }
794
795 # No session is being requested. Just return an empty session
796 return $self unless $self->{_CLAIMED_ID};
797
798 # Attempting to load the session
799 my $driver = $self->_driver();
800 my $raw_data = $driver->retrieve( $self->{_CLAIMED_ID} );
801 unless ( defined $raw_data ) {
802 return $self->set_error( "load(): couldn't retrieve data: " . $driver->errstr );
803 }
804
805 # Requested session couldn't be retrieved
806 return $self unless $raw_data;
807
808 my $serializer = $self->_serializer();
809 $self->{_DATA} = $serializer->thaw($raw_data);
810 unless ( defined $self->{_DATA} ) {
811 #die $raw_data . "\n";
812 return $self->set_error( "load(): couldn't thaw() data using $serializer:" .
813 $serializer->errstr );
814 }
815 unless (defined($self->{_DATA}) && ref ($self->{_DATA}) && (ref $self->{_DATA} eq 'HASH') &&
816 defined($self->{_DATA}->{_SESSION_ID}) ) {
817 return $self->set_error( "Invalid data structure returned from thaw()" );
818 }
819
820 # checking if previous session ip matches current ip
821 if($CGI::Session::IP_MATCH) {
822 unless($self->_ip_matches) {
823 $self->_set_status( STATUS_DELETED );
824 $self->flush;
825 return $self;
826 }
827 }
828
829 # checking for expiration ticker
830 if ( $self->{_DATA}->{_SESSION_ETIME} ) {
831 if ( ($self->{_DATA}->{_SESSION_ATIME} + $self->{_DATA}->{_SESSION_ETIME}) <= time() ) {
832 $self->_set_status( STATUS_EXPIRED ); # <-- so client can detect expired sessions
833 $self->_set_status( STATUS_DELETED ); # <-- session should be removed from database
834 $self->flush(); # <-- flush() will do the actual removal!
835 return $self;
836 }
837 }
838
839 # checking expiration tickers of individuals parameters, if any:
840 my @expired_params = ();
841 while (my ($param, $max_exp_interval) = each %{ $self->{_DATA}->{_SESSION_EXPIRE_LIST} } ) {
842 if ( ($self->{_DATA}->{_SESSION_ATIME} + $max_exp_interval) <= time() ) {
843 push @expired_params, $param;
844 }
845 }
846 $self->clear(\@expired_params) if @expired_params;
847
848 # We update the atime by default, but if this (otherwise undocoumented)
849 # parameter is explicitly set to false, we'll turn the behavior off
850 if ( ! defined $update_atime ) {
851 $self->{_DATA}->{_SESSION_ATIME} = time(); # <-- updating access time
852 $self->_set_status( STATUS_MODIFIED ); # <-- access time modified above
853 }
854
855 return $self;
856}
857
858
859# set the input as a query object or session ID, depending on what it looks like.
860sub _set_query_or_sid {
861 my $self = shift;
862 my $query_or_sid = shift;
863 if ( ref $query_or_sid){ $self->{_QUERY} = $query_or_sid }
864 else { $self->{_CLAIMED_ID} = $query_or_sid }
865}
866
867
868sub _load_pluggables {
869 my ($self) = @_;
870
871 my %DEFAULT_FOR = (
872 driver => "file",
873 serializer => "default",
874 id => "md5",
875 );
876 my %SUBDIR_FOR = (
877 driver => "Driver",
878 serializer => "Serialize",
879 id => "ID",
880 );
881 my $dsn = $self->{_DSN};
882 foreach my $plug (qw(driver serializer id)) {
883 my $mod_name = $dsn->{ $plug };
884 if (not defined $mod_name) {
885 $mod_name = $DEFAULT_FOR{ $plug };
886 }
887 if ($mod_name =~ /^(\w+)$/) {
888
889 # Looks good. Put it into the dsn hash
890 $dsn->{ $plug } = $mod_name = $1;
891
892 # Put together the actual module name to load
893 my $prefix = join '::', (__PACKAGE__, $SUBDIR_FOR{ $plug }, q{});
894 $mod_name = $prefix . $mod_name;
895
896 ## See if we can load load it
897 eval "require $mod_name";
898 if ($@) {
899 my $msg = $@;
900 return $self->set_error("couldn't load $mod_name: " . $msg);
901 }
902 }
903 else {
904 # do something here about bad name for a pluggable
905 }
906 }
907 return;
908}
909
910=pod
911
912=head2 id()
913
914Returns effective ID for a session. Since effective ID and claimed ID can differ, valid session id should always
915be retrieved using this method.
916
917=head2 param($name)
918
919=head2 param(-name=E<gt>$name)
920
921Used in either of the above syntax returns a session parameter set to $name or undef if it doesn't exist. If it's called on a deleted method param() will issue a warning but return value is not defined.
922
923=head2 param($name, $value)
924
925=head2 param(-name=E<gt>$name, -value=E<gt>$value)
926
927Used in either of the above syntax assigns a new value to $name parameter,
928which can later be retrieved with previously introduced param() syntax. C<$value>
929may be a scalar, arrayref or hashref.
930
931Attempts to set parameter names that start with I<_SESSION_> will trigger
932a warning and undef will be returned.
933
934=head2 param_hashref()
935
936B<Deprecated>. Use L<dataref()|/"dataref"> instead.
937
938=head2 dataref()
939
940Returns reference to session's data table:
941
942 $params = $s->dataref();
943 $sid = $params->{_SESSION_ID};
944 $name= $params->{name};
945 # etc...
946
947Useful for having all session data in a hashref, but too risky to update.
948
949=head2 save_param()
950
951=head2 save_param($query)
952
953=head2 save_param($query, \@list)
954
955Saves query parameters to session object. In other words, it's the same as calling L<param($name, $value)|/"param"> for every single query parameter returned by C<< $query->param() >>. The first argument, if present, should be either CGI object or any object which can provide param() method. If it's undef, defaults to the return value of L<query()|/"query">, which returns C<< CGI->new >>. If second argument is present and is a reference to an array, only those query parameters found in the array will be stored in the session. undef is a valid placeholder for any argument to force default behavior.
956
957=head2 load_param()
958
959=head2 load_param($query)
960
961=head2 load_param($query, \@list)
962
963Loads session parameters into a query object. The first argument, if present, should be query object, or any other object which can provide param() method. If second argument is present and is a reference to an array, only parameters found in that array will be loaded to the query object.
964
965=head2 clear()
966
967=head2 clear('field')
968
969=head2 clear(\@list)
970
971Clears parameters from the session object.
972
973With no parameters, all fields are cleared. If passed a single parameter or a
974reference to an array, only the named parameters are cleared.
975
976=head2 flush()
977
978Synchronizes data in memory with the copy serialized by the driver. Call flush()
979if you need to access the session from outside the current session object. You should
980at least call flush() before your program exits.
981
982As a last resort, CGI::Session will automatically call flush for you just
983before the program terminates or session object goes out of scope. This automatic
984behavior was the recommended behavior until the 4.x series. Automatic flushing
985has since proven to be unreliable, and in some cases is now required in places
986that worked with 3.x. For further details see:
987
988 http://rt.cpan.org/Ticket/Display.html?id=17541
989 http://rt.cpan.org/Ticket/Display.html?id=17299
990
991Consequently, always explicitly calling C<flush()> on the session before the program exits
992should be regarded as mandatory until this problem is rectified.
993
994Warning: A bug in your logic whereby the DBI handle has gone out
995out of scope before flush() is called means flush() won't work
996(when the session is a database session), so don't do that.
997
998=head2 atime()
999
1000Read-only method. Returns the last access time of the session in seconds from epoch. This time is used internally while
1001auto-expiring sessions and/or session parameters.
1002
1003=head2 ctime()
1004
1005Read-only method. Returns the time when the session was first created in seconds from epoch.
1006
1007=head2 expire()
1008
1009=head2 expire($time)
1010
1011=head2 expire($param, $time)
1012
1013Sets expiration interval relative to L<atime()|/"atime">.
1014
1015If used with no arguments, returns the expiration interval if it was ever set. If no expiration was ever set, returns undef. For backwards compatibility, a method named C<etime()> does the same thing.
1016
1017Second form sets an expiration time. This value is checked when previously stored session is asked to be retrieved, and if its expiration interval has passed, it will be expunged from the disk immediately. Passing 0 cancels expiration.
1018
1019By using the third syntax you can set the expiration interval for a particular
1020session parameter, say I<~logged-in>. This would cause the library call clear()
1021on the parameter when its time is up. Note it only makes sense to set this value to
1022something I<earlier> than when the whole session expires. Passing 0 cancels expiration.
1023
1024All the time values should be given in the form of seconds. Following keywords are also supported for your convenience:
1025
1026 +-----------+---------------+
1027 | alias | meaning |
1028 +-----------+---------------+
1029 | s | Second |
1030 | m | Minute |
1031 | h | Hour |
1032 | d | Day |
1033 | w | Week |
1034 | M | Month |
1035 | y | Year |
1036 +-----------+---------------+
1037
1038Examples:
1039
1040 $session->expire("2h"); # expires in two hours
1041 $session->expire(0); # cancel expiration
1042 $session->expire("~logged-in", "10m"); # expires '~logged-in' parameter after 10 idle minutes
1043
1044Note: all the expiration times are relative to session's last access time, not to its creation time. To expire a session immediately, call L<delete()|/"delete">. To expire a specific session parameter immediately, call L<clear([$name])|/"clear">.
1045
1046=cut
1047
10481500ns*expires = \&expire;
10491400nsmy $prevent_warning = \&expires;
1050sub etime { $_[0]->expire() }
1051sub expire {
1052 my $self = shift;
1053
1054 # no params, just return the expiration time.
1055 if (not @_) {
1056 return $self->{_DATA}->{_SESSION_ETIME};
1057 }
1058 # We have just a time
1059 elsif ( @_ == 1 ) {
1060 my $time = $_[0];
1061 # If 0 is passed, cancel expiration
1062 if ( defined $time && ($time =~ m/^\d$/) && ($time == 0) ) {
1063 $self->{_DATA}->{_SESSION_ETIME} = undef;
1064 $self->_set_status( STATUS_MODIFIED );
1065 }
1066 # set the expiration to this time
1067 else {
1068 $self->{_DATA}->{_SESSION_ETIME} = $self->_str2seconds( $time );
1069 $self->_set_status( STATUS_MODIFIED );
1070 }
1071 }
1072 # If we get this far, we expect expire($param,$time)
1073 # ( This would be a great use of a Perl6 multi sub! )
1074 else {
1075 my ($param, $time) = @_;
1076 if ( ($time =~ m/^\d$/) && ($time == 0) ) {
1077 delete $self->{_DATA}->{_SESSION_EXPIRE_LIST}->{ $param };
1078 $self->_set_status( STATUS_MODIFIED );
1079 } else {
1080 $self->{_DATA}->{_SESSION_EXPIRE_LIST}->{ $param } = $self->_str2seconds( $time );
1081 $self->_set_status( STATUS_MODIFIED );
1082 }
1083 }
1084 return 1;
1085}
1086
1087# =head2 _str2seconds()
1088#
1089# my $secs = $self->_str2seconds('1d')
1090#
1091# Takes a CGI.pm-style time representation and returns an equivalent number
1092# of seconds.
1093#
1094# See the docs of expire() for more detail.
1095#
1096# =cut
1097
1098sub _str2seconds {
1099 my $self = shift;
1100 my ($str) = @_;
1101
1102 return unless defined $str;
1103 return $str if $str =~ m/^[-+]?\d+$/;
1104
1105 my %_map = (
1106 s => 1,
1107 m => 60,
1108 h => 3600,
1109 d => 86400,
1110 w => 604800,
1111 M => 2592000,
1112 y => 31536000
1113 );
1114
1115 my ($koef, $d) = $str =~ m/^([+-]?\d+)([smhdwMy])$/;
1116 unless ( defined($koef) && defined($d) ) {
1117 die "_str2seconds(): couldn't parse '$str' into \$koef and \$d parts. Possible invalid syntax";
1118 }
1119 return $koef * $_map{ $d };
1120}
1121
1122
1123=pod
1124
1125=head2 is_new()
1126
1127Returns true only for a brand new session.
1128
1129=head2 is_expired()
1130
1131Tests whether session initialized using L<load()|/"load"> is to be expired. This method works only on sessions initialized with load():
1132
1133 $s = CGI::Session->load() or die CGI::Session->errstr;
1134 if ( $s->is_expired ) {
1135 die "Your session expired. Please refresh";
1136 }
1137 if ( $s->is_empty ) {
1138 $s = $s->new() or die $s->errstr;
1139 }
1140
1141
1142=head2 is_empty()
1143
1144Returns true for sessions that are empty. It's preferred way of testing whether requested session was loaded successfully or not:
1145
1146 $s = CGI::Session->load($sid);
1147 if ( $s->is_empty ) {
1148 $s = $s->new();
1149 }
1150
1151Actually, the above code is nothing but waste. The same effect could've been achieved by saying:
1152
1153 $s = CGI::Session->new( $sid );
1154
1155L<is_empty()|/"is_empty"> is useful only if you wanted to catch requests for expired sessions, and create new session afterwards. See L<is_expired()|/"is_expired"> for an example.
1156
1157=head2 delete()
1158
1159Deletes a session from the data store and empties session data from memory, completely, so subsequent read/write requests on the same object will fail. Technically speaking, though, it will only set the object's status to I<STATUS_DELETED>.
1160
1161The intention is that in due course (of the program's execution) this will trigger L<flush()|/"flush">, and flush() will do the actual removal.
1162
1163However: Auto-flushing can be unreliable, and always explicitly calling C<flush()> on the session after C<delete()>
1164should be regarded as mandatory until this problem is rectified.
1165
1166Warning: A bug in your logic whereby the DBI handle has gone out
1167out of scope before flush() is called means flush() won't work
1168(when the session is a database session), so don't do that.
1169
1170=head2 find( \&code )
1171
1172=head2 find( $dsn, \&code )
1173
1174=head2 find( $dsn, \&code, \%dsn_args )
1175
1176Experimental feature. Executes \&code for every session object stored in disk, passing initialized CGI::Session object as the first argument of \&code. Useful for housekeeping purposes, such as for removing expired sessions. Following line, for instance, will remove sessions already expired, but are still in disk:
1177
1178The following line, for instance, will remove sessions already expired, but which are still on disk:
1179
1180 CGI::Session->find( sub {} );
1181
1182Notice, above \&code didn't have to do anything, because load(), which is called to initialize sessions inside find(), will automatically remove expired sessions. Following example will remove all the objects that are 10+ days old:
1183
1184 CGI::Session->find( \&purge );
1185 sub purge {
1186 my ($session) = @_;
1187 next if $session->is_empty; # <-- already expired?!
1188 if ( ($session->ctime + 3600*240) <= time() ) {
1189 $session->delete() or warn "couldn't remove " . $session->id . ": " . $session->errstr;
1190 }
1191 }
1192
1193B<Note>: find will not change the modification or access times on the sessions it returns.
1194
1195Explanation of the 3 parameters to C<find()>:
1196
1197=over 4
1198
1199=item $dsn
1200
1201This is the DSN (Data Source Name) used by CGI::Session to control what type of
1202sessions you previously created and what type of sessions you now wish method
1203C<find()> to pass to your callback.
1204
1205The default value is defined above, in the docs for method C<new()>, and is
1206'driver:file;serializer:default;id:md5'.
1207
1208Do not confuse this DSN with the DSN arguments mentioned just below, under \%dsn_args.
1209
1210=item \&code
1211
1212This is the callback provided by you (i.e. the caller of method C<find()>)
1213which is called by CGI::Session once for each session found by method C<find()>
1214which matches the given $dsn.
1215
1216There is no default value for this coderef.
1217
1218When your callback is actually called, the only parameter is a session. If you
1219want to call a subroutine you already have with more parameters, you can
1220achieve this by creating an anonymous subroutine that calls your subroutine
1221with the parameters you want. For example:
1222
1223 CGI::Session->find($dsn, sub { my_subroutine( @_, 'param 1', 'param 2' ) } );
1224 CGI::Session->find($dsn, sub { $coderef->( @_, $extra_arg ) } );
1225
1226Or if you wish, you can define a sub generator as such:
1227
1228 sub coderef_with_args {
1229 my ( $coderef, @params ) = @_;
1230 return sub { $coderef->( @_, @params ) };
1231 }
1232
1233 CGI::Session->find($dsn, coderef_with_args( $coderef, 'param 1', 'param 2' ) );
1234
1235=item \%dsn_args
1236
1237If your $dsn uses file-based storage, then this hashref might contain keys such as:
1238
1239 {
1240 Directory => Value 1,
1241 NoFlock => Value 2,
1242 UMask => Value 3
1243 }
1244
1245If your $dsn uses db-based storage, then this hashref contains (up to) 3 keys, and looks like:
1246
1247 {
1248 DataSource => Value 1,
1249 User => Value 2,
1250 Password => Value 3
1251 }
1252
1253These 3 form the DSN, username and password used by DBI to control access to your database server,
1254and hence are only relevant when using db-based sessions.
1255
1256The default value of this hashref is undef.
1257
1258=back
1259
1260B<Note:> find() is meant to be convenient, not necessarily efficient. It's best suited in cron scripts.
1261
1262=head1 MISCELLANEOUS METHODS
1263
1264=head2 remote_addr()
1265
1266Returns the remote address of the user who created the session for the first time. Returns undef if variable REMOTE_ADDR wasn't present in the environment when the session was created.
1267
1268=cut
1269
1270sub remote_addr { return $_[0]->{_DATA}->{_SESSION_REMOTE_ADDR} }
1271
1272=pod
1273
1274=head2 errstr()
1275
1276Class method. Returns last error message from the library.
1277
1278=head2 dump()
1279
1280Returns a dump of the session object. Useful for debugging purposes only.
1281
1282=head2 header()
1283
1284Replacement for L<CGI.pm|CGI>'s header() method. Without this method, you usually need to create a CGI::Cookie object and send it as part of the HTTP header:
1285
1286 $cookie = CGI::Cookie->new(-name=>$session->name, -value=>$session->id);
1287 print $cgi->header(-cookie=>$cookie);
1288
1289You can minimize the above into:
1290
1291 print $session->header();
1292
1293It will retrieve the name of the session cookie from C<$session->name()> which defaults to C<$CGI::Session::NAME>. If you want to use a different name for your session cookie, do something like following before creating session object:
1294
1295 CGI::Session->name("MY_SID");
1296 $session = new CGI::Session(undef, $cgi, \%attrs);
1297
1298Now, $session->header() uses "MY_SID" as a name for the session cookie.
1299
1300=head2 query()
1301
1302Returns query object associated with current session object. Default query object class is L<CGI.pm|CGI>.
1303
1304=head2 DEPRECATED METHODS
1305
1306These methods exist solely for for compatibility with CGI::Session 3.x.
1307
1308=head3 close()
1309
1310Closes the session. Using flush() is recommended instead, since that's exactly what a call
1311to close() does now.
1312
1313=head1 DISTRIBUTION
1314
1315CGI::Session consists of several components such as L<drivers|"DRIVERS">, L<serializers|"SERIALIZERS"> and L<id generators|"ID GENERATORS">. This section lists what is available.
1316
1317=head2 DRIVERS
1318
1319Following drivers are included in the standard distribution:
1320
1321=over 4
1322
1323=item *
1324
1325L<file|CGI::Session::Driver::file> - default driver for storing session data in plain files. Full name: B<CGI::Session::Driver::file>
1326
1327=item *
1328
1329L<db_file|CGI::Session::Driver::db_file> - for storing session data in BerkelyDB. Requires: L<DB_File>.
1330Full name: B<CGI::Session::Driver::db_file>
1331
1332=item *
1333
1334L<mysql|CGI::Session::Driver::mysql> - for storing session data in MySQL tables. Requires L<DBI|DBI> and L<DBD::mysql|DBD::mysql>.
1335Full name: B<CGI::Session::Driver::mysql>
1336
1337=item *
1338
1339L<sqlite|CGI::Session::Driver::sqlite> - for storing session data in SQLite. Requires L<DBI|DBI> and L<DBD::SQLite|DBD::SQLite>.
1340Full name: B<CGI::Session::Driver::sqlite>
1341
1342=back
1343
1344=head2 SERIALIZERS
1345
1346=over 4
1347
1348=item *
1349
1350L<default|CGI::Session::Serialize::default> - default data serializer. Uses standard L<Data::Dumper|Data::Dumper>.
1351Full name: B<CGI::Session::Serialize::default>.
1352
1353=item *
1354
1355L<storable|CGI::Session::Serialize::storable> - serializes data using L<Storable>. Requires L<Storable>.
1356Full name: B<CGI::Session::Serialize::storable>.
1357
1358=item *
1359
1360L<freezethaw|CGI::Session::Serialize::freezethaw> - serializes data using L<FreezeThaw>. Requires L<FreezeThaw>.
1361Full name: B<CGI::Session::Serialize::freezethaw>
1362
1363=item *
1364
1365L<yaml|CGI::Session::Serialize::yaml> - serializes data using YAML. Requires L<YAML> or L<YAML::Syck>.
1366Full name: B<CGI::Session::Serialize::yaml>
1367
1368=back
1369
1370=head2 ID GENERATORS
1371
1372Following ID generators are available:
1373
1374=over 4
1375
1376=item *
1377
1378L<md5|CGI::Session::ID::md5> - generates 32 character long hexadecimal string. Requires L<Digest::MD5|Digest::MD5>.
1379Full name: B<CGI::Session::ID::md5>.
1380
1381=item *
1382
1383L<incr|CGI::Session::ID::incr> - generates incremental session ids.
1384
1385=item *
1386
1387L<static|CGI::Session::ID::static> - generates static session ids. B<CGI::Session::ID::static>
1388
1389=back
1390
1391
1392=head1 CREDITS
1393
1394CGI::Session evolved to what it is today with the help of following developers. The list doesn't follow any strict order, but somewhat chronological. Specifics can be found in F<Changes> file
1395
1396=over 4
1397
1398=item Andy Lester
1399
1400=item Brian King E<lt>mrbbking@mac.comE<gt>
1401
1402=item Olivier Dragon E<lt>dragon@shadnet.shad.caE<gt>
1403
1404=item Adam Jacob E<lt>adam@sysadminsith.orgE<gt>
1405
1406=item Igor Plisco E<lt>igor@plisco.ruE<gt>
1407
1408=item Mark Stosberg
1409
1410=item Matt LeBlanc E<lt>mleblanc@cpan.orgE<gt>
1411
1412=item Shawn Sorichetti
1413
1414=back
1415
1416=head1 COPYRIGHT
1417
1418Copyright (C) 2001-2005 Sherzod Ruzmetov E<lt>sherzodr@cpan.orgE<gt>. All rights reserved.
1419This library is free software. You can modify and or distribute it under the same terms as Perl itself.
1420
1421=head1 PUBLIC CODE REPOSITORY
1422
1423You can see what the developers have been up to since the last release by
1424checking out the code repository. You can browse the Subversion repository from here:
1425
1426 http://svn.cromedome.net/repos/CGI-Session
1427
1428Or check it directly with C<svn> from here:
1429
1430 https://svn.cromedome.net/repos/CGI-Session
1431
1432=head1 SUPPORT
1433
1434If you need help using CGI::Session consider the mailing list. You can ask the list by sending your questions to
1435cgi-session-user@lists.sourceforge.net .
1436
1437You can subscribe to the mailing list at https://lists.sourceforge.net/lists/listinfo/cgi-session-user .
1438
1439Bug reports can be submitted at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=CGI-Session
1440
1441=head1 AUTHOR
1442
1443Sherzod Ruzmetov E<lt>sherzodr@cpan.orgE<gt>, http://author.handalak.com/
1444
1445Mark Stosberg became a co-maintainer during the development of 4.0. C<markstos@cpan.org>.
1446Ron Savage became a co-maintainer during the development of 4.30. C<rsavage@cpan.org>.
1447
1448=head1 SEE ALSO
1449
1450=over 4
1451
1452=item *
1453
1454L<CGI::Session::Tutorial|CGI::Session::Tutorial> - extended CGI::Session manual
1455
1456=item *
1457
1458B<RFC 2965> - "HTTP State Management Mechanism" found at ftp://ftp.isi.edu/in-notes/rfc2965.txt
1459
1460=item *
1461
1462L<CGI|CGI> - standard CGI library
1463
1464=item *
1465
1466L<Apache::Session|Apache::Session> - another fine alternative to CGI::Session
1467
1468=back
1469
1470=cut
1471
147219µs1;
1473