line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
#!/usr/local/bin/perl |
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
package CGI::Thin::Cookies; |
4
|
1
|
|
|
1
|
|
464
|
use strict; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
33
|
|
5
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
BEGIN { |
7
|
1
|
|
|
1
|
|
5
|
use Exporter (); |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
17
|
|
8
|
1
|
|
|
1
|
|
3
|
use vars qw ($VERSION @ISA @EXPORT); |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
84
|
|
9
|
1
|
|
|
1
|
|
2
|
$VERSION = 0.52; |
10
|
1
|
|
|
|
|
12
|
@ISA = qw (Exporter); |
11
|
1
|
|
|
|
|
680
|
@EXPORT = qw (&Parse_Cookies &Set_Cookie); |
12
|
|
|
|
|
|
|
} |
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
########################################### main pod documentation begin ## |
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
=pod |
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
=head1 NAME |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
CGI::Thin::Cookies - A very lightweight way to read and set Cookies |
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
=head1 SYNOPSIS |
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
C |
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
C |
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
C 'a cookie value', EXPIRE => '+12h);> |
29
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
=head1 DESCRIPTION |
31
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
This module is a very lightweight parser and setter of cookies. And |
33
|
|
|
|
|
|
|
it has a special feature that it will return an array if the same key |
34
|
|
|
|
|
|
|
is used twice for different cookies with the ame name. And you can |
35
|
|
|
|
|
|
|
force an array to avoid complications. |
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
=head1 USAGE |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
* 'CGI::Thin::Cookies::Parse_Cookies(@keys)' |
40
|
|
|
|
|
|
|
The optional @keys will be used to force arrays to be returned. |
41
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
The function returns a hash of the cookies available to the script. It |
43
|
|
|
|
|
|
|
can return more than one cookie if they exist. |
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
* 'CGI::Thin::Cookies::Set_Cookie (%options)VALUE => 'a cookie value', EXPIRE => '+12h);' |
46
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
The %options contain the the following information for the cookie: |
48
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
NAME: the name of the cookie |
50
|
|
|
|
|
|
|
VALUE: a string with the value of the cookie |
51
|
|
|
|
|
|
|
DOMAIN: the domain for the cookie, default is the '.secondaryDomain.toplevelDomain' |
52
|
|
|
|
|
|
|
PATH: the path within the domain, default is '/' |
53
|
|
|
|
|
|
|
SECURE: true or false value for setting the SECURE flag |
54
|
|
|
|
|
|
|
EXPIRE: when to expire including the following options |
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
"delete" -- expire long ago (the first second of the epoch) |
57
|
|
|
|
|
|
|
"now" -- expire immediately |
58
|
|
|
|
|
|
|
"never" -- expire in 2038 (the last second of the epoch in 31 bits) |
59
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
"+180s" -- in 180 seconds |
61
|
|
|
|
|
|
|
"+2m" -- in 2 minutes |
62
|
|
|
|
|
|
|
"+12h" -- in 12 hours |
63
|
|
|
|
|
|
|
"+1d" -- in 1 day |
64
|
|
|
|
|
|
|
"+3M" -- in 3 months |
65
|
|
|
|
|
|
|
"+2y" -- in 2 years |
66
|
|
|
|
|
|
|
"-3m" -- 3 minutes ago(!) |
67
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
If $time is false (0 or '') then don't send an expiration, it will expire |
69
|
|
|
|
|
|
|
with the browser being closed |
70
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
If you don't supply one of these forms, we assume you are |
72
|
|
|
|
|
|
|
specifying the date yourself |
73
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
=head1 BUGS |
75
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
=head2 Fixed |
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
=over 4 |
79
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
=back |
81
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
=head2 Pending |
83
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
=over 4 |
85
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
=back |
87
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
=head1 SEE ALSO |
89
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
CGI::Thin |
91
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
=head1 SUPPORT |
93
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
Visit CGI::Thin::Cookies' web site at |
95
|
|
|
|
|
|
|
http://www.PlatypiVentures.com/perl/modules/cgi_thin.shtml |
96
|
|
|
|
|
|
|
Send email to |
97
|
|
|
|
|
|
|
mailto:cgi_thin@PlatypiVentures.com |
98
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
=head1 AUTHOR |
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
R. Geoffrey Avery |
102
|
|
|
|
|
|
|
CPAN ID: RGEOFFREY |
103
|
|
|
|
|
|
|
modules@PlatypiVentures.com |
104
|
|
|
|
|
|
|
http://www.PlatypiVentures.com/perl |
105
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
=head1 COPYRIGHT |
107
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
This module is free software, you may redistribute it or modify in under the same terms as Perl itself. |
109
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
=cut |
111
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
############################################# main pod documentation end ## |
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
################################################ subroutine header begin ## |
115
|
|
|
|
|
|
|
################################################## subroutine header end ## |
116
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
sub Parse_Cookies |
118
|
|
|
|
|
|
|
{ |
119
|
0
|
|
|
0
|
0
|
|
my (%cookie); |
120
|
0
|
|
|
|
|
|
foreach (split(/; /, $ENV{'HTTP_COOKIE'})) { |
121
|
0
|
|
|
|
|
|
tr/+/ /; |
122
|
0
|
|
|
|
|
|
my ($chip, $val) = split(/=/, $_, 2); |
123
|
0
|
|
|
|
|
|
$chip =~ s/%([A-Fa-f0-9]{2})/chr(hex($1))/ge; |
|
0
|
|
|
|
|
|
|
124
|
0
|
|
|
|
|
|
$val =~ s/%([A-Fa-f0-9]{2})/chr(hex($1))/ge; |
|
0
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
|
126
|
0
|
0
|
|
|
|
|
if ( defined($cookie{$chip})) { |
127
|
0
|
0
|
|
|
|
|
$cookie{$chip} = [$cookie{$chip}] unless (ref ($cookie{$chip}) eq "ARRAY"); |
128
|
0
|
|
|
|
|
|
push (@{$cookie{$chip}}, $val); |
|
0
|
|
|
|
|
|
|
129
|
|
|
|
|
|
|
} else { |
130
|
0
|
|
|
|
|
|
$cookie{$chip} = $val; |
131
|
|
|
|
|
|
|
} |
132
|
|
|
|
|
|
|
} |
133
|
|
|
|
|
|
|
|
134
|
0
|
|
|
|
|
|
foreach (@_) { |
135
|
0
|
0
|
|
|
|
|
$cookie{$_} = &Force_Array ($cookie{$_}) if ($cookie{$_}); |
136
|
|
|
|
|
|
|
} |
137
|
|
|
|
|
|
|
|
138
|
0
|
|
|
|
|
|
return (%cookie); |
139
|
|
|
|
|
|
|
} |
140
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
################################################ subroutine header begin ## |
142
|
|
|
|
|
|
|
################################################## subroutine header end ## |
143
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
sub Set_Cookie |
145
|
|
|
|
|
|
|
{ |
146
|
0
|
|
|
0
|
0
|
|
my (%cookie) = @_; |
147
|
|
|
|
|
|
|
|
148
|
0
|
|
|
|
|
|
$cookie{'VALUE'} =~ s/ /+/g; |
149
|
0
|
0
|
|
|
|
|
$cookie{'VALUE'} = 'deleted' if ($cookie{'EXPIRE'} eq 'delete'); |
150
|
|
|
|
|
|
|
|
151
|
0
|
|
|
|
|
|
$cookie{'EXPIRE'} = &Expire ($cookie{'EXPIRE'}); |
152
|
|
|
|
|
|
|
|
153
|
0
|
0
|
|
|
|
|
$cookie{'PATH'} = '/' unless $cookie{'PATH'}; |
154
|
|
|
|
|
|
|
|
155
|
0
|
0
|
|
|
|
|
unless ($cookie{'DOMAIN'}) { |
156
|
0
|
|
|
|
|
|
my @where = split ('\.', $ENV{'SERVER_NAME'}); |
157
|
0
|
|
|
|
|
|
$cookie{'DOMAIN'} = '.' . join ('.', splice (@where, -2)); |
158
|
|
|
|
|
|
|
} |
159
|
|
|
|
|
|
|
|
160
|
0
|
0
|
|
|
|
|
return (join ('; ', |
161
|
|
|
|
|
|
|
"Set-Cookie: $cookie{'NAME'}\=$cookie{'VALUE'}", |
162
|
|
|
|
|
|
|
$cookie{'EXPIRE'}, |
163
|
|
|
|
|
|
|
"path\=$cookie{'PATH'}", |
164
|
|
|
|
|
|
|
"domain\=$cookie{'DOMAIN'}", |
165
|
|
|
|
|
|
|
(($cookie{'SECURE'}) ? 'secure' : '') |
166
|
|
|
|
|
|
|
) . "\n"); |
167
|
|
|
|
|
|
|
} |
168
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
################################################ subroutine header begin ## |
170
|
|
|
|
|
|
|
# Loosely based on &expire_calc from CGI.pm |
171
|
|
|
|
|
|
|
################################################### subroutine header end ## |
172
|
|
|
|
|
|
|
|
173
|
|
|
|
|
|
|
sub Expire |
174
|
|
|
|
|
|
|
{ |
175
|
0
|
|
|
0
|
0
|
|
my($time) = @_; |
176
|
|
|
|
|
|
|
|
177
|
0
|
0
|
|
|
|
|
return ('') unless ($time); |
178
|
|
|
|
|
|
|
|
179
|
0
|
|
|
|
|
|
my(%mult) = ('s'=>1, |
180
|
|
|
|
|
|
|
'm'=>60, |
181
|
|
|
|
|
|
|
'h'=>60*60, |
182
|
|
|
|
|
|
|
'd'=>60*60*24, |
183
|
|
|
|
|
|
|
'M'=>60*60*24*30, |
184
|
|
|
|
|
|
|
'y'=>60*60*24*365); |
185
|
|
|
|
|
|
|
|
186
|
0
|
0
|
|
|
|
|
if ($time eq 'now') { |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
187
|
0
|
|
|
|
|
|
$time = time; |
188
|
|
|
|
|
|
|
} elsif ($time eq 'delete') { |
189
|
0
|
|
|
|
|
|
$time = 1; |
190
|
|
|
|
|
|
|
} elsif ($time eq 'never') { |
191
|
0
|
|
|
|
|
|
$time = 2147483647; |
192
|
|
|
|
|
|
|
} elsif ($time=~/^([+-]?\d+)([mhdMy]?)/) { |
193
|
0
|
|
0
|
|
|
|
$time = time + (($mult{$2} || 1)*$1); |
194
|
|
|
|
|
|
|
} |
195
|
|
|
|
|
|
|
|
196
|
0
|
|
|
|
|
|
my ($seconds,$min,$hour,$mday,$mon,$year,$wday) = gmtime ($time); |
197
|
|
|
|
|
|
|
|
198
|
0
|
|
|
|
|
|
my (@days) = qw (Sun Mon Tue Wed Thu Fri Sat); |
199
|
0
|
|
|
|
|
|
my (@months) = qw (Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec); |
200
|
0
|
0
|
|
|
|
|
$seconds = "0" . $seconds if $seconds < 10; |
201
|
0
|
0
|
|
|
|
|
$min = "0" . $min if $min < 10; |
202
|
0
|
0
|
|
|
|
|
$hour = "0" . $hour if $hour < 10; |
203
|
0
|
|
|
|
|
|
$year += 1900; |
204
|
|
|
|
|
|
|
|
205
|
0
|
|
|
|
|
|
return ("expires\=$days[$wday], $mday-$months[$mon]-$year $hour:$min:$seconds GMT"); |
206
|
|
|
|
|
|
|
} |
207
|
|
|
|
|
|
|
|
208
|
|
|
|
|
|
|
################################################ subroutine header begin ## |
209
|
|
|
|
|
|
|
################################################## subroutine header end ## |
210
|
|
|
|
|
|
|
|
211
|
|
|
|
|
|
|
sub Force_Array |
212
|
|
|
|
|
|
|
{ |
213
|
0
|
|
|
0
|
0
|
|
my ($item) = @_; |
214
|
|
|
|
|
|
|
|
215
|
0
|
0
|
|
|
|
|
$item = [$item] unless( ref($item) eq "ARRAY" ); |
216
|
|
|
|
|
|
|
|
217
|
0
|
|
|
|
|
|
return ($item); |
218
|
|
|
|
|
|
|
} |
219
|
|
|
|
|
|
|
|
220
|
|
|
|
|
|
|
########################################################################### |
221
|
|
|
|
|
|
|
########################################################################### |
222
|
|
|
|
|
|
|
########################################################################### |
223
|
|
|
|
|
|
|
########################################################################### |
224
|
|
|
|
|
|
|
|
225
|
|
|
|
|
|
|
1; |
226
|
|
|
|
|
|
|
|
227
|
|
|
|
|
|
|
__END__ |