Codebase list libhttp-cookiejar-perl / aa20e7a
dump/load_cookies without save/load to file David Golden 11 years ago
2 changed file(s) with 38 addition(s) and 30 deletion(s). Raw diff Collapse all Expand all
44 package HTTP::CookieJar;
55 # ABSTRACT: A minimalist HTTP user agent cookie jar
66 # VERSION
7
8 use Path::Tiny ();
97
108 sub new {
119 my ($class) = @_;
2725 # XXX doesn't check for public suffixes; see Mozilla::PublicSuffix
2826 if ( exists $parse->{domain} ) {
2927 return unless _domain_match( $host, $parse->{domain} );
30 $parse->{hostonly} = 0;
3128 }
3229 else {
3330 $parse->{domain} = $host;
4239 # set timestamps and normalize expires
4340 my $now = $parse->{creation_time} = $parse->{last_access_time} = time;
4441 if ( exists $parse->{'max-age'} ) {
45 $parse->{expires} = $now + $parse->{'max-age'};
42 $parse->{expires} = $now + delete $parse->{'max-age'};
4643 }
4744 # update creation time from old cookie, if exists
4845 if ( my $old = $self->{store}{$domain}{$path}{$name} ) {
8986 }
9087
9188 # generate as list that can be fed back in to add
92 sub as_list {
89 sub dump_cookies {
9390 my ( $self, $args ) = @_;
9491 my @list;
9592 for my $c ( $self->_all_cookies ) {
96 next if $args->{persistent} && !defined $c->{expires};
9793 my @parts = "$c->{name}=$c->{value}";
98 for my $attr (qw/Domain Path Expires Creation_Time Last_Access_Time/) {
94 if ( defined $c->{expires} ) {
95 push @parts, 'Expires=' . _http_date($c->{expires});
96 } else {
97 next if $args->{persistent};
98 }
99 for my $attr (qw/Domain Path Creation_Time Last_Access_Time/) {
99100 push @parts, "$attr=$c->{lc $attr}" if defined $c->{ lc $attr };
100101 }
101102 for my $attr (qw/Secure HttpOnly HostOnly/) {
106107 return @list;
107108 }
108109
109 sub from_list {
110 # returns self
111 sub load_cookies {
110112 my ( $self, @cookies ) = @_;
111113 for my $cookie ( @cookies ) {
112114 my $p = _parse_cookie($cookie, 1);
115 next unless exists $p->{domain} && exists $p->{path};
113116 $p->{$_} //= time for qw/creation_time last_access_time/;
114117 $self->{store}{ $p->{domain} }{ $p->{path} }{ $p->{name} } = $p;
115118 }
116 return;
117 }
118
119 sub save {
120 my ( $self, $filename ) = @_;
121 Path::Tiny::path($filename)->spew( join( "\n", $self->as_list ) );
122 }
123
124 sub load {
125 my ( $self, $filename ) = @_;
126 $self->from_list( Path::Tiny::path($filename)->lines( { chomp => 1 } ) );
127119 return $self;
128120 }
129121
22 use warnings;
33 use Test::More 0.96;
44 use Test::Deep '!blessed';
5 use Path::Tiny;
65
76 use HTTP::CookieJar;
87
1312 'SID=31d4d96e407aad42; Path=/; Secure; HttpOnly',
1413 );
1514
16 my $file = Path::Tiny->tempfile;
15 my @persistent = (
16 'lang=en_US; Path=/; Domain=example.com; Secure; HttpOnly; Max-Age = 3600',
17 );
1718
1819 subtest "empty cookie jar" => sub {
1920 my $jar = HTTP::CookieJar->new;
20 ok( $jar->save("$file"), "save cookie jar");
21 ok( my $jar2 = HTTP::CookieJar->new->load("$file"), "load cookie jar" );
22 is( scalar $jar2->_all_cookies, 0, "jar is empty" );
21 my @list = $jar->dump_cookies;
22 is( scalar @list, 0, "dumped zero cookies" );
23 ok( my $jar2 = HTTP::CookieJar->new->load_cookies(@list), "load new cookie jar" );
24 is( scalar $jar2->dump_cookies, 0, "second jar is empty" );
2325 };
2426
2527 subtest "roundtrip" => sub {
2628 my $jar = HTTP::CookieJar->new;
27 $jar->add("http://www.example.com/", $_) for @cookies;
28 ok( $jar->save("$file"), "save cookie jar");
29 ok( my $jar2 = HTTP::CookieJar->new->load("$file"), "load cookie jar" );
30 is( scalar $jar2->_all_cookies, 1, "jar has a cookie" );
31 cmp_deeply( $jar, $jar2, "old and new jars are the same" );
29 $jar->add("http://www.example.com/", $_) for @cookies, @persistent;
30 my @list = $jar->dump_cookies;
31 is( scalar @list, @cookies + @persistent, "dumped correct number of cookies" );
32 ok( my $jar2 = HTTP::CookieJar->new->load_cookies(@list), "load new cookie jar" );
33 is( scalar $jar2->dump_cookies, @cookies+@persistent, "second jar has correct count" );
34 cmp_deeply( $jar, $jar2, "old and new jars are the same" ) or diag explain [$jar, $jar2];
3235 };
3336
34 # test cookie jar load without private stuff
37 subtest "persistent" => sub {
38 my $jar = HTTP::CookieJar->new;
39 $jar->add("http://www.example.com/", $_) for @cookies, @persistent;
40 my @list = $jar->dump_cookies({persistent => 1});
41 is( scalar @list, @cookies, "dumped correct number of cookies" );
42 ok( my $jar2 = HTTP::CookieJar->new->load_cookies(@list), "load new cookie jar" );
43 is( scalar $jar2->dump_cookies, @cookies, "second jar has correct count" );
44 };
3545
46 # can load raw cookies with both path and domain
47 subtest "liberal load" => sub {
48 my $jar = HTTP::CookieJar->new;
49 ok( $jar->load_cookies(@persistent, @cookies), "load_cookies with raw cookies" );
50 is( scalar $jar->dump_cookies, @persistent, "jar has correct count" );
51 };
3652
3753 done_testing;
3854 # COPYRIGHT