This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Re: [ID 20020422.003] Suggestion in Perl 5.6.1 installation on AIX
[perl5.git] / lib / CGI / Cookie.pm
CommitLineData
424ec8fa
GS
1package CGI::Cookie;
2
3# See the bottom of this file for the POD documentation. Search for the
4# string '=head'.
5
6# You can run this file through either pod2man or pod2html to produce pretty
7# documentation in manual or html file format (these utilities are part of the
8# Perl 5 distribution).
9
3538e1d5 10# Copyright 1995-1999, Lincoln D. Stein. All rights reserved.
424ec8fa
GS
11# It may be used and modified freely, but I do request that this copyright
12# notice remain attached to the file. You may modify this module as you
13# wish, but if you redistribute a modified version, please attach a note
14# listing the modifications you have made.
15
199d4a26 16$CGI::Cookie::VERSION='1.20';
424ec8fa 17
3d1a2ec4 18use CGI::Util qw(rearrange unescape escape);
424ec8fa
GS
19use overload '""' => \&as_string,
20 'cmp' => \&compare,
21 'fallback'=>1;
22
23# fetch a list of cookies from the environment and
24# return as a hash. the cookies are parsed as normal
25# escaped URL data.
26sub fetch {
27 my $class = shift;
28 my $raw_cookie = $ENV{HTTP_COOKIE} || $ENV{COOKIE};
29 return () unless $raw_cookie;
30 return $class->parse($raw_cookie);
31}
32
33# fetch a list of cookies from the environment and
34# return as a hash. the cookie values are not unescaped
35# or altered in any way.
36sub raw_fetch {
37 my $class = shift;
38 my $raw_cookie = $ENV{HTTP_COOKIE} || $ENV{COOKIE};
39 return () unless $raw_cookie;
40 my %results;
41 my($key,$value);
42
6b4ac661 43 my(@pairs) = split("; ?",$raw_cookie);
424ec8fa 44 foreach (@pairs) {
6b4ac661
JH
45 s/\s*(.*?)\s*/$1/;
46 if (/^([^=]+)=(.*)/) {
47 $key = $1;
48 $value = $2;
49 }
50 else {
51 $key = $_;
52 $value = '';
53 }
54 $results{$key} = $value;
424ec8fa
GS
55 }
56 return \%results unless wantarray;
57 return %results;
58}
59
424ec8fa 60
ba056755
JH
61sub parse {
62 my ($self,$raw_cookie) = @_;
63 my %results;
64
65 my(@pairs) = split("; ?",$raw_cookie);
66 foreach (@pairs) {
67 s/\s*(.*?)\s*/$1/;
199d4a26 68 my($key,$value) = split("=",$_,2);
ba056755
JH
69
70 # Some foreign cookies are not in name=value format, so ignore
71 # them.
72 next if !defined($value);
73 my @values = ();
74 if ($value ne '') {
199d4a26 75 @values = map unescape($_),split(/[&;]/,$value.'&dmy');
ba056755 76 pop @values;
424ec8fa 77 }
ba056755
JH
78 $key = unescape($key);
79 # A bug in Netscape can cause several cookies with same name to
80 # appear. The FIRST one in HTTP_COOKIE is the most recent version.
81 $results{$key} ||= $self->new(-name=>$key,-value=>\@values);
82 }
83 return \%results unless wantarray;
84 return %results;
424ec8fa
GS
85}
86
87sub new {
ba056755
JH
88 my $class = shift;
89 $class = ref($class) if ref($class);
90 my($name,$value,$path,$domain,$secure,$expires) =
91 rearrange([NAME,[VALUE,VALUES],PATH,DOMAIN,SECURE,EXPIRES],@_);
92
93 # Pull out our parameters.
94 my @values;
95 if (ref($value)) {
96 if (ref($value) eq 'ARRAY') {
97 @values = @$value;
98 } elsif (ref($value) eq 'HASH') {
99 @values = %$value;
424ec8fa 100 }
ba056755
JH
101 } else {
102 @values = ($value);
103 }
104
105 bless my $self = {
106 'name'=>$name,
107 'value'=>[@values],
108 },$class;
109
110 # IE requires the path and domain to be present for some reason.
111 $path ||= "/";
112 # however, this breaks networks which use host tables without fully qualified
113 # names, so we comment it out.
114 # $domain = CGI::virtual_host() unless defined $domain;
115
116 $self->path($path) if defined $path;
117 $self->domain($domain) if defined $domain;
118 $self->secure($secure) if defined $secure;
119 $self->expires($expires) if defined $expires;
120 return $self;
424ec8fa
GS
121}
122
123sub as_string {
124 my $self = shift;
125 return "" unless $self->name;
126
127 my(@constant_values,$domain,$path,$expires,$secure);
128
129 push(@constant_values,"domain=$domain") if $domain = $self->domain;
130 push(@constant_values,"path=$path") if $path = $self->path;
131 push(@constant_values,"expires=$expires") if $expires = $self->expires;
ba056755 132 push(@constant_values,"secure") if $secure = $self->secure;
424ec8fa 133
3d1a2ec4
GS
134 my($key) = escape($self->name);
135 my($cookie) = join("=",$key,join("&",map escape($_),$self->value));
424ec8fa
GS
136 return join("; ",$cookie,@constant_values);
137}
138
139sub compare {
140 my $self = shift;
141 my $value = shift;
142 return "$self" cmp $value;
143}
144
145# accessors
146sub name {
147 my $self = shift;
148 my $name = shift;
149 $self->{'name'} = $name if defined $name;
150 return $self->{'name'};
151}
152
153sub value {
154 my $self = shift;
155 my $value = shift;
ac734d8b
JH
156 if (defined $value) {
157 my @values;
158 if (ref($value)) {
159 if (ref($value) eq 'ARRAY') {
160 @values = @$value;
161 } elsif (ref($value) eq 'HASH') {
162 @values = %$value;
163 }
164 } else {
165 @values = ($value);
166 }
167 $self->{'value'} = [@values];
168 }
424ec8fa
GS
169 return wantarray ? @{$self->{'value'}} : $self->{'value'}->[0]
170}
171
172sub domain {
173 my $self = shift;
174 my $domain = shift;
175 $self->{'domain'} = $domain if defined $domain;
176 return $self->{'domain'};
177}
178
179sub secure {
180 my $self = shift;
181 my $secure = shift;
182 $self->{'secure'} = $secure if defined $secure;
183 return $self->{'secure'};
184}
185
186sub expires {
187 my $self = shift;
188 my $expires = shift;
3d1a2ec4 189 $self->{'expires'} = CGI::Util::expires($expires,'cookie') if defined $expires;
424ec8fa
GS
190 return $self->{'expires'};
191}
192
193sub path {
194 my $self = shift;
195 my $path = shift;
196 $self->{'path'} = $path if defined $path;
197 return $self->{'path'};
198}
199
2001;
201
202=head1 NAME
203
204CGI::Cookie - Interface to Netscape Cookies
205
206=head1 SYNOPSIS
207
208 use CGI qw/:standard/;
209 use CGI::Cookie;
210
211 # Create new cookies and send them
212 $cookie1 = new CGI::Cookie(-name=>'ID',-value=>123456);
213 $cookie2 = new CGI::Cookie(-name=>'preferences',
214 -value=>{ font => Helvetica,
215 size => 12 }
216 );
217 print header(-cookie=>[$cookie1,$cookie2]);
218
219 # fetch existing cookies
220 %cookies = fetch CGI::Cookie;
221 $id = $cookies{'ID'}->value;
222
223 # create cookies returned from an external source
224 %cookies = parse CGI::Cookie($ENV{COOKIE});
225
226=head1 DESCRIPTION
227
228CGI::Cookie is an interface to Netscape (HTTP/1.1) cookies, an
229innovation that allows Web servers to store persistent information on
230the browser's side of the connection. Although CGI::Cookie is
231intended to be used in conjunction with CGI.pm (and is in fact used by
232it internally), you can use this module independently.
233
234For full information on cookies see
235
236 http://www.ics.uci.edu/pub/ietf/http/rfc2109.txt
237
238=head1 USING CGI::Cookie
239
240CGI::Cookie is object oriented. Each cookie object has a name and a
241value. The name is any scalar value. The value is any scalar or
242array value (associative arrays are also allowed). Cookies also have
243several optional attributes, including:
244
245=over 4
246
247=item B<1. expiration date>
248
249The expiration date tells the browser how long to hang on to the
250cookie. If the cookie specifies an expiration date in the future, the
251browser will store the cookie information in a disk file and return it
252to the server every time the user reconnects (until the expiration
253date is reached). If the cookie species an expiration date in the
254past, the browser will remove the cookie from the disk file. If the
255expiration date is not specified, the cookie will persist only until
256the user quits the browser.
257
258=item B<2. domain>
259
260This is a partial or complete domain name for which the cookie is
261valid. The browser will return the cookie to any host that matches
262the partial domain name. For example, if you specify a domain name
263of ".capricorn.com", then Netscape will return the cookie to
264Web servers running on any of the machines "www.capricorn.com",
265"ftp.capricorn.com", "feckless.capricorn.com", etc. Domain names
266must contain at least two periods to prevent attempts to match
267on top level domains like ".edu". If no domain is specified, then
268the browser will only return the cookie to servers on the host the
269cookie originated from.
270
271=item B<3. path>
272
273If you provide a cookie path attribute, the browser will check it
274against your script's URL before returning the cookie. For example,
275if you specify the path "/cgi-bin", then the cookie will be returned
3538e1d5
GS
276to each of the scripts "/cgi-bin/tally.pl", "/cgi-bin/order.pl", and
277"/cgi-bin/customer_service/complain.pl", but not to the script
3d1a2ec4
GS
278"/cgi-private/site_admin.pl". By default, the path is set to "/", so
279that all scripts at your site will receive the cookie.
424ec8fa
GS
280
281=item B<4. secure flag>
282
283If the "secure" attribute is set, the cookie will only be sent to your
284script if the CGI request is occurring on a secure channel, such as SSL.
285
286=back
287
288=head2 Creating New Cookies
289
290 $c = new CGI::Cookie(-name => 'foo',
291 -value => 'bar',
292 -expires => '+3M',
293 -domain => '.capricorn.com',
199d4a26 294 -path => '/cgi-bin/database',
424ec8fa
GS
295 -secure => 1
296 );
297
298Create cookies from scratch with the B<new> method. The B<-name> and
299B<-value> parameters are required. The name must be a scalar value.
300The value can be a scalar, an array reference, or a hash reference.
301(At some point in the future cookies will support one of the Perl
302object serialization protocols for full generality).
303
304B<-expires> accepts any of the relative or absolute date formats
305recognized by CGI.pm, for example "+3M" for three months in the
306future. See CGI.pm's documentation for details.
307
308B<-domain> points to a domain name or to a fully qualified host name.
309If not specified, the cookie will be returned only to the Web server
310that created it.
311
312B<-path> points to a partial URL on the current server. The cookie
313will be returned to all URLs beginning with the specified path. If
314not specified, it defaults to '/', which returns the cookie to all
315pages at your site.
316
317B<-secure> if set to a true value instructs the browser to return the
318cookie only when a cryptographic protocol is in use.
319
320=head2 Sending the Cookie to the Browser
321
322Within a CGI script you can send a cookie to the browser by creating
323one or more Set-Cookie: fields in the HTTP header. Here is a typical
324sequence:
325
326 my $c = new CGI::Cookie(-name => 'foo',
327 -value => ['bar','baz'],
328 -expires => '+3M');
329
330 print "Set-Cookie: $c\n";
331 print "Content-Type: text/html\n\n";
332
333To send more than one cookie, create several Set-Cookie: fields.
334Alternatively, you may concatenate the cookies together with "; " and
335send them in one field.
336
337If you are using CGI.pm, you send cookies by providing a -cookie
338argument to the header() method:
339
340 print header(-cookie=>$c);
341
342Mod_perl users can set cookies using the request object's header_out()
343method:
344
345 $r->header_out('Set-Cookie',$c);
346
347Internally, Cookie overloads the "" operator to call its as_string()
348method when incorporated into the HTTP header. as_string() turns the
349Cookie's internal representation into an RFC-compliant text
350representation. You may call as_string() yourself if you prefer:
351
352 print "Set-Cookie: ",$c->as_string,"\n";
353
354=head2 Recovering Previous Cookies
355
356 %cookies = fetch CGI::Cookie;
357
358B<fetch> returns an associative array consisting of all cookies
359returned by the browser. The keys of the array are the cookie names. You
360can iterate through the cookies this way:
361
362 %cookies = fetch CGI::Cookie;
363 foreach (keys %cookies) {
364 do_something($cookies{$_});
365 }
366
367In a scalar context, fetch() returns a hash reference, which may be more
368efficient if you are manipulating multiple cookies.
3cb6de81 369
424ec8fa
GS
370CGI.pm uses the URL escaping methods to save and restore reserved characters
371in its cookies. If you are trying to retrieve a cookie set by a foreign server,
372this escaping method may trip you up. Use raw_fetch() instead, which has the
373same semantics as fetch(), but performs no unescaping.
374
375You may also retrieve cookies that were stored in some external
376form using the parse() class method:
377
378 $COOKIES = `cat /usr/tmp/Cookie_stash`;
379 %cookies = parse CGI::Cookie($COOKIES);
380
381=head2 Manipulating Cookies
382
383Cookie objects have a series of accessor methods to get and set cookie
384attributes. Each accessor has a similar syntax. Called without
385arguments, the accessor returns the current value of the attribute.
386Called with an argument, the accessor changes the attribute and
387returns its new value.
388
389=over 4
390
391=item B<name()>
392
393Get or set the cookie's name. Example:
394
395 $name = $c->name;
396 $new_name = $c->name('fred');
397
398=item B<value()>
399
400Get or set the cookie's value. Example:
401
402 $value = $c->value;
403 @new_value = $c->value(['a','b','c','d']);
404
a3b3a725 405B<value()> is context sensitive. In a list context it will return
424ec8fa
GS
406the current value of the cookie as an array. In a scalar context it
407will return the B<first> value of a multivalued cookie.
408
409=item B<domain()>
410
411Get or set the cookie's domain.
412
413=item B<path()>
414
415Get or set the cookie's path.
416
417=item B<expires()>
418
419Get or set the cookie's expiration time.
420
421=back
422
423
424=head1 AUTHOR INFORMATION
425
71f3e297 426Copyright 1997-1998, Lincoln D. Stein. All rights reserved.
424ec8fa 427
71f3e297
JH
428This library is free software; you can redistribute it and/or modify
429it under the same terms as Perl itself.
430
431Address bug reports and comments to: lstein@cshl.org
424ec8fa
GS
432
433=head1 BUGS
434
435This section intentionally left blank.
436
437=head1 SEE ALSO
438
439L<CGI::Carp>, L<CGI>
3cb6de81 440
424ec8fa 441=cut