my($self) = @_;
$self->scan(sub {
if($_[9] or # "Discard" flag set
not $_[8]) { # No expire field?
$_[8] = -1; # Set the expire/max_age field
$self->set_cookie(@_); # Clear the cookie
}
});
}
sub DESTROY
{
my $self = shift;
$self->save if $self->{'autosave'};
}
sub scan
{
my($self, $cb) = @_;
my($domain,$path,$key);
for $domain (sort keys %{$self->{COOKIES}}) {
for $path (sort keys %{$self->{COOKIES}{$domain}}) {
for $key (sort keys %{$self->{COOKIES}{$domain}{$path}}) {
my($version,$val,$port,$path_spec,
$secure,$expires,$discard,$rest) =
@{$self->{COOKIES}{$domain}{$path}{$key}};
$rest = {} unless defined($rest);
&$cb($version,$key,$val,$path,$domain,$port,
$path_spec,$secure,$expires,$discard,$rest);
}
}
}
}
sub as_string
{
my($self, $skip_discard) = @_;
my @res;
$self->scan(sub {
my($version,$key,$val,$path,$domain,$port,
$path_spec,$secure,$expires,$discard,$rest) = @_;
return if $discard && $skip_discard;
my @h = ($key, $val);
push(@h, "path", $path);
push(@h, "domain" => $domain);
push(@h, "port" => $port) if defined $port;
push(@h, "path_spec" => undef) if $path_spec;
push(@h, "secure" => undef) if $secure;
push(@h, "expires" => HTTP::Date::time2isoz($expires)) if $expires;
push(@h, "discard" => undef) if $discard;
my $k;
for $k (sort keys %$rest) {
push(@h, $k, $rest->{$k});
}
push(@h, "version" => $version);
push(@res, "Set-Cookie3: " . join_header_words(\@h));
});
join("\n", @res, "");
}
sub _host
{
my($request, $url) = @_;
if (my $h = $request->header("Host")) {
$h =~ s/:\d+$//; # might have a port as well
return lc($h);
}
return lc($url->host);
}
sub _url_path
{
my $url = shift;
my $path;
if($url->can('epath')) {
$path = $url->epath; # URI::URL method
}
else {
$path = $url->path; # URI::_generic method
}
$path = "/" unless length $path;
$path;
}
sub _normalize_path # so that plain string compare can be used
{
my $x;
$_[0] =~ s/%([0-9a-fA-F][0-9a-fA-F])/
$x = uc($1);
$x eq "2F" || $x eq "25" ? "%$x" :
pack("C", hex($x));
/eg;
$_[0] =~ s/([\0-\x20\x7f-\xff])/sprintf("%%%02X",ord($1))/eg;
}
1;
=6= |