File Coverage

blib/lib/HTTP/Cookies/Safari.pm
Criterion Covered Total %
statement 72 73 98.6
branch 7 14 50.0
condition 7 18 38.8
subroutine 12 12 100.0
pod 2 2 100.0
total 100 119 84.0


line stmt bran cond sub pod time code
1             package HTTP::Cookies::Safari;
2 4     4   46181 use strict;
  4         5  
  4         87  
3              
4 4     4   12 use warnings;
  4         3  
  4         68  
5 4     4   16 no warnings;
  4         3  
  4         131  
6              
7             =encoding utf8
8              
9             =head1 NAME
10              
11             HTTP::Cookies::Safari - Cookie storage and management for Safari
12              
13             =head1 SYNOPSIS
14              
15             use HTTP::Cookies::Safari;
16              
17             my $cookie_jar = HTTP::Cookies::Safari->new;
18             $cookie_jar->load( '/Users/Buster/Library/Cookies/Cookies.plist' );
19              
20             # otherwise same as HTTP::Cookies
21              
22             =head1 DESCRIPTION
23              
24             This package overrides the C and C methods of
25             C so it can work with Safari cookie files.
26              
27             Note: If the source Safari cookie file specifies and expiry date past
28             the unix 32-bit epoch, this file changes the expiry date to 0xFFFFFFFF
29             in unix seconds. That should be enough for anyone, at least to the
30             next release.
31              
32             See L.
33              
34             =head1 SOURCE AVAILABILITY
35              
36             This module is in Github:
37              
38             http://github.com/briandfoy/HTTP-Cookies-Safari
39              
40             =head1 AUTHOR
41              
42             brian d foy, C<< >>
43              
44             =head1 CREDITS
45              
46             Jon Orwant pointed out the problem with dates too far in the future
47              
48             =head1 COPYRIGHT AND LICENSE
49              
50             Copyright © 2003-2015, brian d foy . All rights reserved.
51              
52             This program is free software; you can redistribute it and/or modify
53             it under the same terms as Perl itself.
54              
55             =cut
56              
57             #
58             #
59             # Domain
60             # usatoday.com
61             # Expires
62             # 2020-02-19T14:28:00Z
63             # Name
64             # v1st
65             # Path
66             # /
67             # Value
68             # 3E1B9B935912A908
69             #
70              
71 4     4   10 use base qw( HTTP::Cookies );
  4         3  
  4         1765  
72 4     4   31189 use vars qw( $VERSION );
  4         4  
  4         138  
73              
74 4     4   13 use constant TRUE => 'TRUE';
  4         4  
  4         175  
75 4     4   13 use constant FALSE => 'FALSE';
  4         4  
  4         163  
76              
77             $VERSION = '1.152';
78              
79 4     4   1443 use Date::Calc;
  4         23062  
  4         693  
80 4     4   2219 use Mac::PropertyList;
  4         89703  
  4         1941  
81              
82             sub load
83             {
84 3     3 1 100 my( $self, $file ) = @_;
85              
86 3   50     21 $file ||= $self->{'file'} || return;
      33        
87              
88 3         3 local $_;
89 3         9 local $/ = "\n"; # make sure we got standard record separator
90              
91 3 50       98 open my( $fh ), $file or return;
92              
93 3         5 my $data = do { local $/; <$fh> };
  3         8  
  3         58  
94              
95 3         14 my $plist = Mac::PropertyList::parse_plist( $data );
96              
97 3         31179 my $cookies = $plist->value;
98              
99 3         53 foreach my $hash ( @$cookies )
100             {
101 9         118 my $cookie = $hash->value;
102              
103 9         113 my @bits = map { $cookie->{$_}->value }
  45         297  
104             qw( Domain Path Name Value Expires );
105             # 0 1 2 3 4
106              
107 9         75 my $expires = $bits[4];
108              
109 9         37 my( $y, $m, $d, $h, $mn, $s ) = $expires =~
110             m/(\d\d\d\d)-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)Z/g;
111              
112 9   100     13 $expires = eval {
113             &Date::Calc::Mktime( $y, $m, $d, $h, $mn, $s ) } || 0xFFFFFFFF;
114              
115             # XXX: Convert Expires date to unix epoch
116              
117             #print STDERR "@bits\n";
118              
119 9         9 my $secure = FALSE;
120              
121 9         49 $self->set_cookie(undef, @bits[2,3,1,0], undef,
122             0, 0, $expires - time, 0);
123             }
124              
125 3         128 close $fh;
126              
127 3         67 1;
128             }
129              
130             sub save
131             {
132 1     1 1 342 my( $self, $file ) = @_;
133              
134 1   0     3 $file ||= $self->{'file'} || return;
      33        
135              
136 1         16 my $plist = Mac::PropertyList::array->new( [] );
137 1         14 print STDERR "plist is $plist\n";
138              
139              
140             $self->scan(
141 1         2 do {
142              
143 1         3 my $array = $plist->value;
144 1         11 my $n = 1;
145              
146             sub {
147 4     4   75 my( $version, $key, $val, $path, $domain, $port,
148             $path_spec, $secure, $expires, $discard, $rest ) = @_;
149              
150 4 50 33     9 return if $discard && not $self->{ignore_discard};
151              
152 4 50 33     15 return if defined $expires && time > $expires;
153              
154 4         2 $expires = do {
155 4 50       7 unless( $expires ) { 0 }
  0         0  
156             else
157             {
158 4         47 my @times = localtime( $expires );
159 4         6 $times[5] += 1900;
160 4         3 $times[4] += 1;
161              
162 4         17 sprintf "%4d-%02d-%02dT%02d:%02d:%02dZ",
163             @times[5,4,3,2,1,0];
164             }
165             };
166              
167 4 50       8 $secure = $secure ? TRUE : FALSE;
168              
169 4 50       12 my $bool = $domain =~ /^\./ ? TRUE : FALSE;
170              
171 4         11 my $hash = {
172             Value => Mac::PropertyList::string->new( $val ),
173             Path => Mac::PropertyList::string->new( $path ),
174             Domain => Mac::PropertyList::string->new( $domain ),
175             Name => Mac::PropertyList::string->new( $key ),
176             Expires => Mac::PropertyList::date ->new( $expires ),
177             };
178              
179 4         77 push @$array, Mac::PropertyList::dict->new( $hash );
180             }
181 1         47 } );
182              
183 1 50       115 open my $fh, "> $file" or die "Could not write file [$file]! $!\n";
184 1         4 print $fh ( Mac::PropertyList::plist_as_string( $plist ) );
185 1         685 close $fh;
186             }
187              
188             1;