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