xref: /onnv-gate/usr/src/cmd/perl/5.8.4/distrib/lib/CGI/Cookie.pm (revision 6287:9a1f5d2c8dd8)
10Sstevel@tonic-gatepackage CGI::Cookie;
20Sstevel@tonic-gate
30Sstevel@tonic-gate# See the bottom of this file for the POD documentation.  Search for the
40Sstevel@tonic-gate# string '=head'.
50Sstevel@tonic-gate
60Sstevel@tonic-gate# You can run this file through either pod2man or pod2html to produce pretty
70Sstevel@tonic-gate# documentation in manual or html file format (these utilities are part of the
80Sstevel@tonic-gate# Perl 5 distribution).
90Sstevel@tonic-gate
100Sstevel@tonic-gate# Copyright 1995-1999, Lincoln D. Stein.  All rights reserved.
110Sstevel@tonic-gate# It may be used and modified freely, but I do request that this copyright
120Sstevel@tonic-gate# notice remain attached to the file.  You may modify this module as you
130Sstevel@tonic-gate# wish, but if you redistribute a modified version, please attach a note
140Sstevel@tonic-gate# listing the modifications you have made.
150Sstevel@tonic-gate
16*6287Sps156622$CGI::Cookie::VERSION='1.28';
170Sstevel@tonic-gate
180Sstevel@tonic-gateuse CGI::Util qw(rearrange unescape escape);
19*6287Sps156622use CGI;
200Sstevel@tonic-gateuse overload '""' => \&as_string,
210Sstevel@tonic-gate    'cmp' => \&compare,
220Sstevel@tonic-gate    'fallback'=>1;
230Sstevel@tonic-gate
240Sstevel@tonic-gate# Turn on special checking for Doug MacEachern's modperl
250Sstevel@tonic-gatemy $MOD_PERL = 0;
260Sstevel@tonic-gateif (exists $ENV{MOD_PERL}) {
27667Sps156622  if (exists $ENV{MOD_PERL_API_VERSION} && $ENV{MOD_PERL_API_VERSION} == 2) {
280Sstevel@tonic-gate      $MOD_PERL = 2;
29667Sps156622      require Apache2::RequestUtil;
30667Sps156622      require APR::Table;
31667Sps156622  } else {
32667Sps156622    $MOD_PERL = 1;
33667Sps156622    require Apache;
340Sstevel@tonic-gate  }
350Sstevel@tonic-gate}
360Sstevel@tonic-gate
370Sstevel@tonic-gate# fetch a list of cookies from the environment and
380Sstevel@tonic-gate# return as a hash.  the cookies are parsed as normal
390Sstevel@tonic-gate# escaped URL data.
400Sstevel@tonic-gatesub fetch {
410Sstevel@tonic-gate    my $class = shift;
420Sstevel@tonic-gate    my $raw_cookie = get_raw_cookie(@_) or return;
430Sstevel@tonic-gate    return $class->parse($raw_cookie);
440Sstevel@tonic-gate}
450Sstevel@tonic-gate
460Sstevel@tonic-gate# Fetch a list of cookies from the environment or the incoming headers and
470Sstevel@tonic-gate# return as a hash. The cookie values are not unescaped or altered in any way.
480Sstevel@tonic-gate sub raw_fetch {
490Sstevel@tonic-gate   my $class = shift;
500Sstevel@tonic-gate   my $raw_cookie = get_raw_cookie(@_) or return;
510Sstevel@tonic-gate   my %results;
520Sstevel@tonic-gate   my($key,$value);
530Sstevel@tonic-gate
54*6287Sps156622   my(@pairs) = split("[;,] ?",$raw_cookie);
550Sstevel@tonic-gate   foreach (@pairs) {
560Sstevel@tonic-gate     s/\s*(.*?)\s*/$1/;
570Sstevel@tonic-gate     if (/^([^=]+)=(.*)/) {
580Sstevel@tonic-gate       $key = $1;
590Sstevel@tonic-gate       $value = $2;
600Sstevel@tonic-gate     }
610Sstevel@tonic-gate     else {
620Sstevel@tonic-gate       $key = $_;
630Sstevel@tonic-gate       $value = '';
640Sstevel@tonic-gate     }
650Sstevel@tonic-gate     $results{$key} = $value;
660Sstevel@tonic-gate   }
670Sstevel@tonic-gate   return \%results unless wantarray;
680Sstevel@tonic-gate   return %results;
690Sstevel@tonic-gate}
700Sstevel@tonic-gate
710Sstevel@tonic-gatesub get_raw_cookie {
720Sstevel@tonic-gate  my $r = shift;
73667Sps156622  $r ||= eval { $MOD_PERL == 2                    ?
74667Sps156622                  Apache2::RequestUtil->request() :
75667Sps156622                  Apache->request } if $MOD_PERL;
760Sstevel@tonic-gate  if ($r) {
770Sstevel@tonic-gate    $raw_cookie = $r->headers_in->{'Cookie'};
780Sstevel@tonic-gate  } else {
790Sstevel@tonic-gate    if ($MOD_PERL && !exists $ENV{REQUEST_METHOD}) {
800Sstevel@tonic-gate      die "Run $r->subprocess_env; before calling fetch()";
810Sstevel@tonic-gate    }
820Sstevel@tonic-gate    $raw_cookie = $ENV{HTTP_COOKIE} || $ENV{COOKIE};
830Sstevel@tonic-gate  }
840Sstevel@tonic-gate}
850Sstevel@tonic-gate
860Sstevel@tonic-gate
870Sstevel@tonic-gatesub parse {
880Sstevel@tonic-gate  my ($self,$raw_cookie) = @_;
890Sstevel@tonic-gate  my %results;
900Sstevel@tonic-gate
910Sstevel@tonic-gate  my(@pairs) = split("; ?",$raw_cookie);
920Sstevel@tonic-gate  foreach (@pairs) {
930Sstevel@tonic-gate    s/\s*(.*?)\s*/$1/;
940Sstevel@tonic-gate    my($key,$value) = split("=",$_,2);
950Sstevel@tonic-gate
960Sstevel@tonic-gate    # Some foreign cookies are not in name=value format, so ignore
970Sstevel@tonic-gate    # them.
980Sstevel@tonic-gate    next if !defined($value);
990Sstevel@tonic-gate    my @values = ();
1000Sstevel@tonic-gate    if ($value ne '') {
1010Sstevel@tonic-gate      @values = map unescape($_),split(/[&;]/,$value.'&dmy');
1020Sstevel@tonic-gate      pop @values;
1030Sstevel@tonic-gate    }
1040Sstevel@tonic-gate    $key = unescape($key);
1050Sstevel@tonic-gate    # A bug in Netscape can cause several cookies with same name to
1060Sstevel@tonic-gate    # appear.  The FIRST one in HTTP_COOKIE is the most recent version.
1070Sstevel@tonic-gate    $results{$key} ||= $self->new(-name=>$key,-value=>\@values);
1080Sstevel@tonic-gate  }
1090Sstevel@tonic-gate  return \%results unless wantarray;
1100Sstevel@tonic-gate  return %results;
1110Sstevel@tonic-gate}
1120Sstevel@tonic-gate
1130Sstevel@tonic-gatesub new {
1140Sstevel@tonic-gate  my $class = shift;
1150Sstevel@tonic-gate  $class = ref($class) if ref($class);
116*6287Sps156622  # Ignore mod_perl request object--compatability with Apache::Cookie.
117*6287Sps156622  shift if ref $_[0]
118*6287Sps156622        && eval { $_[0]->isa('Apache::Request::Req') || $_[0]->isa('Apache') };
119*6287Sps156622  my($name,$value,$path,$domain,$secure,$expires,$httponly) =
120*6287Sps156622    rearrange([NAME,[VALUE,VALUES],PATH,DOMAIN,SECURE,EXPIRES,HTTPONLY],@_);
1210Sstevel@tonic-gate
1220Sstevel@tonic-gate  # Pull out our parameters.
1230Sstevel@tonic-gate  my @values;
1240Sstevel@tonic-gate  if (ref($value)) {
1250Sstevel@tonic-gate    if (ref($value) eq 'ARRAY') {
1260Sstevel@tonic-gate      @values = @$value;
1270Sstevel@tonic-gate    } elsif (ref($value) eq 'HASH') {
1280Sstevel@tonic-gate      @values = %$value;
1290Sstevel@tonic-gate    }
1300Sstevel@tonic-gate  } else {
1310Sstevel@tonic-gate    @values = ($value);
1320Sstevel@tonic-gate  }
1330Sstevel@tonic-gate
1340Sstevel@tonic-gate  bless my $self = {
1350Sstevel@tonic-gate		    'name'=>$name,
1360Sstevel@tonic-gate		    'value'=>[@values],
1370Sstevel@tonic-gate		   },$class;
1380Sstevel@tonic-gate
1390Sstevel@tonic-gate  # IE requires the path and domain to be present for some reason.
1400Sstevel@tonic-gate  $path   ||= "/";
1410Sstevel@tonic-gate  # however, this breaks networks which use host tables without fully qualified
1420Sstevel@tonic-gate  # names, so we comment it out.
1430Sstevel@tonic-gate  #    $domain = CGI::virtual_host()    unless defined $domain;
1440Sstevel@tonic-gate
1450Sstevel@tonic-gate  $self->path($path)     if defined $path;
1460Sstevel@tonic-gate  $self->domain($domain) if defined $domain;
1470Sstevel@tonic-gate  $self->secure($secure) if defined $secure;
1480Sstevel@tonic-gate  $self->expires($expires) if defined $expires;
149*6287Sps156622  $self->httponly($httponly) if defined $httponly;
1500Sstevel@tonic-gate#  $self->max_age($expires) if defined $expires;
1510Sstevel@tonic-gate  return $self;
1520Sstevel@tonic-gate}
1530Sstevel@tonic-gate
1540Sstevel@tonic-gatesub as_string {
1550Sstevel@tonic-gate    my $self = shift;
1560Sstevel@tonic-gate    return "" unless $self->name;
1570Sstevel@tonic-gate
158*6287Sps156622    my(@constant_values,$domain,$path,$expires,$max_age,$secure,$httponly);
1590Sstevel@tonic-gate
1600Sstevel@tonic-gate    push(@constant_values,"domain=$domain")   if $domain = $self->domain;
1610Sstevel@tonic-gate    push(@constant_values,"path=$path")       if $path = $self->path;
1620Sstevel@tonic-gate    push(@constant_values,"expires=$expires") if $expires = $self->expires;
1630Sstevel@tonic-gate    push(@constant_values,"max-age=$max_age") if $max_age = $self->max_age;
1640Sstevel@tonic-gate    push(@constant_values,"secure") if $secure = $self->secure;
165*6287Sps156622    push(@constant_values,"HttpOnly") if $httponly = $self->httponly;
1660Sstevel@tonic-gate
1670Sstevel@tonic-gate    my($key) = escape($self->name);
168*6287Sps156622    my($cookie) = join("=",(defined $key ? $key : ''),join("&",map escape(defined $_ ? $_ : ''),$self->value));
1690Sstevel@tonic-gate    return join("; ",$cookie,@constant_values);
1700Sstevel@tonic-gate}
1710Sstevel@tonic-gate
1720Sstevel@tonic-gatesub compare {
1730Sstevel@tonic-gate    my $self = shift;
1740Sstevel@tonic-gate    my $value = shift;
1750Sstevel@tonic-gate    return "$self" cmp $value;
1760Sstevel@tonic-gate}
1770Sstevel@tonic-gate
178*6287Sps156622sub bake {
179*6287Sps156622  my ($self, $r) = @_;
180*6287Sps156622
181*6287Sps156622  $r ||= eval {
182*6287Sps156622      $MOD_PERL == 2
183*6287Sps156622          ? Apache2::RequestUtil->request()
184*6287Sps156622          : Apache->request
185*6287Sps156622  } if $MOD_PERL;
186*6287Sps156622  if ($r) {
187*6287Sps156622      $r->headers_out->add('Set-Cookie' => $self->as_string);
188*6287Sps156622  } else {
189*6287Sps156622      print CGI::header(-cookie => $self);
190*6287Sps156622  }
191*6287Sps156622
192*6287Sps156622}
193*6287Sps156622
1940Sstevel@tonic-gate# accessors
1950Sstevel@tonic-gatesub name {
1960Sstevel@tonic-gate    my $self = shift;
1970Sstevel@tonic-gate    my $name = shift;
1980Sstevel@tonic-gate    $self->{'name'} = $name if defined $name;
1990Sstevel@tonic-gate    return $self->{'name'};
2000Sstevel@tonic-gate}
2010Sstevel@tonic-gate
2020Sstevel@tonic-gatesub value {
2030Sstevel@tonic-gate    my $self = shift;
2040Sstevel@tonic-gate    my $value = shift;
2050Sstevel@tonic-gate      if (defined $value) {
2060Sstevel@tonic-gate              my @values;
2070Sstevel@tonic-gate        if (ref($value)) {
2080Sstevel@tonic-gate            if (ref($value) eq 'ARRAY') {
2090Sstevel@tonic-gate                @values = @$value;
2100Sstevel@tonic-gate            } elsif (ref($value) eq 'HASH') {
2110Sstevel@tonic-gate                @values = %$value;
2120Sstevel@tonic-gate            }
2130Sstevel@tonic-gate        } else {
2140Sstevel@tonic-gate            @values = ($value);
2150Sstevel@tonic-gate        }
2160Sstevel@tonic-gate      $self->{'value'} = [@values];
2170Sstevel@tonic-gate      }
2180Sstevel@tonic-gate    return wantarray ? @{$self->{'value'}} : $self->{'value'}->[0]
2190Sstevel@tonic-gate}
2200Sstevel@tonic-gate
2210Sstevel@tonic-gatesub domain {
2220Sstevel@tonic-gate    my $self = shift;
2230Sstevel@tonic-gate    my $domain = shift;
224667Sps156622    $self->{'domain'} = lc $domain if defined $domain;
2250Sstevel@tonic-gate    return $self->{'domain'};
2260Sstevel@tonic-gate}
2270Sstevel@tonic-gate
2280Sstevel@tonic-gatesub secure {
2290Sstevel@tonic-gate    my $self = shift;
2300Sstevel@tonic-gate    my $secure = shift;
2310Sstevel@tonic-gate    $self->{'secure'} = $secure if defined $secure;
2320Sstevel@tonic-gate    return $self->{'secure'};
2330Sstevel@tonic-gate}
2340Sstevel@tonic-gate
2350Sstevel@tonic-gatesub expires {
2360Sstevel@tonic-gate    my $self = shift;
2370Sstevel@tonic-gate    my $expires = shift;
2380Sstevel@tonic-gate    $self->{'expires'} = CGI::Util::expires($expires,'cookie') if defined $expires;
2390Sstevel@tonic-gate    return $self->{'expires'};
2400Sstevel@tonic-gate}
2410Sstevel@tonic-gate
2420Sstevel@tonic-gatesub max_age {
2430Sstevel@tonic-gate  my $self = shift;
2440Sstevel@tonic-gate  my $expires = shift;
2450Sstevel@tonic-gate  $self->{'max-age'} = CGI::Util::expire_calc($expires)-time() if defined $expires;
2460Sstevel@tonic-gate  return $self->{'max-age'};
2470Sstevel@tonic-gate}
2480Sstevel@tonic-gate
2490Sstevel@tonic-gatesub path {
2500Sstevel@tonic-gate    my $self = shift;
2510Sstevel@tonic-gate    my $path = shift;
2520Sstevel@tonic-gate    $self->{'path'} = $path if defined $path;
2530Sstevel@tonic-gate    return $self->{'path'};
2540Sstevel@tonic-gate}
2550Sstevel@tonic-gate
256*6287Sps156622
257*6287Sps156622sub httponly { # HttpOnly
258*6287Sps156622    my $self     = shift;
259*6287Sps156622    my $httponly = shift;
260*6287Sps156622    $self->{'httponly'} = $httponly if defined $httponly;
261*6287Sps156622    return $self->{'httponly'};
262*6287Sps156622}
263*6287Sps156622
2640Sstevel@tonic-gate1;
2650Sstevel@tonic-gate
2660Sstevel@tonic-gate=head1 NAME
2670Sstevel@tonic-gate
2680Sstevel@tonic-gateCGI::Cookie - Interface to Netscape Cookies
2690Sstevel@tonic-gate
2700Sstevel@tonic-gate=head1 SYNOPSIS
2710Sstevel@tonic-gate
2720Sstevel@tonic-gate    use CGI qw/:standard/;
2730Sstevel@tonic-gate    use CGI::Cookie;
2740Sstevel@tonic-gate
2750Sstevel@tonic-gate    # Create new cookies and send them
2760Sstevel@tonic-gate    $cookie1 = new CGI::Cookie(-name=>'ID',-value=>123456);
2770Sstevel@tonic-gate    $cookie2 = new CGI::Cookie(-name=>'preferences',
2780Sstevel@tonic-gate                               -value=>{ font => Helvetica,
2790Sstevel@tonic-gate                                         size => 12 }
2800Sstevel@tonic-gate                               );
2810Sstevel@tonic-gate    print header(-cookie=>[$cookie1,$cookie2]);
2820Sstevel@tonic-gate
2830Sstevel@tonic-gate    # fetch existing cookies
2840Sstevel@tonic-gate    %cookies = fetch CGI::Cookie;
2850Sstevel@tonic-gate    $id = $cookies{'ID'}->value;
2860Sstevel@tonic-gate
2870Sstevel@tonic-gate    # create cookies returned from an external source
2880Sstevel@tonic-gate    %cookies = parse CGI::Cookie($ENV{COOKIE});
2890Sstevel@tonic-gate
2900Sstevel@tonic-gate=head1 DESCRIPTION
2910Sstevel@tonic-gate
2920Sstevel@tonic-gateCGI::Cookie is an interface to Netscape (HTTP/1.1) cookies, an
2930Sstevel@tonic-gateinnovation that allows Web servers to store persistent information on
2940Sstevel@tonic-gatethe browser's side of the connection.  Although CGI::Cookie is
2950Sstevel@tonic-gateintended to be used in conjunction with CGI.pm (and is in fact used by
2960Sstevel@tonic-gateit internally), you can use this module independently.
2970Sstevel@tonic-gate
2980Sstevel@tonic-gateFor full information on cookies see
2990Sstevel@tonic-gate
3000Sstevel@tonic-gate	http://www.ics.uci.edu/pub/ietf/http/rfc2109.txt
3010Sstevel@tonic-gate
3020Sstevel@tonic-gate=head1 USING CGI::Cookie
3030Sstevel@tonic-gate
3040Sstevel@tonic-gateCGI::Cookie is object oriented.  Each cookie object has a name and a
3050Sstevel@tonic-gatevalue.  The name is any scalar value.  The value is any scalar or
3060Sstevel@tonic-gatearray value (associative arrays are also allowed).  Cookies also have
3070Sstevel@tonic-gateseveral optional attributes, including:
3080Sstevel@tonic-gate
3090Sstevel@tonic-gate=over 4
3100Sstevel@tonic-gate
3110Sstevel@tonic-gate=item B<1. expiration date>
3120Sstevel@tonic-gate
3130Sstevel@tonic-gateThe expiration date tells the browser how long to hang on to the
3140Sstevel@tonic-gatecookie.  If the cookie specifies an expiration date in the future, the
3150Sstevel@tonic-gatebrowser will store the cookie information in a disk file and return it
3160Sstevel@tonic-gateto the server every time the user reconnects (until the expiration
3170Sstevel@tonic-gatedate is reached).  If the cookie species an expiration date in the
3180Sstevel@tonic-gatepast, the browser will remove the cookie from the disk file.  If the
3190Sstevel@tonic-gateexpiration date is not specified, the cookie will persist only until
3200Sstevel@tonic-gatethe user quits the browser.
3210Sstevel@tonic-gate
3220Sstevel@tonic-gate=item B<2. domain>
3230Sstevel@tonic-gate
3240Sstevel@tonic-gateThis is a partial or complete domain name for which the cookie is
3250Sstevel@tonic-gatevalid.  The browser will return the cookie to any host that matches
3260Sstevel@tonic-gatethe partial domain name.  For example, if you specify a domain name
3270Sstevel@tonic-gateof ".capricorn.com", then Netscape will return the cookie to
3280Sstevel@tonic-gateWeb servers running on any of the machines "www.capricorn.com",
3290Sstevel@tonic-gate"ftp.capricorn.com", "feckless.capricorn.com", etc.  Domain names
3300Sstevel@tonic-gatemust contain at least two periods to prevent attempts to match
3310Sstevel@tonic-gateon top level domains like ".edu".  If no domain is specified, then
3320Sstevel@tonic-gatethe browser will only return the cookie to servers on the host the
3330Sstevel@tonic-gatecookie originated from.
3340Sstevel@tonic-gate
3350Sstevel@tonic-gate=item B<3. path>
3360Sstevel@tonic-gate
3370Sstevel@tonic-gateIf you provide a cookie path attribute, the browser will check it
3380Sstevel@tonic-gateagainst your script's URL before returning the cookie.  For example,
3390Sstevel@tonic-gateif you specify the path "/cgi-bin", then the cookie will be returned
3400Sstevel@tonic-gateto each of the scripts "/cgi-bin/tally.pl", "/cgi-bin/order.pl", and
3410Sstevel@tonic-gate"/cgi-bin/customer_service/complain.pl", but not to the script
3420Sstevel@tonic-gate"/cgi-private/site_admin.pl".  By default, the path is set to "/", so
3430Sstevel@tonic-gatethat all scripts at your site will receive the cookie.
3440Sstevel@tonic-gate
3450Sstevel@tonic-gate=item B<4. secure flag>
3460Sstevel@tonic-gate
3470Sstevel@tonic-gateIf the "secure" attribute is set, the cookie will only be sent to your
3480Sstevel@tonic-gatescript if the CGI request is occurring on a secure channel, such as SSL.
3490Sstevel@tonic-gate
350*6287Sps156622=item B<4. httponly flag>
351*6287Sps156622
352*6287Sps156622If the "httponly" attribute is set, the cookie will only be accessible
353*6287Sps156622through HTTP Requests. This cookie will be inaccessible via JavaScript
354*6287Sps156622(to prevent XSS attacks).
355*6287Sps156622
356*6287Sps156622But, currently this feature only used and recognised by
357*6287Sps156622MS Internet Explorer 6 Service Pack 1 and later.
358*6287Sps156622
359*6287Sps156622See this URL for more information:
360*6287Sps156622
361*6287Sps156622L<http://msdn.microsoft.com/workshop/author/dhtml/httponly_cookies.asp>
362*6287Sps156622
3630Sstevel@tonic-gate=back
3640Sstevel@tonic-gate
3650Sstevel@tonic-gate=head2 Creating New Cookies
3660Sstevel@tonic-gate
367*6287Sps156622	my $c = new CGI::Cookie(-name    =>  'foo',
3680Sstevel@tonic-gate                             -value   =>  'bar',
3690Sstevel@tonic-gate                             -expires =>  '+3M',
3700Sstevel@tonic-gate                             -domain  =>  '.capricorn.com',
3710Sstevel@tonic-gate                             -path    =>  '/cgi-bin/database',
3720Sstevel@tonic-gate                             -secure  =>  1
3730Sstevel@tonic-gate	                    );
3740Sstevel@tonic-gate
3750Sstevel@tonic-gateCreate cookies from scratch with the B<new> method.  The B<-name> and
3760Sstevel@tonic-gateB<-value> parameters are required.  The name must be a scalar value.
3770Sstevel@tonic-gateThe value can be a scalar, an array reference, or a hash reference.
3780Sstevel@tonic-gate(At some point in the future cookies will support one of the Perl
3790Sstevel@tonic-gateobject serialization protocols for full generality).
3800Sstevel@tonic-gate
3810Sstevel@tonic-gateB<-expires> accepts any of the relative or absolute date formats
3820Sstevel@tonic-gaterecognized by CGI.pm, for example "+3M" for three months in the
3830Sstevel@tonic-gatefuture.  See CGI.pm's documentation for details.
3840Sstevel@tonic-gate
3850Sstevel@tonic-gateB<-domain> points to a domain name or to a fully qualified host name.
3860Sstevel@tonic-gateIf not specified, the cookie will be returned only to the Web server
3870Sstevel@tonic-gatethat created it.
3880Sstevel@tonic-gate
3890Sstevel@tonic-gateB<-path> points to a partial URL on the current server.  The cookie
3900Sstevel@tonic-gatewill be returned to all URLs beginning with the specified path.  If
3910Sstevel@tonic-gatenot specified, it defaults to '/', which returns the cookie to all
3920Sstevel@tonic-gatepages at your site.
3930Sstevel@tonic-gate
3940Sstevel@tonic-gateB<-secure> if set to a true value instructs the browser to return the
3950Sstevel@tonic-gatecookie only when a cryptographic protocol is in use.
3960Sstevel@tonic-gate
397*6287Sps156622B<-httponly> if set to a true value, the cookie will not be accessible
398*6287Sps156622via JavaScript.
399*6287Sps156622
400*6287Sps156622For compatibility with Apache::Cookie, you may optionally pass in
401*6287Sps156622a mod_perl request object as the first argument to C<new()>. It will
402*6287Sps156622simply be ignored:
403*6287Sps156622
404*6287Sps156622  my $c = new CGI::Cookie($r,
405*6287Sps156622                          -name    =>  'foo',
406*6287Sps156622                          -value   =>  ['bar','baz']);
407*6287Sps156622
4080Sstevel@tonic-gate=head2 Sending the Cookie to the Browser
4090Sstevel@tonic-gate
410*6287Sps156622The simplest way to send a cookie to the browser is by calling the bake()
411*6287Sps156622method:
412*6287Sps156622
413*6287Sps156622  $c->bake;
414*6287Sps156622
415*6287Sps156622Under mod_perl, pass in an Apache request object:
416*6287Sps156622
417*6287Sps156622  $c->bake($r);
418*6287Sps156622
419*6287Sps156622If you want to set the cookie yourself, Within a CGI script you can send
420*6287Sps156622a cookie to the browser by creating one or more Set-Cookie: fields in the
421*6287Sps156622HTTP header.  Here is a typical sequence:
4220Sstevel@tonic-gate
4230Sstevel@tonic-gate  my $c = new CGI::Cookie(-name    =>  'foo',
4240Sstevel@tonic-gate                          -value   =>  ['bar','baz'],
4250Sstevel@tonic-gate                          -expires =>  '+3M');
4260Sstevel@tonic-gate
4270Sstevel@tonic-gate  print "Set-Cookie: $c\n";
4280Sstevel@tonic-gate  print "Content-Type: text/html\n\n";
4290Sstevel@tonic-gate
4300Sstevel@tonic-gateTo send more than one cookie, create several Set-Cookie: fields.
4310Sstevel@tonic-gate
4320Sstevel@tonic-gateIf you are using CGI.pm, you send cookies by providing a -cookie
4330Sstevel@tonic-gateargument to the header() method:
4340Sstevel@tonic-gate
4350Sstevel@tonic-gate  print header(-cookie=>$c);
4360Sstevel@tonic-gate
4370Sstevel@tonic-gateMod_perl users can set cookies using the request object's header_out()
4380Sstevel@tonic-gatemethod:
4390Sstevel@tonic-gate
4400Sstevel@tonic-gate  $r->headers_out->set('Set-Cookie' => $c);
4410Sstevel@tonic-gate
4420Sstevel@tonic-gateInternally, Cookie overloads the "" operator to call its as_string()
4430Sstevel@tonic-gatemethod when incorporated into the HTTP header.  as_string() turns the
4440Sstevel@tonic-gateCookie's internal representation into an RFC-compliant text
4450Sstevel@tonic-gaterepresentation.  You may call as_string() yourself if you prefer:
4460Sstevel@tonic-gate
4470Sstevel@tonic-gate  print "Set-Cookie: ",$c->as_string,"\n";
4480Sstevel@tonic-gate
4490Sstevel@tonic-gate=head2 Recovering Previous Cookies
4500Sstevel@tonic-gate
4510Sstevel@tonic-gate	%cookies = fetch CGI::Cookie;
4520Sstevel@tonic-gate
4530Sstevel@tonic-gateB<fetch> returns an associative array consisting of all cookies
4540Sstevel@tonic-gatereturned by the browser.  The keys of the array are the cookie names.  You
4550Sstevel@tonic-gatecan iterate through the cookies this way:
4560Sstevel@tonic-gate
4570Sstevel@tonic-gate	%cookies = fetch CGI::Cookie;
4580Sstevel@tonic-gate	foreach (keys %cookies) {
4590Sstevel@tonic-gate	   do_something($cookies{$_});
4600Sstevel@tonic-gate        }
4610Sstevel@tonic-gate
4620Sstevel@tonic-gateIn a scalar context, fetch() returns a hash reference, which may be more
4630Sstevel@tonic-gateefficient if you are manipulating multiple cookies.
4640Sstevel@tonic-gate
4650Sstevel@tonic-gateCGI.pm uses the URL escaping methods to save and restore reserved characters
4660Sstevel@tonic-gatein its cookies.  If you are trying to retrieve a cookie set by a foreign server,
4670Sstevel@tonic-gatethis escaping method may trip you up.  Use raw_fetch() instead, which has the
4680Sstevel@tonic-gatesame semantics as fetch(), but performs no unescaping.
4690Sstevel@tonic-gate
4700Sstevel@tonic-gateYou may also retrieve cookies that were stored in some external
4710Sstevel@tonic-gateform using the parse() class method:
4720Sstevel@tonic-gate
4730Sstevel@tonic-gate       $COOKIES = `cat /usr/tmp/Cookie_stash`;
4740Sstevel@tonic-gate       %cookies = parse CGI::Cookie($COOKIES);
4750Sstevel@tonic-gate
4760Sstevel@tonic-gateIf you are in a mod_perl environment, you can save some overhead by
4770Sstevel@tonic-gatepassing the request object to fetch() like this:
4780Sstevel@tonic-gate
4790Sstevel@tonic-gate   CGI::Cookie->fetch($r);
4800Sstevel@tonic-gate
4810Sstevel@tonic-gate=head2 Manipulating Cookies
4820Sstevel@tonic-gate
4830Sstevel@tonic-gateCookie objects have a series of accessor methods to get and set cookie
4840Sstevel@tonic-gateattributes.  Each accessor has a similar syntax.  Called without
4850Sstevel@tonic-gatearguments, the accessor returns the current value of the attribute.
4860Sstevel@tonic-gateCalled with an argument, the accessor changes the attribute and
4870Sstevel@tonic-gatereturns its new value.
4880Sstevel@tonic-gate
4890Sstevel@tonic-gate=over 4
4900Sstevel@tonic-gate
4910Sstevel@tonic-gate=item B<name()>
4920Sstevel@tonic-gate
4930Sstevel@tonic-gateGet or set the cookie's name.  Example:
4940Sstevel@tonic-gate
4950Sstevel@tonic-gate	$name = $c->name;
4960Sstevel@tonic-gate	$new_name = $c->name('fred');
4970Sstevel@tonic-gate
4980Sstevel@tonic-gate=item B<value()>
4990Sstevel@tonic-gate
5000Sstevel@tonic-gateGet or set the cookie's value.  Example:
5010Sstevel@tonic-gate
5020Sstevel@tonic-gate	$value = $c->value;
5030Sstevel@tonic-gate	@new_value = $c->value(['a','b','c','d']);
5040Sstevel@tonic-gate
5050Sstevel@tonic-gateB<value()> is context sensitive.  In a list context it will return
5060Sstevel@tonic-gatethe current value of the cookie as an array.  In a scalar context it
5070Sstevel@tonic-gatewill return the B<first> value of a multivalued cookie.
5080Sstevel@tonic-gate
5090Sstevel@tonic-gate=item B<domain()>
5100Sstevel@tonic-gate
5110Sstevel@tonic-gateGet or set the cookie's domain.
5120Sstevel@tonic-gate
5130Sstevel@tonic-gate=item B<path()>
5140Sstevel@tonic-gate
5150Sstevel@tonic-gateGet or set the cookie's path.
5160Sstevel@tonic-gate
5170Sstevel@tonic-gate=item B<expires()>
5180Sstevel@tonic-gate
5190Sstevel@tonic-gateGet or set the cookie's expiration time.
5200Sstevel@tonic-gate
5210Sstevel@tonic-gate=back
5220Sstevel@tonic-gate
5230Sstevel@tonic-gate
5240Sstevel@tonic-gate=head1 AUTHOR INFORMATION
5250Sstevel@tonic-gate
5260Sstevel@tonic-gateCopyright 1997-1998, Lincoln D. Stein.  All rights reserved.
5270Sstevel@tonic-gate
5280Sstevel@tonic-gateThis library is free software; you can redistribute it and/or modify
5290Sstevel@tonic-gateit under the same terms as Perl itself.
5300Sstevel@tonic-gate
5310Sstevel@tonic-gateAddress bug reports and comments to: lstein@cshl.org
5320Sstevel@tonic-gate
5330Sstevel@tonic-gate=head1 BUGS
5340Sstevel@tonic-gate
5350Sstevel@tonic-gateThis section intentionally left blank.
5360Sstevel@tonic-gate
5370Sstevel@tonic-gate=head1 SEE ALSO
5380Sstevel@tonic-gate
5390Sstevel@tonic-gateL<CGI::Carp>, L<CGI>
5400Sstevel@tonic-gate
5410Sstevel@tonic-gate=cut
542