📄 cookie.pm
字号:
package CGI::Cookie;# See the bottom of this file for the POD documentation. Search for the# string '=head'.# You can run this file through either pod2man or pod2html to produce pretty# documentation in manual or html file format (these utilities are part of the# Perl 5 distribution).# Copyright 1995-1999, Lincoln D. Stein. All rights reserved.# It may be used and modified freely, but I do request that this copyright# notice remain attached to the file. You may modify this module as you # wish, but if you redistribute a modified version, please attach a note# listing the modifications you have made.$CGI::Cookie::VERSION='1.18';use CGI::Util qw(rearrange unescape escape);use overload '""' => \&as_string, 'cmp' => \&compare, 'fallback'=>1;# fetch a list of cookies from the environment and# return as a hash. the cookies are parsed as normal# escaped URL data.sub fetch { my $class = shift; my $raw_cookie = $ENV{HTTP_COOKIE} || $ENV{COOKIE}; return () unless $raw_cookie; return $class->parse($raw_cookie);}# fetch a list of cookies from the environment and# return as a hash. the cookie values are not unescaped# or altered in any way.sub raw_fetch { my $class = shift; my $raw_cookie = $ENV{HTTP_COOKIE} || $ENV{COOKIE}; return () unless $raw_cookie; my %results; my($key,$value); my(@pairs) = split("; ?",$raw_cookie); foreach (@pairs) { s/\s*(.*?)\s*/$1/; if (/^([^=]+)=(.*)/) { $key = $1; $value = $2; } else { $key = $_; $value = ''; } $results{$key} = $value; } return \%results unless wantarray; return %results;}sub parse { my ($self,$raw_cookie) = @_; my %results; my(@pairs) = split("; ?",$raw_cookie); foreach (@pairs) { s/\s*(.*?)\s*/$1/; my($key,$value) = split("="); # Some foreign cookies are not in name=value format, so ignore # them. next if !defined($value); my @values = (); if ($value ne '') { @values = map CGI::unescape($_),split(/[&;]/,$value.'&dmy'); pop @values; } $key = unescape($key); # A bug in Netscape can cause several cookies with same name to # appear. The FIRST one in HTTP_COOKIE is the most recent version. $results{$key} ||= $self->new(-name=>$key,-value=>\@values); } return \%results unless wantarray; return %results;}sub new { my $class = shift; $class = ref($class) if ref($class); my($name,$value,$path,$domain,$secure,$expires) = rearrange([NAME,[VALUE,VALUES],PATH,DOMAIN,SECURE,EXPIRES],@_); # Pull out our parameters. my @values; if (ref($value)) { if (ref($value) eq 'ARRAY') { @values = @$value; } elsif (ref($value) eq 'HASH') { @values = %$value; } } else { @values = ($value); } bless my $self = { 'name'=>$name, 'value'=>[@values], },$class; # IE requires the path and domain to be present for some reason. $path ||= "/"; # however, this breaks networks which use host tables without fully qualified # names, so we comment it out. # $domain = CGI::virtual_host() unless defined $domain; $self->path($path) if defined $path; $self->domain($domain) if defined $domain; $self->secure($secure) if defined $secure; $self->expires($expires) if defined $expires; return $self;}sub as_string { my $self = shift; return "" unless $self->name; my(@constant_values,$domain,$path,$expires,$secure); push(@constant_values,"domain=$domain") if $domain = $self->domain; push(@constant_values,"path=$path") if $path = $self->path; push(@constant_values,"expires=$expires") if $expires = $self->expires; push(@constant_values,"secure") if $secure = $self->secure; my($key) = escape($self->name); my($cookie) = join("=",$key,join("&",map escape($_),$self->value)); return join("; ",$cookie,@constant_values);}sub compare { my $self = shift; my $value = shift; return "$self" cmp $value;}# accessorssub name { my $self = shift; my $name = shift; $self->{'name'} = $name if defined $name; return $self->{'name'};}sub value { my $self = shift; my $value = shift; $self->{'value'} = $value if defined $value; return wantarray ? @{$self->{'value'}} : $self->{'value'}->[0]}sub domain { my $self = shift; my $domain = shift; $self->{'domain'} = $domain if defined $domain; return $self->{'domain'};}sub secure { my $self = shift; my $secure = shift; $self->{'secure'} = $secure if defined $secure; return $self->{'secure'};}sub expires { my $self = shift; my $expires = shift; $self->{'expires'} = CGI::Util::expires($expires,'cookie') if defined $expires; return $self->{'expires'};}sub path { my $self = shift; my $path = shift; $self->{'path'} = $path if defined $path; return $self->{'path'};}1;=head1 NAMECGI::Cookie - Interface to Netscape Cookies=head1 SYNOPSIS use CGI qw/:standard/; use CGI::Cookie; # Create new cookies and send them $cookie1 = new CGI::Cookie(-name=>'ID',-value=>123456); $cookie2 = new CGI::Cookie(-name=>'preferences', -value=>{ font => Helvetica, size => 12 } ); print header(-cookie=>[$cookie1,$cookie2]); # fetch existing cookies %cookies = fetch CGI::Cookie; $id = $cookies{'ID'}->value; # create cookies returned from an external source %cookies = parse CGI::Cookie($ENV{COOKIE});=head1 DESCRIPTIONCGI::Cookie is an interface to Netscape (HTTP/1.1) cookies, aninnovation that allows Web servers to store persistent information onthe browser's side of the connection. Although CGI::Cookie isintended to be used in conjunction with CGI.pm (and is in fact used byit internally), you can use this module independently.For full information on cookies see http://www.ics.uci.edu/pub/ietf/http/rfc2109.txt=head1 USING CGI::CookieCGI::Cookie is object oriented. Each cookie object has a name and avalue. The name is any scalar value. The value is any scalar orarray value (associative arrays are also allowed). Cookies also haveseveral optional attributes, including:=over 4=item B<1. expiration date>The expiration date tells the browser how long to hang on to thecookie. If the cookie specifies an expiration date in the future, thebrowser will store the cookie information in a disk file and return itto the server every time the user reconnects (until the expirationdate is reached). If the cookie species an expiration date in thepast, the browser will remove the cookie from the disk file. If theexpiration date is not specified, the cookie will persist only untilthe user quits the browser.=item B<2. domain>This is a partial or complete domain name for which the cookie is valid. The browser will return the cookie to any host that matchesthe partial domain name. For example, if you specify a domain nameof ".capricorn.com", then Netscape will return the cookie toWeb servers running on any of the machines "www.capricorn.com", "ftp.capricorn.com", "feckless.capricorn.com", etc. Domain namesmust contain at least two periods to prevent attempts to matchon top level domains like ".edu". If no domain is specified, thenthe browser will only return the cookie to servers on the host thecookie originated from.=item B<3. path>If you provide a cookie path attribute, the browser will check itagainst your script's URL before returning the cookie. For example,if you specify the path "/cgi-bin", then the cookie will be returnedto each of the scripts "/cgi-bin/tally.pl", "/cgi-bin/order.pl", and"/cgi-bin/customer_service/complain.pl", but not to the script"/cgi-private/site_admin.pl". By default, the path is set to "/", sothat all scripts at your site will receive the cookie.=item B<4. secure flag>If the "secure" attribute is set, the cookie will only be sent to yourscript if the CGI request is occurring on a secure channel, such as SSL.=back=head2 Creating New Cookies $c = new CGI::Cookie(-name => 'foo', -value => 'bar', -expires => '+3M', -domain => '.capricorn.com', -path => '/cgi-bin/database' -secure => 1 );Create cookies from scratch with the B<new> method. The B<-name> andB<-value> parameters are required. The name must be a scalar value.The value can be a scalar, an array reference, or a hash reference.(At some point in the future cookies will support one of the Perlobject serialization protocols for full generality).B<-expires> accepts any of the relative or absolute date formatsrecognized by CGI.pm, for example "+3M" for three months in thefuture. See CGI.pm's documentation for details.B<-domain> points to a domain name or to a fully qualified host name.If not specified, the cookie will be returned only to the Web serverthat created it.B<-path> points to a partial URL on the current server. The cookiewill be returned to all URLs beginning with the specified path. Ifnot specified, it defaults to '/', which returns the cookie to allpages at your site.B<-secure> if set to a true value instructs the browser to return thecookie only when a cryptographic protocol is in use.=head2 Sending the Cookie to the BrowserWithin a CGI script you can send a cookie to the browser by creatingone or more Set-Cookie: fields in the HTTP header. Here is a typicalsequence: my $c = new CGI::Cookie(-name => 'foo', -value => ['bar','baz'], -expires => '+3M'); print "Set-Cookie: $c\n"; print "Content-Type: text/html\n\n";To send more than one cookie, create several Set-Cookie: fields.Alternatively, you may concatenate the cookies together with "; " andsend them in one field.If you are using CGI.pm, you send cookies by providing a -cookieargument to the header() method: print header(-cookie=>$c);Mod_perl users can set cookies using the request object's header_out()method: $r->header_out('Set-Cookie',$c);Internally, Cookie overloads the "" operator to call its as_string()method when incorporated into the HTTP header. as_string() turns theCookie's internal representation into an RFC-compliant textrepresentation. You may call as_string() yourself if you prefer: print "Set-Cookie: ",$c->as_string,"\n";=head2 Recovering Previous Cookies %cookies = fetch CGI::Cookie;B<fetch> returns an associative array consisting of all cookiesreturned by the browser. The keys of the array are the cookie names. Youcan iterate through the cookies this way: %cookies = fetch CGI::Cookie; foreach (keys %cookies) { do_something($cookies{$_}); }In a scalar context, fetch() returns a hash reference, which may be moreefficient if you are manipulating multiple cookies.CGI.pm uses the URL escaping methods to save and restore reserved charactersin its cookies. If you are trying to retrieve a cookie set by a foreign server,this escaping method may trip you up. Use raw_fetch() instead, which has thesame semantics as fetch(), but performs no unescaping.You may also retrieve cookies that were stored in some externalform using the parse() class method: $COOKIES = `cat /usr/tmp/Cookie_stash`; %cookies = parse CGI::Cookie($COOKIES);=head2 Manipulating CookiesCookie objects have a series of accessor methods to get and set cookieattributes. Each accessor has a similar syntax. Called withoutarguments, the accessor returns the current value of the attribute.Called with an argument, the accessor changes the attribute andreturns its new value.=over 4=item B<name()>Get or set the cookie's name. Example: $name = $c->name; $new_name = $c->name('fred');=item B<value()>Get or set the cookie's value. Example: $value = $c->value; @new_value = $c->value(['a','b','c','d']);B<value()> is context sensitive. In a list context it will returnthe current value of the cookie as an array. In a scalar context itwill return the B<first> value of a multivalued cookie.=item B<domain()>Get or set the cookie's domain.=item B<path()>Get or set the cookie's path.=item B<expires()>Get or set the cookie's expiration time.=back=head1 AUTHOR INFORMATIONCopyright 1997-1998, Lincoln D. Stein. All rights reserved. This library is free software; you can redistribute it and/or modifyit under the same terms as Perl itself.Address bug reports and comments to: lstein@cshl.org=head1 BUGSThis section intentionally left blank.=head1 SEE ALSOL<CGI::Carp>, L<CGI>=cut
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -