File Coverage

blib/lib/HTTP/Cookies/iCab.pm
Criterion Covered Total %
statement 98 100 98.0
branch 25 48 52.0
condition 5 16 31.2
subroutine 16 16 100.0
pod 2 7 28.5
total 146 187 78.0


line stmt bran cond sub pod time code
1             package HTTP::Cookies::iCab;
2 3     3   45314 use strict;
  3         9  
  3         140  
3              
4 3     3   18 use warnings;
  3         6  
  3         258  
5 3     3   28 no warnings;
  3         8  
  3         182  
6              
7             =head1 NAME
8              
9             HTTP::Cookies::iCab - Cookie storage and management for iCab
10              
11             =head1 SYNOPSIS
12              
13             use HTTP::Cookies::iCab;
14              
15             my $cookie_jar = HTTP::Cookies::iCab->new( $cookies_file );
16              
17             # otherwise same as HTTP::Cookies
18              
19             =head1 DESCRIPTION
20              
21             This package overrides the load() and save() methods of HTTP::Cookies
22             so it can work with iCab 3 cookie files. This doesn't work on iCab
23             4 cookie files yet, but if you really need that, convert HTTP::Cookies::Safari
24             to do what you need.
25              
26             See L.
27              
28             =head1 SOURCE AVAILABILITY
29              
30             This source is part of a SourceForge project which always has the
31             latest sources in CVS, as well as all of the previous releases.
32              
33             http://sourceforge.net/projects/brian-d-foy/
34              
35             If, for some reason, I disappear from the world, one of the other
36             members of the project can shepherd this module appropriately.
37              
38             =head1 AUTHOR
39              
40             brian d foy, C<< >>
41              
42             =head1 COPYRIGHT AND LICENSE
43              
44             Copyright (c) 2003-2011 brian d foy. All rights reserved.
45              
46             This program is free software; you can redistribute it and/or modify
47             it under the same terms as Perl itself.
48              
49             =cut
50              
51             #/Users/brian/Library/Preferences/iCab Preferences/iCab Cookies
52             # Time::Local::timelocal(0,0,0,1,0,70)
53              
54 3     3   25 use base qw( HTTP::Cookies );
  3         6  
  3         3248  
55 3     3   48752 use vars qw( $VERSION );
  3         7  
  3         140  
56              
57 3     3   17 use constant TRUE => 'TRUE';
  3         6  
  3         322  
58 3     3   15 use constant FALSE => 'FALSE';
  3         7  
  3         147  
59 3     3   15 use constant OFFSET => 2_082_823_200;
  3         6  
  3         4971  
