line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Cookie::Baker; |
2
|
|
|
|
|
|
|
|
3
|
3
|
|
|
3
|
|
110189
|
use 5.008001; |
|
3
|
|
|
|
|
24
|
|
4
|
3
|
|
|
3
|
|
13
|
use strict; |
|
3
|
|
|
|
|
5
|
|
|
3
|
|
|
|
|
47
|
|
5
|
3
|
|
|
3
|
|
12
|
use warnings; |
|
3
|
|
|
|
|
3
|
|
|
3
|
|
|
|
|
74
|
|
6
|
3
|
|
|
3
|
|
13
|
use base qw/Exporter/; |
|
3
|
|
|
|
|
4
|
|
|
3
|
|
|
|
|
206
|
|
7
|
3
|
|
|
3
|
|
1068
|
use URI::Escape; |
|
3
|
|
|
|
|
3644
|
|
|
3
|
|
|
|
|
511
|
|
8
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
BEGIN { |
10
|
3
|
|
|
3
|
|
10
|
our $VERSION = "0.11"; |
11
|
3
|
|
|
|
|
8
|
our @EXPORT = qw/bake_cookie crush_cookie/; |
12
|
3
|
|
|
|
|
5
|
my $use_pp = $ENV{COOKIE_BAKER_PP}; |
13
|
3
|
50
|
|
|
|
10
|
if (!$use_pp) { |
14
|
3
|
|
|
|
|
6
|
eval { |
15
|
3
|
|
|
|
|
348
|
require Cookie::Baker::XS; |
16
|
0
|
0
|
|
|
|
0
|
if ( $Cookie::Baker::XS::VERSION < $VERSION ) { |
17
|
0
|
|
|
|
|
0
|
warn "Cookie::Baker::XS $VERSION is require. fallback to PP version"; |
18
|
0
|
|
|
|
|
0
|
die; |
19
|
|
|
|
|
|
|
} |
20
|
|
|
|
|
|
|
}; |
21
|
3
|
|
|
|
|
13
|
$use_pp = !!$@; |
22
|
|
|
|
|
|
|
} |
23
|
3
|
50
|
|
|
|
8
|
if ($use_pp) { |
24
|
3
|
|
|
|
|
1154
|
*crush_cookie = \&pp_crush_cookie; |
25
|
|
|
|
|
|
|
} |
26
|
|
|
|
|
|
|
else { |
27
|
0
|
|
|
|
|
0
|
*crush_cookie = \&Cookie::Baker::XS::crush_cookie; |
28
|
|
|
|
|
|
|
} |
29
|
|
|
|
|
|
|
} |
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
sub bake_cookie { |
32
|
26
|
|
|
26
|
1
|
10696
|
my ($name,$val) = @_; |
33
|
|
|
|
|
|
|
|
34
|
26
|
50
|
|
|
|
56
|
return '' unless defined $val; |
35
|
26
|
100
|
|
|
|
50
|
my %args = ref $val ? %{$val} : (value => $val); |
|
25
|
|
|
|
|
82
|
|
36
|
26
|
50
|
|
|
|
81
|
$name = URI::Escape::uri_escape($name) if $name =~ m![^a-zA-Z\-\._~]!; |
37
|
26
|
|
|
|
|
77
|
my $cookie = "$name=" . URI::Escape::uri_escape($args{value}) . '; '; |
38
|
26
|
50
|
|
|
|
300
|
$cookie .= 'domain=' . $args{domain} . '; ' if $args{domain}; |
39
|
26
|
100
|
|
|
|
67
|
$cookie .= 'path='. $args{path} . '; ' if $args{path}; |
40
|
26
|
100
|
100
|
|
|
81
|
$cookie .= 'expires=' . _date($args{expires}) . '; ' if exists $args{expires} && defined $args{expires}; |
41
|
26
|
100
|
|
|
|
47
|
$cookie .= 'max-age=' . $args{"max-age"} . '; ' if exists $args{"max-age"}; |
42
|
26
|
100
|
100
|
|
|
56
|
if (exists $args{samesite} && $args{samesite} =~ m/^(?:lax|strict|none)/i) { |
43
|
3
|
|
|
|
|
9
|
$cookie .= 'SameSite=' . ucfirst(lc($args{samesite})) . '; ' |
44
|
|
|
|
|
|
|
} |
45
|
26
|
100
|
|
|
|
38
|
$cookie .= 'secure; ' if $args{secure}; |
46
|
26
|
100
|
|
|
|
36
|
$cookie .= 'HttpOnly; ' if $args{httponly}; |
47
|
26
|
|
|
|
|
42
|
substr($cookie,-2,2,''); |
48
|
26
|
|
|
|
|
75
|
$cookie; |
49
|
|
|
|
|
|
|
} |
50
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
my @MON = qw( Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec ); |
52
|
|
|
|
|
|
|
my @WDAY = qw( Sun Mon Tue Wed Thu Fri Sat ); |
53
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
my %term = ( |
55
|
|
|
|
|
|
|
's' => 1, |
56
|
|
|
|
|
|
|
'm' => 60, |
57
|
|
|
|
|
|
|
'h' => 3600, |
58
|
|
|
|
|
|
|
'd' => 86400, |
59
|
|
|
|
|
|
|
'M' => 86400 * 30, |
60
|
|
|
|
|
|
|
'y' => 86400 * 365, |
61
|
|
|
|
|
|
|
); |
62
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
sub _date { |
64
|
13
|
|
|
13
|
|
18
|
my $expires = shift; |
65
|
|
|
|
|
|
|
|
66
|
13
|
|
|
|
|
24
|
my $expires_at; |
67
|
13
|
100
|
|
|
|
70
|
if ($expires =~ /^\d+$/) { |
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
68
|
|
|
|
|
|
|
# all numbers -> epoch date |
69
|
2
|
|
|
|
|
3
|
$expires_at = $expires; |
70
|
|
|
|
|
|
|
} |
71
|
|
|
|
|
|
|
elsif ( $expires =~ /^([-+]?(?:\d+|\d*\.\d*))([smhdMy]?)/ ) { |
72
|
3
|
|
|
3
|
|
21
|
no warnings; |
|
3
|
|
|
|
|
4
|
|
|
3
|
|
|
|
|
963
|
|
73
|
9
|
|
100
|
|
|
41
|
my $offset = ($term{$2} || 1) * $1; |
74
|
9
|
|
|
|
|
20
|
$expires_at = time + $offset; |
75
|
|
|
|
|
|
|
} |
76
|
|
|
|
|
|
|
elsif ( $expires eq 'now' ) { |
77
|
1
|
|
|
|
|
3
|
$expires_at = time; |
78
|
|
|
|
|
|
|
} |
79
|
|
|
|
|
|
|
else { |
80
|
1
|
|
|
|
|
3
|
return $expires; |
81
|
|
|
|
|
|
|
} |
82
|
12
|
|
|
|
|
104
|
my($sec, $min, $hour, $mday, $mon, $year, $wday) = gmtime($expires_at); |
83
|
12
|
|
|
|
|
22
|
$year += 1900; |
84
|
|
|
|
|
|
|
# (cookies use '-' as date separator, HTTP uses ' ') |
85
|
12
|
|
|
|
|
69
|
return sprintf("%s, %02d-%s-%04d %02d:%02d:%02d GMT", |
86
|
|
|
|
|
|
|
$WDAY[$wday], $mday, $MON[$mon], $year, $hour, $min, $sec); |
87
|
|
|
|
|
|
|
} |
88
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
sub pp_crush_cookie { |
90
|
44
|
|
|
44
|
0
|
8865
|
my $cookie_string = shift; |
91
|
44
|
100
|
|
|
|
87
|
return {} unless $cookie_string; |
92
|
40
|
|
|
|
|
48
|
my %results; |
93
|
40
|
|
|
|
|
303
|
my @pairs = grep m/=/, split /; ?/, $cookie_string; |
94
|
40
|
|
|
|
|
75
|
for my $pair ( @pairs ) { |
95
|
|
|
|
|
|
|
# trim leading trailing whitespace |
96
|
114
|
|
|
|
|
217
|
$pair =~ s/^\s+//; $pair =~ s/\s+$//; |
|
114
|
|
|
|
|
225
|
|
97
|
|
|
|
|
|
|
|
98
|
114
|
|
|
|
|
259
|
my ($key, $value) = split( "=", $pair, 2 ); |
99
|
|
|
|
|
|
|
|
100
|
114
|
|
|
|
|
204
|
$key = URI::Escape::uri_unescape($key); |
101
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
# Values can be quoted |
103
|
114
|
50
|
|
|
|
692
|
$value = "" unless defined $value; |
104
|
114
|
|
|
|
|
144
|
$value =~ s/\A"(.*)"\z/$1/; |
105
|
114
|
|
|
|
|
157
|
$value = URI::Escape::uri_unescape($value); |
106
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
# Take the first one like CGI.pm or rack do |
108
|
114
|
100
|
|
|
|
885
|
$results{$key} = $value unless exists $results{$key}; |
109
|
|
|
|
|
|
|
} |
110
|
40
|
|
|
|
|
112
|
return \%results; |
111
|
|
|
|
|
|
|
} |
112
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
1; |
114
|
|
|
|
|
|
|
__END__ |