Filename | /usr/share/perl5/CGI/Cookie.pm |
Statements | Executed 276 statements in 1.82ms |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
4 | 4 | 3 | 125µs | 226µs | as_string | CGI::Cookie::
2 | 2 | 2 | 55µs | 204µs | new | CGI::Cookie::
10 | 3 | 1 | 34µs | 34µs | name | CGI::Cookie::
1 | 1 | 1 | 26µs | 118µs | parse | CGI::Cookie::
7 | 3 | 2 | 20µs | 20µs | value | CGI::Cookie::
1 | 1 | 1 | 16µs | 98µs | BEGIN@6 | CGI::Cookie::
10 | 2 | 1 | 14µs | 14µs | path | CGI::Cookie::
1 | 1 | 1 | 12µs | 29µs | BEGIN@3 | CGI::Cookie::
1 | 1 | 1 | 11µs | 61µs | BEGIN@11 | CGI::Cookie::
1 | 1 | 1 | 10µs | 130µs | fetch | CGI::Cookie::
1 | 1 | 1 | 10µs | 26µs | BEGIN@138 | CGI::Cookie::
1 | 1 | 1 | 9µs | 18µs | BEGIN@4 | CGI::Cookie::
1 | 1 | 1 | 8µs | 42µs | BEGIN@10 | CGI::Cookie::
5 | 2 | 1 | 8µs | 8µs | httponly | CGI::Cookie::
4 | 1 | 1 | 6µs | 6µs | domain | CGI::Cookie::
4 | 1 | 1 | 5µs | 5µs | max_age | CGI::Cookie::
4 | 1 | 1 | 5µs | 5µs | secure | CGI::Cookie::
4 | 1 | 1 | 5µs | 5µs | expires | CGI::Cookie::
1 | 1 | 1 | 2µs | 2µs | get_raw_cookie | CGI::Cookie::
2 | 2 | 1 | 1µs | 1µs | CORE:subst (opcode) | CGI::Cookie::
0 | 0 | 0 | 0s | 0s | bake | CGI::Cookie::
0 | 0 | 0 | 0s | 0s | compare | CGI::Cookie::
0 | 0 | 0 | 0s | 0s | raw_fetch | CGI::Cookie::
Line | State ments |
Time on line |
Calls | Time in subs |
Code |
---|---|---|---|---|---|
1 | package CGI::Cookie; | ||||
2 | |||||
3 | 2 | 29µs | 2 | 46µs | # spent 29µs (12+17) within CGI::Cookie::BEGIN@3 which was called:
# once (12µs+17µs) by CGI::cookie at line 3 # spent 29µs making 1 call to CGI::Cookie::BEGIN@3
# spent 17µs making 1 call to strict::import |
4 | 2 | 41µs | 2 | 26µs | # spent 18µs (9+8) within CGI::Cookie::BEGIN@4 which was called:
# once (9µs+8µs) by CGI::cookie at line 4 # spent 18µs making 1 call to CGI::Cookie::BEGIN@4
# spent 8µs making 1 call to warnings::import |
5 | |||||
6 | 2 | 39µs | 2 | 101µs | # spent 98µs (16+81) within CGI::Cookie::BEGIN@6 which was called:
# once (16µs+81µs) by CGI::cookie at line 6 # spent 98µs making 1 call to CGI::Cookie::BEGIN@6
# spent 4µs making 1 call to if::import |
7 | |||||
8 | 1 | 400ns | our $VERSION='4.09'; | ||
9 | |||||
10 | 2 | 37µs | 2 | 77µs | # spent 42µs (8+35) within CGI::Cookie::BEGIN@10 which was called:
# once (8µs+35µs) by CGI::cookie at line 10 # spent 42µs making 1 call to CGI::Cookie::BEGIN@10
# spent 34µs making 1 call to Exporter::import |
11 | 2 | 708µs | 2 | 111µs | # spent 61µs (11+50) within CGI::Cookie::BEGIN@11 which was called:
# once (11µs+50µs) by CGI::cookie at line 11 # spent 61µs making 1 call to CGI::Cookie::BEGIN@11
# spent 50µs making 1 call to overload::import |
12 | |||||
13 | 1 | 200ns | my $PERLEX = 0; | ||
14 | # Turn on special checking for ActiveState's PerlEx | ||||
15 | 1 | 700ns | $PERLEX++ if defined($ENV{'GATEWAY_INTERFACE'}) && $ENV{'GATEWAY_INTERFACE'} =~ /^CGI-PerlEx/; | ||
16 | |||||
17 | # Turn on special checking for mod_perl | ||||
18 | # PerlEx::DBI tries to fool DBI by setting MOD_PERL | ||||
19 | 1 | 100ns | my $MOD_PERL = 0; | ||
20 | 1 | 300ns | if (exists $ENV{MOD_PERL} && ! $PERLEX) { | ||
21 | if (exists $ENV{MOD_PERL_API_VERSION} && $ENV{MOD_PERL_API_VERSION} == 2) { | ||||
22 | $MOD_PERL = 2; | ||||
23 | require Apache2::RequestUtil; | ||||
24 | require APR::Table; | ||||
25 | } else { | ||||
26 | $MOD_PERL = 1; | ||||
27 | require Apache; | ||||
28 | } | ||||
29 | } | ||||
30 | |||||
31 | # fetch a list of cookies from the environment and | ||||
32 | # return as a hash. the cookies are parsed as normal | ||||
33 | # escaped URL data. | ||||
34 | # spent 130µs (10+120) within CGI::Cookie::fetch which was called:
# once (10µs+120µs) by CGI::cookie at line 12 of (eval 75)[CGI.pm:932] | ||||
35 | 1 | 300ns | my $class = shift; | ||
36 | 1 | 1µs | 1 | 2µs | my $raw_cookie = get_raw_cookie(@_) or return; # spent 2µs making 1 call to CGI::Cookie::get_raw_cookie |
37 | 1 | 3µs | 1 | 118µs | return $class->parse($raw_cookie); # spent 118µs making 1 call to CGI::Cookie::parse |
38 | } | ||||
39 | |||||
40 | # Fetch a list of cookies from the environment or the incoming headers and | ||||
41 | # return as a hash. The cookie values are not unescaped or altered in any way. | ||||
42 | sub raw_fetch { | ||||
43 | my $class = shift; | ||||
44 | my $raw_cookie = get_raw_cookie(@_) or return; | ||||
45 | my %results; | ||||
46 | my($key,$value); | ||||
47 | |||||
48 | my @pairs = split("[;,] ?",$raw_cookie); | ||||
49 | for my $pair ( @pairs ) { | ||||
50 | $pair =~ s/^\s+|\s+$//g; # trim leading trailing whitespace | ||||
51 | my ( $key, $value ) = split "=", $pair; | ||||
52 | |||||
53 | $value = defined $value ? $value : ''; | ||||
54 | $results{$key} = $value; | ||||
55 | } | ||||
56 | return wantarray ? %results : \%results; | ||||
57 | } | ||||
58 | |||||
59 | # spent 2µs within CGI::Cookie::get_raw_cookie which was called:
# once (2µs+0s) by CGI::Cookie::fetch at line 36 | ||||
60 | 1 | 100ns | my $r = shift; | ||
61 | 1 | 200ns | $r ||= eval { $MOD_PERL == 2 ? | ||
62 | Apache2::RequestUtil->request() : | ||||
63 | Apache->request } if $MOD_PERL; | ||||
64 | |||||
65 | 1 | 0s | return $r->headers_in->{'Cookie'} if $r; | ||
66 | |||||
67 | 1 | 0s | die "Run $r->subprocess_env; before calling fetch()" | ||
68 | if $MOD_PERL and !exists $ENV{REQUEST_METHOD}; | ||||
69 | |||||
70 | 1 | 5µs | return $ENV{HTTP_COOKIE} || $ENV{COOKIE}; | ||
71 | } | ||||
72 | |||||
73 | |||||
74 | # spent 118µs (26+92) within CGI::Cookie::parse which was called:
# once (26µs+92µs) by CGI::Cookie::fetch at line 37 | ||||
75 | 1 | 400ns | my ($self,$raw_cookie) = @_; | ||
76 | 1 | 100ns | return wantarray ? () : {} unless $raw_cookie; | ||
77 | |||||
78 | 1 | 100ns | my %results; | ||
79 | |||||
80 | 1 | 3µs | my @pairs = split("[;,] ?",$raw_cookie); | ||
81 | 1 | 700ns | for (@pairs) { | ||
82 | 1 | 5µs | 1 | 800ns | s/^\s+//; # spent 800ns making 1 call to CGI::Cookie::CORE:subst |
83 | 1 | 2µs | 1 | 600ns | s/\s+$//; # spent 600ns making 1 call to CGI::Cookie::CORE:subst |
84 | |||||
85 | 1 | 1µs | my($key,$value) = split("=",$_,2); | ||
86 | |||||
87 | # Some foreign cookies are not in name=value format, so ignore | ||||
88 | # them. | ||||
89 | 1 | 100ns | next if !defined($value); | ||
90 | 1 | 300ns | my @values = (); | ||
91 | 1 | 400ns | if ($value ne '') { | ||
92 | 1 | 5µs | 2 | 10µs | @values = map unescape($_),split(/[&;]/,$value.'&dmy'); # spent 10µs making 2 calls to CGI::Util::unescape, avg 5µs/call |
93 | 1 | 300ns | pop @values; | ||
94 | } | ||||
95 | 1 | 800ns | 1 | 3µs | $key = unescape($key); # spent 3µs making 1 call to CGI::Util::unescape |
96 | # A bug in Netscape can cause several cookies with same name to | ||||
97 | # appear. The FIRST one in HTTP_COOKIE is the most recent version. | ||||
98 | 1 | 3µs | 1 | 77µs | $results{$key} ||= $self->new(-name=>$key,-value=>\@values); # spent 77µs making 1 call to CGI::Cookie::new |
99 | } | ||||
100 | 1 | 4µs | return wantarray ? %results : \%results; | ||
101 | } | ||||
102 | |||||
103 | # spent 204µs (55+149) within CGI::Cookie::new which was called 2 times, avg 102µs/call:
# once (39µs+88µs) by CGI::cookie at line 33 of (eval 75)[CGI.pm:932]
# once (16µs+61µs) by CGI::Cookie::parse at line 98 | ||||
104 | 2 | 2µs | my ( $class, @params ) = @_; | ||
105 | 2 | 700ns | $class = ref( $class ) || $class; | ||
106 | # Ignore mod_perl request object--compatibility with Apache::Cookie. | ||||
107 | shift if ref $params[0] | ||||
108 | 2 | 500ns | && eval { $params[0]->isa('Apache::Request::Req') || $params[0]->isa('Apache') }; | ||
109 | 2 | 10µs | 2 | 105µs | my ( $name, $value, $path, $domain, $secure, $expires, $max_age, $httponly ) # spent 105µs making 2 calls to CGI::Util::rearrange, avg 52µs/call |
110 | = rearrange( | ||||
111 | [ | ||||
112 | 'NAME', [ 'VALUE', 'VALUES' ], | ||||
113 | 'PATH', 'DOMAIN', | ||||
114 | 'SECURE', 'EXPIRES', | ||||
115 | 'MAX-AGE','HTTPONLY' | ||||
116 | ], | ||||
117 | @params | ||||
118 | ); | ||||
119 | 2 | 1µs | return undef unless defined $name and defined $value; | ||
120 | 2 | 1µs | my $self = {}; | ||
121 | 2 | 3µs | bless $self, $class; | ||
122 | 2 | 5µs | 2 | 24µs | $self->name( $name ); # spent 24µs making 2 calls to CGI::Cookie::name, avg 12µs/call |
123 | 2 | 4µs | 2 | 12µs | $self->value( $value ); # spent 12µs making 2 calls to CGI::Cookie::value, avg 6µs/call |
124 | 2 | 800ns | $path ||= "/"; | ||
125 | 2 | 4µs | 2 | 6µs | $self->path( $path ) if defined $path; # spent 6µs making 2 calls to CGI::Cookie::path, avg 3µs/call |
126 | 2 | 700ns | $self->domain( $domain ) if defined $domain; | ||
127 | 2 | 400ns | $self->secure( $secure ) if defined $secure; | ||
128 | 2 | 400ns | $self->expires( $expires ) if defined $expires; | ||
129 | 2 | 400ns | $self->max_age( $max_age ) if defined $max_age; | ||
130 | 2 | 2µs | 1 | 3µs | $self->httponly( $httponly ) if defined $httponly; # spent 3µs making 1 call to CGI::Cookie::httponly |
131 | 2 | 7µs | return $self; | ||
132 | } | ||||
133 | |||||
134 | # spent 226µs (125+101) within CGI::Cookie::as_string which was called 4 times, avg 56µs/call:
# once (47µs+34µs) by C4::Output::output_with_http_headers at line 305 of C4/Output.pm
# once (29µs+25µs) by CGI::cookie at line 17 of (eval 75)[CGI.pm:932]
# once (26µs+23µs) by CGI::header at line 17 of (eval 81)[CGI.pm:932]
# once (22µs+19µs) by CGI::header at line 75 of (eval 81)[CGI.pm:932] | ||||
135 | 4 | 800ns | my $self = shift; | ||
136 | 4 | 5µs | 4 | 7µs | return "" unless $self->name; # spent 7µs making 4 calls to CGI::Cookie::name, avg 2µs/call |
137 | |||||
138 | 2 | 645µs | 2 | 42µs | # spent 26µs (10+16) within CGI::Cookie::BEGIN@138 which was called:
# once (10µs+16µs) by CGI::cookie at line 138 # spent 26µs making 1 call to CGI::Cookie::BEGIN@138
# spent 16µs making 1 call to warnings::unimport |
139 | |||||
140 | 4 | 9µs | 8 | 39µs | my $name = escape( $self->name ); # spent 36µs making 4 calls to CGI::Util::escape, avg 9µs/call
# spent 3µs making 4 calls to CGI::Cookie::name, avg 850ns/call |
141 | 8 | 27µs | 8 | 22µs | my $value = join "&", map { escape($_) } $self->value; # spent 15µs making 4 calls to CGI::Util::escape, avg 4µs/call
# spent 7µs making 4 calls to CGI::Cookie::value, avg 2µs/call |
142 | 4 | 5µs | my @cookie = ( "$name=$value" ); | ||
143 | |||||
144 | 4 | 5µs | 4 | 6µs | push @cookie,"domain=".$self->domain if $self->domain; # spent 6µs making 4 calls to CGI::Cookie::domain, avg 1µs/call |
145 | 4 | 9µs | 8 | 8µs | push @cookie,"path=".$self->path if $self->path; # spent 8µs making 8 calls to CGI::Cookie::path, avg 1µs/call |
146 | 4 | 4µs | 4 | 5µs | push @cookie,"expires=".$self->expires if $self->expires; # spent 5µs making 4 calls to CGI::Cookie::expires, avg 1µs/call |
147 | 4 | 4µs | 4 | 5µs | push @cookie,"max-age=".$self->max_age if $self->max_age; # spent 5µs making 4 calls to CGI::Cookie::max_age, avg 1µs/call |
148 | 4 | 4µs | 4 | 5µs | push @cookie,"secure" if $self->secure; # spent 5µs making 4 calls to CGI::Cookie::secure, avg 1µs/call |
149 | 4 | 4µs | 4 | 4µs | push @cookie,"HttpOnly" if $self->httponly; # spent 4µs making 4 calls to CGI::Cookie::httponly, avg 1µs/call |
150 | |||||
151 | 4 | 13µs | return join "; ", @cookie; | ||
152 | } | ||||
153 | |||||
154 | sub compare { | ||||
155 | my ( $self, $value ) = @_; | ||||
156 | return "$self" cmp $value; | ||||
157 | } | ||||
158 | |||||
159 | sub bake { | ||||
160 | my ($self, $r) = @_; | ||||
161 | |||||
162 | $r ||= eval { | ||||
163 | $MOD_PERL == 2 | ||||
164 | ? Apache2::RequestUtil->request() | ||||
165 | : Apache->request | ||||
166 | } if $MOD_PERL; | ||||
167 | if ($r) { | ||||
168 | $r->headers_out->add('Set-Cookie' => $self->as_string); | ||||
169 | } else { | ||||
170 | require CGI; | ||||
171 | print CGI::header(-cookie => $self); | ||||
172 | } | ||||
173 | |||||
174 | } | ||||
175 | |||||
176 | # accessors | ||||
177 | sub name { | ||||
178 | 10 | 3µs | my ( $self, $name ) = @_; | ||
179 | 10 | 20µs | $self->{'name'} = $name if defined $name; | ||
180 | 10 | 20µs | return $self->{'name'}; | ||
181 | } | ||||
182 | |||||
183 | # spent 20µs within CGI::Cookie::value which was called 7 times, avg 3µs/call:
# 4 times (7µs+0s) by CGI::Cookie::as_string at line 141, avg 2µs/call
# 2 times (12µs+0s) by CGI::Cookie::new at line 123, avg 6µs/call
# once (1µs+0s) by CGI::cookie at line 18 of (eval 75)[CGI.pm:932] | ||||
184 | 7 | 2µs | my ( $self, $value ) = @_; | ||
185 | 7 | 2µs | if ( defined $value ) { | ||
186 | my @values | ||||
187 | 2 | 3µs | = ref $value eq 'ARRAY' ? @$value | ||
188 | : ref $value eq 'HASH' ? %$value | ||||
189 | : ( $value ); | ||||
190 | 2 | 3µs | $self->{'value'} = [@values]; | ||
191 | } | ||||
192 | 7 | 18µs | return wantarray ? @{ $self->{'value'} } : $self->{'value'}->[0]; | ||
193 | } | ||||
194 | |||||
195 | # spent 6µs within CGI::Cookie::domain which was called 4 times, avg 1µs/call:
# 4 times (6µs+0s) by CGI::Cookie::as_string at line 144, avg 1µs/call | ||||
196 | 4 | 1µs | my ( $self, $domain ) = @_; | ||
197 | 4 | 700ns | $self->{'domain'} = lc $domain if defined $domain; | ||
198 | 4 | 8µs | return $self->{'domain'}; | ||
199 | } | ||||
200 | |||||
201 | # spent 5µs within CGI::Cookie::secure which was called 4 times, avg 1µs/call:
# 4 times (5µs+0s) by CGI::Cookie::as_string at line 148, avg 1µs/call | ||||
202 | 4 | 700ns | my ( $self, $secure ) = @_; | ||
203 | 4 | 500ns | $self->{'secure'} = $secure if defined $secure; | ||
204 | 4 | 7µs | return $self->{'secure'}; | ||
205 | } | ||||
206 | |||||
207 | # spent 5µs within CGI::Cookie::expires which was called 4 times, avg 1µs/call:
# 4 times (5µs+0s) by CGI::Cookie::as_string at line 146, avg 1µs/call | ||||
208 | 4 | 800ns | my ( $self, $expires ) = @_; | ||
209 | 4 | 700ns | $self->{'expires'} = CGI::Util::expires($expires,'cookie') if defined $expires; | ||
210 | 4 | 7µs | return $self->{'expires'}; | ||
211 | } | ||||
212 | |||||
213 | # spent 5µs within CGI::Cookie::max_age which was called 4 times, avg 1µs/call:
# 4 times (5µs+0s) by CGI::Cookie::as_string at line 147, avg 1µs/call | ||||
214 | 4 | 1µs | my ( $self, $max_age ) = @_; | ||
215 | 4 | 1µs | $self->{'max-age'} = CGI::Util::expire_calc($max_age)-time() if defined $max_age; | ||
216 | 4 | 7µs | return $self->{'max-age'}; | ||
217 | } | ||||
218 | |||||
219 | sub path { | ||||
220 | 10 | 2µs | my ( $self, $path ) = @_; | ||
221 | 10 | 2µs | $self->{'path'} = $path if defined $path; | ||
222 | 10 | 18µs | return $self->{'path'}; | ||
223 | } | ||||
224 | |||||
225 | |||||
226 | sub httponly { # HttpOnly | ||||
227 | 5 | 1µs | my ( $self, $httponly ) = @_; | ||
228 | 5 | 2µs | $self->{'httponly'} = $httponly if defined $httponly; | ||
229 | 5 | 11µs | return $self->{'httponly'}; | ||
230 | } | ||||
231 | |||||
232 | 1 | 6µs | 1; | ||
233 | |||||
234 | =head1 NAME | ||||
235 | |||||
236 | CGI::Cookie - Interface to HTTP Cookies | ||||
237 | |||||
238 | =head1 SYNOPSIS | ||||
239 | |||||
240 | use CGI qw/:standard/; | ||||
241 | use CGI::Cookie; | ||||
242 | |||||
243 | # Create new cookies and send them | ||||
244 | $cookie1 = CGI::Cookie->new(-name=>'ID',-value=>123456); | ||||
245 | $cookie2 = CGI::Cookie->new(-name=>'preferences', | ||||
246 | -value=>{ font => Helvetica, | ||||
247 | size => 12 } | ||||
248 | ); | ||||
249 | print header(-cookie=>[$cookie1,$cookie2]); | ||||
250 | |||||
251 | # fetch existing cookies | ||||
252 | %cookies = CGI::Cookie->fetch; | ||||
253 | $id = $cookies{'ID'}->value; | ||||
254 | |||||
255 | # create cookies returned from an external source | ||||
256 | %cookies = CGI::Cookie->parse($ENV{COOKIE}); | ||||
257 | |||||
258 | =head1 DESCRIPTION | ||||
259 | |||||
260 | CGI::Cookie is an interface to HTTP/1.1 cookies, a mechanism | ||||
261 | that allows Web servers to store persistent information on | ||||
262 | the browser's side of the connection. Although CGI::Cookie is | ||||
263 | intended to be used in conjunction with CGI.pm (and is in fact used by | ||||
264 | it internally), you can use this module independently. | ||||
265 | |||||
266 | For full information on cookies see | ||||
267 | |||||
268 | https://tools.ietf.org/html/rfc6265 | ||||
269 | |||||
270 | =head1 USING CGI::Cookie | ||||
271 | |||||
272 | CGI::Cookie is object oriented. Each cookie object has a name and a | ||||
273 | value. The name is any scalar value. The value is any scalar or | ||||
274 | array value (associative arrays are also allowed). Cookies also have | ||||
275 | several optional attributes, including: | ||||
276 | |||||
277 | =over 4 | ||||
278 | |||||
279 | =item B<1. expiration date> | ||||
280 | |||||
281 | The expiration date tells the browser how long to hang on to the | ||||
282 | cookie. If the cookie specifies an expiration date in the future, the | ||||
283 | browser will store the cookie information in a disk file and return it | ||||
284 | to the server every time the user reconnects (until the expiration | ||||
285 | date is reached). If the cookie species an expiration date in the | ||||
286 | past, the browser will remove the cookie from the disk file. If the | ||||
287 | expiration date is not specified, the cookie will persist only until | ||||
288 | the user quits the browser. | ||||
289 | |||||
290 | =item B<2. domain> | ||||
291 | |||||
292 | This is a partial or complete domain name for which the cookie is | ||||
293 | valid. The browser will return the cookie to any host that matches | ||||
294 | the partial domain name. For example, if you specify a domain name | ||||
295 | of ".capricorn.com", then the browser will return the cookie to | ||||
296 | Web servers running on any of the machines "www.capricorn.com", | ||||
297 | "ftp.capricorn.com", "feckless.capricorn.com", etc. Domain names | ||||
298 | must contain at least two periods to prevent attempts to match | ||||
299 | on top level domains like ".edu". If no domain is specified, then | ||||
300 | the browser will only return the cookie to servers on the host the | ||||
301 | cookie originated from. | ||||
302 | |||||
303 | =item B<3. path> | ||||
304 | |||||
305 | If you provide a cookie path attribute, the browser will check it | ||||
306 | against your script's URL before returning the cookie. For example, | ||||
307 | if you specify the path "/cgi-bin", then the cookie will be returned | ||||
308 | to each of the scripts "/cgi-bin/tally.pl", "/cgi-bin/order.pl", and | ||||
309 | "/cgi-bin/customer_service/complain.pl", but not to the script | ||||
310 | "/cgi-private/site_admin.pl". By default, the path is set to "/", so | ||||
311 | that all scripts at your site will receive the cookie. | ||||
312 | |||||
313 | =item B<4. secure flag> | ||||
314 | |||||
315 | If the "secure" attribute is set, the cookie will only be sent to your | ||||
316 | script if the CGI request is occurring on a secure channel, such as SSL. | ||||
317 | |||||
318 | =item B<5. httponly flag> | ||||
319 | |||||
320 | If the "httponly" attribute is set, the cookie will only be accessible | ||||
321 | through HTTP Requests. This cookie will be inaccessible via JavaScript | ||||
322 | (to prevent XSS attacks). | ||||
323 | |||||
324 | This feature is supported by nearly all modern browsers. | ||||
325 | |||||
326 | See these URLs for more information: | ||||
327 | |||||
328 | http://msdn.microsoft.com/en-us/library/ms533046.aspx | ||||
329 | http://www.browserscope.org/?category=security&v=top | ||||
330 | |||||
331 | =back | ||||
332 | |||||
333 | =head2 Creating New Cookies | ||||
334 | |||||
335 | my $c = CGI::Cookie->new(-name => 'foo', | ||||
336 | -value => 'bar', | ||||
337 | -expires => '+3M', | ||||
338 | '-max-age' => '+3M', | ||||
339 | -domain => '.capricorn.com', | ||||
340 | -path => '/cgi-bin/database', | ||||
341 | -secure => 1 | ||||
342 | ); | ||||
343 | |||||
344 | Create cookies from scratch with the B<new> method. The B<-name> and | ||||
345 | B<-value> parameters are required. The name must be a scalar value. | ||||
346 | The value can be a scalar, an array reference, or a hash reference. | ||||
347 | (At some point in the future cookies will support one of the Perl | ||||
348 | object serialization protocols for full generality). | ||||
349 | |||||
350 | B<-expires> accepts any of the relative or absolute date formats | ||||
351 | recognized by CGI.pm, for example "+3M" for three months in the | ||||
352 | future. See CGI.pm's documentation for details. | ||||
353 | |||||
354 | B<-max-age> accepts the same data formats as B<< -expires >>, but sets a | ||||
355 | relative value instead of an absolute like B<< -expires >>. This is intended to be | ||||
356 | more secure since a clock could be changed to fake an absolute time. In | ||||
357 | practice, as of 2011, C<< -max-age >> still does not enjoy the widespread support | ||||
358 | that C<< -expires >> has. You can set both, and browsers that support | ||||
359 | C<< -max-age >> should ignore the C<< Expires >> header. The drawback | ||||
360 | to this approach is the bit of bandwidth for sending an extra header on each cookie. | ||||
361 | |||||
362 | B<-domain> points to a domain name or to a fully qualified host name. | ||||
363 | If not specified, the cookie will be returned only to the Web server | ||||
364 | that created it. | ||||
365 | |||||
366 | B<-path> points to a partial URL on the current server. The cookie | ||||
367 | will be returned to all URLs beginning with the specified path. If | ||||
368 | not specified, it defaults to '/', which returns the cookie to all | ||||
369 | pages at your site. | ||||
370 | |||||
371 | B<-secure> if set to a true value instructs the browser to return the | ||||
372 | cookie only when a cryptographic protocol is in use. | ||||
373 | |||||
374 | B<-httponly> if set to a true value, the cookie will not be accessible | ||||
375 | via JavaScript. | ||||
376 | |||||
377 | For compatibility with Apache::Cookie, you may optionally pass in | ||||
378 | a mod_perl request object as the first argument to C<new()>. It will | ||||
379 | simply be ignored: | ||||
380 | |||||
381 | my $c = CGI::Cookie->new($r, | ||||
382 | -name => 'foo', | ||||
383 | -value => ['bar','baz']); | ||||
384 | |||||
385 | =head2 Sending the Cookie to the Browser | ||||
386 | |||||
387 | The simplest way to send a cookie to the browser is by calling the bake() | ||||
388 | method: | ||||
389 | |||||
390 | $c->bake; | ||||
391 | |||||
392 | This will print the Set-Cookie HTTP header to STDOUT using CGI.pm. CGI.pm | ||||
393 | will be loaded for this purpose if it is not already. Otherwise CGI.pm is not | ||||
394 | required or used by this module. | ||||
395 | |||||
396 | Under mod_perl, pass in an Apache request object: | ||||
397 | |||||
398 | $c->bake($r); | ||||
399 | |||||
400 | If you want to set the cookie yourself, Within a CGI script you can send | ||||
401 | a cookie to the browser by creating one or more Set-Cookie: fields in the | ||||
402 | HTTP header. Here is a typical sequence: | ||||
403 | |||||
404 | my $c = CGI::Cookie->new(-name => 'foo', | ||||
405 | -value => ['bar','baz'], | ||||
406 | -expires => '+3M'); | ||||
407 | |||||
408 | print "Set-Cookie: $c\n"; | ||||
409 | print "Content-Type: text/html\n\n"; | ||||
410 | |||||
411 | To send more than one cookie, create several Set-Cookie: fields. | ||||
412 | |||||
413 | If you are using CGI.pm, you send cookies by providing a -cookie | ||||
414 | argument to the header() method: | ||||
415 | |||||
416 | print header(-cookie=>$c); | ||||
417 | |||||
418 | Mod_perl users can set cookies using the request object's header_out() | ||||
419 | method: | ||||
420 | |||||
421 | $r->headers_out->set('Set-Cookie' => $c); | ||||
422 | |||||
423 | Internally, Cookie overloads the "" operator to call its as_string() | ||||
424 | method when incorporated into the HTTP header. as_string() turns the | ||||
425 | Cookie's internal representation into an RFC-compliant text | ||||
426 | representation. You may call as_string() yourself if you prefer: | ||||
427 | |||||
428 | print "Set-Cookie: ",$c->as_string,"\n"; | ||||
429 | |||||
430 | =head2 Recovering Previous Cookies | ||||
431 | |||||
432 | %cookies = CGI::Cookie->fetch; | ||||
433 | |||||
434 | B<fetch> returns an associative array consisting of all cookies | ||||
435 | returned by the browser. The keys of the array are the cookie names. You | ||||
436 | can iterate through the cookies this way: | ||||
437 | |||||
438 | %cookies = CGI::Cookie->fetch; | ||||
439 | for (keys %cookies) { | ||||
440 | do_something($cookies{$_}); | ||||
441 | } | ||||
442 | |||||
443 | In a scalar context, fetch() returns a hash reference, which may be more | ||||
444 | efficient if you are manipulating multiple cookies. | ||||
445 | |||||
446 | CGI.pm uses the URL escaping methods to save and restore reserved characters | ||||
447 | in its cookies. If you are trying to retrieve a cookie set by a foreign server, | ||||
448 | this escaping method may trip you up. Use raw_fetch() instead, which has the | ||||
449 | same semantics as fetch(), but performs no unescaping. | ||||
450 | |||||
451 | You may also retrieve cookies that were stored in some external | ||||
452 | form using the parse() class method: | ||||
453 | |||||
454 | $COOKIES = `cat /usr/tmp/Cookie_stash`; | ||||
455 | %cookies = CGI::Cookie->parse($COOKIES); | ||||
456 | |||||
457 | If you are in a mod_perl environment, you can save some overhead by | ||||
458 | passing the request object to fetch() like this: | ||||
459 | |||||
460 | CGI::Cookie->fetch($r); | ||||
461 | |||||
462 | If the value passed to parse() is undefined, an empty array will returned in list | ||||
463 | context, and an empty hashref will be returned in scalar context. | ||||
464 | |||||
465 | =head2 Manipulating Cookies | ||||
466 | |||||
467 | Cookie objects have a series of accessor methods to get and set cookie | ||||
468 | attributes. Each accessor has a similar syntax. Called without | ||||
469 | arguments, the accessor returns the current value of the attribute. | ||||
470 | Called with an argument, the accessor changes the attribute and | ||||
471 | returns its new value. | ||||
472 | |||||
473 | =over 4 | ||||
474 | |||||
475 | =item B<name()> | ||||
476 | |||||
477 | Get or set the cookie's name. Example: | ||||
478 | |||||
479 | $name = $c->name; | ||||
480 | $new_name = $c->name('fred'); | ||||
481 | |||||
482 | =item B<value()> | ||||
483 | |||||
484 | Get or set the cookie's value. Example: | ||||
485 | |||||
486 | $value = $c->value; | ||||
487 | @new_value = $c->value(['a','b','c','d']); | ||||
488 | |||||
489 | B<value()> is context sensitive. In a list context it will return | ||||
490 | the current value of the cookie as an array. In a scalar context it | ||||
491 | will return the B<first> value of a multivalued cookie. | ||||
492 | |||||
493 | =item B<domain()> | ||||
494 | |||||
495 | Get or set the cookie's domain. | ||||
496 | |||||
497 | =item B<path()> | ||||
498 | |||||
499 | Get or set the cookie's path. | ||||
500 | |||||
501 | =item B<expires()> | ||||
502 | |||||
503 | Get or set the cookie's expiration time. | ||||
504 | |||||
505 | =item B<max_age()> | ||||
506 | |||||
507 | Get or set the cookie's max_age value. | ||||
508 | |||||
509 | =back | ||||
510 | |||||
511 | |||||
512 | =head1 AUTHOR INFORMATION | ||||
513 | |||||
514 | The CGI.pm distribution is copyright 1995-2007, Lincoln D. Stein. It is | ||||
515 | distributed under GPL and the Artistic License 2.0. It is currently | ||||
516 | maintained by Lee Johnson with help from many contributors. | ||||
517 | |||||
518 | Address bug reports and comments to: https://github.com/leejo/CGI.pm/issues | ||||
519 | |||||
520 | The original bug tracker can be found at: https://rt.cpan.org/Public/Dist/Display.html?Queue=CGI.pm | ||||
521 | |||||
522 | When sending bug reports, please provide the version of CGI.pm, the version of | ||||
523 | Perl, the name and version of your Web server, and the name and version of the | ||||
524 | operating system you are using. If the problem is even remotely browser | ||||
525 | dependent, please provide information about the affected browsers as well. | ||||
526 | |||||
527 | =head1 BUGS | ||||
528 | |||||
529 | This section intentionally left blank. | ||||
530 | |||||
531 | =head1 SEE ALSO | ||||
532 | |||||
533 | L<CGI::Carp>, L<CGI> | ||||
534 | |||||
535 | L<RFC 2109|http://www.ietf.org/rfc/rfc2109.txt>, L<RFC 2695|http://www.ietf.org/rfc/rfc2965.txt> | ||||
536 | |||||
537 | =cut | ||||
sub CGI::Cookie::CORE:subst; # opcode |