60              
61             $VERSION = '1.131';
62              
63             my $Debug = $ENV{DEBUG} || 0;
64              
65             sub load
66             {
67 2     2 1 1246 my( $self, $file ) = @_;
68              
69 2   50     29 $file ||= $self->{'file'} || return;
      33        
70              
71 2 50       135 open my $fh, '<:raw', $file or die "Could not open file [$file]: $!";
72              
73 2         28 my $size = -s $file;
74              
75 2         59 COOKIE: until( eof $fh )
76             {
77 10 50       24 print STDERR "\n", "-" x 73, "\n" if $Debug;
78 10         24 my $set_date = read_date( $fh );
79 10 50       24 print STDERR ( "\tset date is " . localtime( $set_date ) . "\n" )
80             if $Debug;
81 10         18 my $tag = read_str( $fh, 4 );
82 10 50       29 print STDERR ( "==> tag is [$tag] not 'Cook'\n" )
83             unless $tag eq 'Cook';
84              
85 10         19 my $name = read_var( $fh );
86 10 50       25 warn( "\tname is [$name]\n" ) if $Debug;
87 10         18 my $path = read_var( $fh );
88 10 50       25 warn( "\tpath is [$path]\n" ) if $Debug;
89 10         17 my $domain = read_var( $fh );
90 10 50       24 warn( "\tdomain is [$domain]\n" ) if $Debug;
91 10         21 my $value = read_var( $fh );
92 10 50       26 warn( "\tvalue is [$value]\n" ) if $Debug;
93              
94 10         17 my $expires = read_int( $fh ) - OFFSET;
95              
96 10 50       23 warn( "\t$name expires at " .
97             localtime( $expires ) . "\n" ) if $Debug;
98 10         20 my $str = read_str( $fh, 7 );
99              
100 10         16 DATE: {
101 10         50 my $pos = tell $fh;
102 10 50       140 warn( "read $pos of $size bytes\n" ) if $Debug > 1;
103 10 100       41 if( eof $fh )
104             {
105 2 50       7 warn( "At end of file, setting cookie [$name]\n" ) if $Debug;
106 2         20 $self->set_cookie(undef, $name, $value, $path,
107             $domain, undef, 0, 0, $expires - time, 0);
108              
109 2         47 last COOKIE;
110             }
111              
112 8         25 my $peek = peek( $fh, 12 );
113 8 50       22 warn( "\t--peek is $peek\n" ) if $Debug > 1;
114              
115 8 50       25 if( substr( $peek, 8, 4 ) eq 'Cook' )
116             {
117 8 50       19 warn( "Setting cookie [$name]\n" ) if $Debug;
118 8         56 $self->set_cookie(undef, $name, $value, $path,
119             $domain, undef, 0, 0, $expires - time, 0);
120 8         284 next COOKIE;
121             }
122              
123 0         0 my $date = read_date( $fh );
124              
125 0         0 redo;
126             }
127              
128             }
129              
130 2         28 close $fh;
131              
132 2         11 1;
133             }
134              
135             sub save
136             {
137 1     1 1 935 my( $self, $file ) = @_;
138              
139 1   0     5 $file ||= $self->{'file'} || return;
      33        
140              
141 1 50       165 open my $fh, '>:raw', $file or die "Could not write file [$file]! $!\n";
142              
143             $self->scan(
144             sub {
145 5     5   106 my( $version, $key, $val, $path, $domain, $port,
146             $path_spec, $secure, $expires, $discard, $rest ) = @_;
147              
148 5 50 33     17 return if $discard && not $self->{ignore_discard};
149              
150 5 50 33     28 return if defined $expires && time > $expires;
151              
152 5         8 $expires += OFFSET;
153              
154 5 50       13 $secure = $secure ? TRUE : FALSE;
155              
156 5 50       32 my $bool = $domain =~ /^\./ ? TRUE : FALSE;
157              
158 5         57 print $fh 'Date', pack( 'N', time + OFFSET ),
159             'Cook',
160             pack( 'N', length $key ), $key,
161             pack( 'N', length $path ), $path,
162             pack( 'N', length $domain ), $domain,
163             pack( 'N', length $val ), $val,
164             pack( 'N', $expires );
165             }
166 1         18 );
167              
168 1         83 close $fh;
169             }
170              
171             sub read_int
172             {
173 60     60 0 70 my $fh = shift;
174              
175 60         99 my $result = read_str( $fh, 4 );
176              
177 60         126 my $number = unpack( "N", $result );
178              
179 60         98 return $number;
180             }
181              
182             sub read_date
183             {
184 10     10 0 13 my $fh = shift;
185              
186 10         23 my $string = read_str( $fh, 4 );
187 10 50       29 warn( "\t==tag is [$string] not 'Date'\n" ) unless $string eq 'Date';
188              
189 10         22 my $date = read_int( $fh );
190 10 50       27 warn( sprintf "\t==read date %X | %d | %s\n", $date, $date,
191             scalar localtime $date ) if $Debug > 1;
192              
193 10         14 $date -= OFFSET;
194 10 50       23 warn( sprintf "\t==read date %X | %d | %s\n", $date, $date,
195             scalar localtime $date ) if $Debug > 1;
196              
197 10         26 return $date;
198             }
199              
200             sub read_var
201             {
202 40     40 0 53 my $fh = shift;
203              
204 40         57 my $length = read_int( $fh );
205 40 50       87 warn "length is $length\n" if $Debug > 1;
206 40         65 my $string = read_str( $fh, $length );
207              
208 40         130 return $string;
209             }
210              
211             sub read_str
212             {
213 130     130 0 134 my $fh = shift;
214 130         162 my $length = shift;
215              
216 130         351 my $result = read( $fh, my $string, $length );
217              
218 130         314 return $string;
219             }
220              
221             sub peek
222             {
223 8     8 0 12 my $fh = shift;
224 8         8 my $length = shift;
225              
226 8         17 my $result = read( $fh, my $string, $length );
227              
228 8         73 seek $fh, -$length, 1;
229              
230 8         22 return $string;
231             }
232              
233             1;