| Filename | /usr/share/perl5/CGI/Cookie.pm | 
| Statements | Executed 1069 statements in 3.68ms | 
| Calls | P | F | Exclusive Time | Inclusive Time | Subroutine | 
|---|---|---|---|---|---|
| 4 | 1 | 1 | 308µs | 1.16ms | CGI::Cookie::parse | 
| 17 | 2 | 2 | 302µs | 815µs | CGI::Cookie::new | 
| 8 | 5 | 4 | 291µs | 473µs | CGI::Cookie::as_string | 
| 1 | 1 | 1 | 86µs | 113µs | CGI::Cookie::BEGIN@6 | 
| 29 | 3 | 2 | 82µs | 82µs | CGI::Cookie::value | 
| 33 | 3 | 1 | 82µs | 82µs | CGI::Cookie::name | 
| 33 | 2 | 1 | 42µs | 42µs | CGI::Cookie::path | 
| 4 | 1 | 1 | 34µs | 1.21ms | CGI::Cookie::fetch | 
| 32 | 2 | 1 | 22µs | 22µs | CGI::Cookie::CORE:subst (opcode) | 
| 1 | 1 | 1 | 19µs | 31µs | CGI::Cookie::BEGIN@3 | 
| 4 | 1 | 1 | 17µs | 17µs | CGI::Cookie::get_raw_cookie | 
| 1 | 1 | 1 | 16µs | 49µs | CGI::Cookie::BEGIN@11 | 
| 8 | 1 | 1 | 16µs | 16µs | CGI::Cookie::domain | 
| 9 | 2 | 1 | 15µs | 15µs | CGI::Cookie::httponly | 
| 1 | 1 | 1 | 14µs | 29µs | CGI::Cookie::BEGIN@138 | 
| 8 | 1 | 1 | 13µs | 13µs | CGI::Cookie::expires | 
| 1 | 1 | 1 | 12µs | 45µs | CGI::Cookie::BEGIN@10 | 
| 8 | 1 | 1 | 12µs | 12µs | CGI::Cookie::max_age | 
| 1 | 1 | 1 | 11µs | 20µs | CGI::Cookie::BEGIN@4 | 
| 8 | 1 | 1 | 10µs | 10µs | CGI::Cookie::secure | 
| 1 | 1 | 1 | 1µs | 1µs | CGI::Cookie::CORE:match (opcode) | 
| 0 | 0 | 0 | 0s | 0s | CGI::Cookie::bake | 
| 0 | 0 | 0 | 0s | 0s | CGI::Cookie::compare | 
| 0 | 0 | 0 | 0s | 0s | CGI::Cookie::raw_fetch | 
| Line | State ments | Time on line | Calls | Time in subs | Code | 
|---|---|---|---|---|---|
| 1 | package CGI::Cookie; | ||||
| 2 | |||||
| 3 | 2 | 47µs | 2 | 43µs | # spent 31µs (19+12) within CGI::Cookie::BEGIN@3 which was called:
#    once (19µs+12µs) by C4::Languages::getlanguage at line 3 # spent    31µs making 1 call to CGI::Cookie::BEGIN@3
# spent    12µs making 1 call to strict::import | 
| 4 | 2 | 48µs | 2 | 30µs | # spent 20µs (11+10) within CGI::Cookie::BEGIN@4 which was called:
#    once (11µs+10µs) by C4::Languages::getlanguage at line 4 # spent    20µs making 1 call to CGI::Cookie::BEGIN@4
# spent    10µs making 1 call to warnings::import | 
| 5 | |||||
| 6 | 2 | 156µs | 2 | 122µs | # spent 113µs (86+28) within CGI::Cookie::BEGIN@6 which was called:
#    once (86µs+28µs) by C4::Languages::getlanguage at line 6 # spent   113µs making 1 call to CGI::Cookie::BEGIN@6
# spent     9µs making 1 call to if::import | 
| 7 | |||||
| 8 | 1 | 400ns | our $VERSION='4.09'; | ||
| 9 | |||||
| 10 | 2 | 82µs | 2 | 79µs | # spent 45µs (12+33) within CGI::Cookie::BEGIN@10 which was called:
#    once (12µs+33µs) by C4::Languages::getlanguage at line 10 # spent    45µs making 1 call to CGI::Cookie::BEGIN@10
# spent    33µs making 1 call to Exporter::import | 
| 11 | 2 | 748µs | 2 | 82µs | # spent 49µs (16+33) within CGI::Cookie::BEGIN@11 which was called:
#    once (16µs+33µs) by C4::Languages::getlanguage at line 11 # spent    49µs making 1 call to CGI::Cookie::BEGIN@11
# spent    33µs making 1 call to overload::import | 
| 12 | |||||
| 13 | 1 | 300ns | my $PERLEX = 0; | ||
| 14 | # Turn on special checking for ActiveState's PerlEx | ||||
| 15 | 1 | 11µs | 1 | 1µs | $PERLEX++ if defined($ENV{'GATEWAY_INTERFACE'}) && $ENV{'GATEWAY_INTERFACE'} =~ /^CGI-PerlEx/; # spent     1µs making 1 call to CGI::Cookie::CORE:match | 
| 16 | |||||
| 17 | # Turn on special checking for mod_perl | ||||
| 18 | # PerlEx::DBI tries to fool DBI by setting MOD_PERL | ||||
| 19 | 1 | 200ns | 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 1.21ms (34µs+1.17) within CGI::Cookie::fetch which was called 4 times, avg 302µs/call:
# 4 times (34µs+1.17ms) by C4::Languages::getlanguage or CGI::cookie at line 12 of (eval 1118)[CGI.pm:932], avg 302µs/call | ||||
| 35 | 4 | 2µs | my $class = shift; | ||
| 36 | 4 | 8µs | 4 | 17µs | my $raw_cookie = get_raw_cookie(@_) or return;     # spent    17µs making 4 calls to CGI::Cookie::get_raw_cookie, avg 4µs/call | 
| 37 | 4 | 17µs | 4 | 1.16ms | return $class->parse($raw_cookie);     # spent  1.16ms making 4 calls to CGI::Cookie::parse, avg 289µs/call | 
| 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 17µs within CGI::Cookie::get_raw_cookie which was called 4 times, avg 4µs/call:
# 4 times (17µs+0s) by CGI::Cookie::fetch at line 36, avg 4µs/call | ||||
| 60 | 4 | 2µs | my $r = shift; | ||
| 61 | 4 | 900ns | $r ||= eval { $MOD_PERL == 2 ? | ||
| 62 | Apache2::RequestUtil->request() : | ||||
| 63 | Apache->request } if $MOD_PERL; | ||||
| 64 | |||||
| 65 | 4 | 1µs | return $r->headers_in->{'Cookie'} if $r; | ||
| 66 | |||||
| 67 | 4 | 900ns | die "Run $r->subprocess_env; before calling fetch()" | ||
| 68 | if $MOD_PERL and !exists $ENV{REQUEST_METHOD}; | ||||
| 69 | |||||
| 70 | 4 | 18µs | return $ENV{HTTP_COOKIE} || $ENV{COOKIE}; | ||
| 71 | } | ||||
| 72 | |||||
| 73 | |||||
| 74 | # spent 1.16ms (308µs+849µs) within CGI::Cookie::parse which was called 4 times, avg 289µs/call:
# 4 times (308µs+849µs) by CGI::Cookie::fetch at line 37, avg 289µs/call | ||||
| 75 | 4 | 3µs | my ($self,$raw_cookie) = @_; | ||
| 76 | 4 | 1µs | return wantarray ? () : {} unless $raw_cookie; | ||
| 77 | |||||
| 78 | 4 | 700ns | my %results; | ||
| 79 | |||||
| 80 | 4 | 23µs | my @pairs = split("[;,] ?",$raw_cookie); | ||
| 81 | 4 | 4µs | for (@pairs) { | ||
| 82 | 16 | 43µs | 16 | 13µs | s/^\s+//;     # spent    13µs making 16 calls to CGI::Cookie::CORE:subst, avg 838ns/call | 
| 83 | 16 | 27µs | 16 | 9µs | s/\s+$//;     # spent     9µs making 16 calls to CGI::Cookie::CORE:subst, avg 556ns/call | 
| 84 | |||||
| 85 | 16 | 20µs | my($key,$value) = split("=",$_,2); | ||
| 86 | |||||
| 87 | # Some foreign cookies are not in name=value format, so ignore | ||||
| 88 | # them. | ||||
| 89 | 16 | 3µs | next if !defined($value); | ||
| 90 | 16 | 5µs | my @values = (); | ||
| 91 | 16 | 7µs | if ($value ne '') { | ||
| 92 | 16 | 175µs | 32 | 81µs | @values = map unescape($_),split(/[&;]/,$value.'&dmy');       # spent    81µs making 32 calls to CGI::Util::unescape, avg 3µs/call | 
| 93 | 16 | 4µs | pop @values; | ||
| 94 | } | ||||
| 95 | 16 | 56µs | 16 | 28µs | $key = unescape($key);     # spent    28µs making 16 calls to CGI::Util::unescape, avg 2µs/call | 
| 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 | 16 | 55µs | 16 | 718µs | $results{$key} ||= $self->new(-name=>$key,-value=>\@values);     # spent   718µs making 16 calls to CGI::Cookie::new, avg 45µs/call | 
| 99 | } | ||||
| 100 | 4 | 12µs | return wantarray ? %results : \%results; | ||
| 101 | } | ||||
| 102 | |||||
| 103 | # spent 815µs (302+513) within CGI::Cookie::new which was called 17 times, avg 48µs/call:
# 16 times (239µs+478µs) by CGI::Cookie::parse at line 98, avg 45µs/call
#     once (62µs+35µs) by CGI::cookie at line 33 of (eval 1118)[CGI.pm:932] | ||||
| 104 | 17 | 14µs | my ( $class, @params ) = @_; | ||
| 105 | 17 | 4µs | $class = ref( $class ) || $class; | ||
| 106 | # Ignore mod_perl request object--compatibility with Apache::Cookie. | ||||
| 107 | shift if ref $params[0] | ||||
| 108 | 17 | 3µs | && eval { $params[0]->isa('Apache::Request::Req') || $params[0]->isa('Apache') }; | ||
| 109 | 17 | 445µs | 17 | 367µs | my ( $name, $value, $path, $domain, $secure, $expires, $max_age, $httponly )   # spent   367µs making 17 calls to CGI::Util::rearrange, avg 22µs/call | 
| 110 | = rearrange( | ||||
| 111 | [ | ||||
| 112 | 'NAME', [ 'VALUE', 'VALUES' ], | ||||
| 113 | 'PATH', 'DOMAIN', | ||||
| 114 | 'SECURE', 'EXPIRES', | ||||
| 115 | 'MAX-AGE','HTTPONLY' | ||||
| 116 | ], | ||||
| 117 | @params | ||||
| 118 | ); | ||||
| 119 | 17 | 5µs | return undef unless defined $name and defined $value; | ||
| 120 | 17 | 7µs | my $self = {}; | ||
| 121 | 17 | 36µs | bless $self, $class; | ||
| 122 | 17 | 23µs | 17 | 59µs | $self->name( $name );   # spent    59µs making 17 calls to CGI::Cookie::name, avg 3µs/call | 
| 123 | 17 | 17µs | 17 | 60µs | $self->value( $value );   # spent    60µs making 17 calls to CGI::Cookie::value, avg 4µs/call | 
| 124 | 17 | 5µs | $path ||= "/"; | ||
| 125 | 17 | 19µs | 17 | 25µs | $self->path( $path )         if defined $path;   # spent    25µs making 17 calls to CGI::Cookie::path, avg 1µs/call | 
| 126 | 17 | 3µs | $self->domain( $domain ) if defined $domain; | ||
| 127 | 17 | 2µs | $self->secure( $secure ) if defined $secure; | ||
| 128 | 17 | 2µs | $self->expires( $expires ) if defined $expires; | ||
| 129 | 17 | 2µs | $self->max_age( $max_age ) if defined $max_age; | ||
| 130 | 17 | 3µs | 1 | 3µs | $self->httponly( $httponly ) if defined $httponly;   # spent     3µs making 1 call to CGI::Cookie::httponly | 
| 131 | 17 | 33µs | return $self; | ||
| 132 | } | ||||
| 133 | |||||
| 134 | # spent 473µs (291+182) within CGI::Cookie::as_string which was called 8 times, avg 59µs/call:
# 4 times (140µs+84µs) by C4::Languages::getlanguage or CGI::cookie at line 17 of (eval 1118)[CGI.pm:932], avg 56µs/call
#    once (52µs+33µs) by C4::Output::output_with_http_headers at line 275 of C4/Output.pm
#    once (44µs+32µs) by C4::Auth::checkauth at line 1172 of C4/Auth.pm
#    once (28µs+17µs) by C4::Output::output_with_http_headers at line 75 of (eval 1141)[CGI.pm:932]
#    once (26µs+15µs) by C4::Output::output_with_http_headers at line 17 of (eval 1141)[CGI.pm:932] | ||||
| 135 | 8 | 3µs | my $self = shift; | ||
| 136 | 8 | 11µs | 8 | 15µs | return "" unless $self->name;     # spent    15µs making 8 calls to CGI::Cookie::name, avg 2µs/call | 
| 137 | |||||
| 138 | 2 | 776µs | 2 | 45µs | # spent 29µs (14+16) within CGI::Cookie::BEGIN@138 which was called:
#    once (14µs+16µs) by C4::Languages::getlanguage at line 138     # spent    29µs making 1 call to CGI::Cookie::BEGIN@138
    # spent    16µs making 1 call to warnings::unimport | 
| 139 | |||||
| 140 | 8 | 87µs | 16 | 55µs | my $name  = escape( $self->name );     # spent    47µs making 8 calls to CGI::Util::escape, avg 6µs/call
    # spent     8µs making 8 calls to CGI::Cookie::name, avg 963ns/call | 
| 141 | 16 | 60µs | 16 | 31µs | my $value = join "&", map { escape($_) } $self->value;     # spent    16µs making 8 calls to CGI::Cookie::value, avg 2µs/call
    # spent    15µs making 8 calls to CGI::Util::escape, avg 2µs/call | 
| 142 | 8 | 11µs | my @cookie = ( "$name=$value" ); | ||
| 143 | |||||
| 144 | 8 | 12µs | 8 | 16µs | push @cookie,"domain=".$self->domain   if $self->domain;     # spent    16µs making 8 calls to CGI::Cookie::domain, avg 2µs/call | 
| 145 | 8 | 21µs | 16 | 18µs | push @cookie,"path=".$self->path       if $self->path;     # spent    18µs making 16 calls to CGI::Cookie::path, avg 1µs/call | 
| 146 | 8 | 11µs | 8 | 13µs | push @cookie,"expires=".$self->expires if $self->expires;     # spent    13µs making 8 calls to CGI::Cookie::expires, avg 2µs/call | 
| 147 | 8 | 10µs | 8 | 12µs | push @cookie,"max-age=".$self->max_age if $self->max_age;     # spent    12µs making 8 calls to CGI::Cookie::max_age, avg 1µs/call | 
| 148 | 8 | 10µs | 8 | 10µs | push @cookie,"secure"                  if $self->secure;     # spent    10µs making 8 calls to CGI::Cookie::secure, avg 1µs/call | 
| 149 | 8 | 11µs | 8 | 12µs | push @cookie,"HttpOnly"                if $self->httponly;     # spent    12µs making 8 calls to CGI::Cookie::httponly, avg 2µs/call | 
| 150 | |||||
| 151 | 8 | 32µ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 | 33 | 9µs | my ( $self, $name ) = @_; | ||
| 179 | 33 | 37µs | $self->{'name'} = $name if defined $name; | ||
| 180 | 33 | 66µs | return $self->{'name'}; | ||
| 181 | } | ||||
| 182 | |||||
| 183 | # spent 82µs within CGI::Cookie::value which was called 29 times, avg 3µs/call:
# 17 times (60µs+0s) by CGI::Cookie::new at line 123, avg 4µs/call
#  8 times (16µs+0s) by CGI::Cookie::as_string at line 141, avg 2µs/call
#  4 times (6µs+0s) by C4::Languages::getlanguage or CGI::cookie at line 18 of (eval 1118)[CGI.pm:932], avg 1µs/call | ||||
| 184 | 29 | 8µs | my ( $self, $value ) = @_; | ||
| 185 | 29 | 7µs | if ( defined $value ) { | ||
| 186 | my @values | ||||
| 187 | 17 | 17µs | = ref $value eq 'ARRAY' ? @$value | ||
| 188 | : ref $value eq 'HASH' ? %$value | ||||
| 189 | : ( $value ); | ||||
| 190 | 17 | 17µs | $self->{'value'} = [@values]; | ||
| 191 | } | ||||
| 192 | 29 | 69µs | return wantarray ? @{ $self->{'value'} } : $self->{'value'}->[0]; | ||
| 193 | } | ||||
| 194 | |||||
| 195 | # spent 16µs within CGI::Cookie::domain which was called 8 times, avg 2µs/call:
# 8 times (16µs+0s) by CGI::Cookie::as_string at line 144, avg 2µs/call | ||||
| 196 | 8 | 3µs | my ( $self, $domain ) = @_; | ||
| 197 | 8 | 2µs | $self->{'domain'} = lc $domain if defined $domain; | ||
| 198 | 8 | 17µs | return $self->{'domain'}; | ||
| 199 | } | ||||
| 200 | |||||
| 201 | # spent 10µs within CGI::Cookie::secure which was called 8 times, avg 1µs/call:
# 8 times (10µs+0s) by CGI::Cookie::as_string at line 148, avg 1µs/call | ||||
| 202 | 8 | 2µs | my ( $self, $secure ) = @_; | ||
| 203 | 8 | 1µs | $self->{'secure'} = $secure if defined $secure; | ||
| 204 | 8 | 14µs | return $self->{'secure'}; | ||
| 205 | } | ||||
| 206 | |||||
| 207 | # spent 13µs within CGI::Cookie::expires which was called 8 times, avg 2µs/call:
# 8 times (13µs+0s) by CGI::Cookie::as_string at line 146, avg 2µs/call | ||||
| 208 | 8 | 2µs | my ( $self, $expires ) = @_; | ||
| 209 | 8 | 2µs | $self->{'expires'} = CGI::Util::expires($expires,'cookie') if defined $expires; | ||
| 210 | 8 | 16µs | return $self->{'expires'}; | ||
| 211 | } | ||||
| 212 | |||||
| 213 | # spent 12µs within CGI::Cookie::max_age which was called 8 times, avg 1µs/call:
# 8 times (12µs+0s) by CGI::Cookie::as_string at line 147, avg 1µs/call | ||||
| 214 | 8 | 2µs | my ( $self, $max_age ) = @_; | ||
| 215 | 8 | 2µs | $self->{'max-age'} = CGI::Util::expire_calc($max_age)-time() if defined $max_age; | ||
| 216 | 8 | 16µs | return $self->{'max-age'}; | ||
| 217 | } | ||||
| 218 | |||||
| 219 | sub path { | ||||
| 220 | 33 | 7µs | my ( $self, $path ) = @_; | ||
| 221 | 33 | 10µs | $self->{'path'} = $path if defined $path; | ||
| 222 | 33 | 55µs | return $self->{'path'}; | ||
| 223 | } | ||||
| 224 | |||||
| 225 | |||||
| 226 | sub httponly { # HttpOnly | ||||
| 227 | 9 | 3µs | my ( $self, $httponly ) = @_; | ||
| 228 | 9 | 3µs | $self->{'httponly'} = $httponly if defined $httponly; | ||
| 229 | 9 | 21µs | return $self->{'httponly'}; | ||
| 230 | } | ||||
| 231 | |||||
| 232 | 1 | 8µ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 | ||||
| # spent 1µs within CGI::Cookie::CORE:match which was called:
#    once (1µs+0s) by C4::Languages::getlanguage at line 15 | |||||
| sub CGI::Cookie::CORE:subst; # opcode |