File Coverage

blib/lib/Mojo/Cookie/Response.pm
Criterion Covered Total %
statement 39 39 100.0
branch 28 28 100.0
condition 15 16 93.7
subroutine 5 5 100.0
pod 2 2 100.0
total 89 90 98.8


line stmt bran cond sub pod time code
1             package Mojo::Cookie::Response;
2 62     62   93265 use Mojo::Base 'Mojo::Cookie';
  62         146  
  62         470  
3              
4 62     62   32987 use Mojo::Date;
  62         251  
  62         1092  
5 62     62   1055 use Mojo::Util qw(quote split_cookie_header);
  62         145  
  62         60668  
6              
7             has [qw(domain expires host_only httponly max_age path samesite secure)];
8              
9             my %ATTRS = map { $_ => 1 } qw(domain expires httponly max-age path samesite secure);
10              
11             sub parse {
12 1065     1065 1 59905 my ($self, $str) = @_;
13              
14 1065         2122 my @cookies;
15 1065   100     8438 my $tree = split_cookie_header $str // '';
16 1065         4472 while (my $pairs = shift @$tree) {
17 195         667 my ($name, $value) = splice @$pairs, 0, 2;
18 195   50     969 push @cookies, $self->new(name => $name, value => $value // '');
19              
20 195         717 while (my ($name, $value) = splice @$pairs, 0, 2) {
21 395 100       1175 next unless $ATTRS{my $attr = lc $name};
22 392 100 100     987 $value =~ s/^\.// if $attr eq 'domain' && defined $value;
23 392 100 100     1053 $value = Mojo::Date->new($value // '')->epoch if $attr eq 'expires';
24 392 100 100     1427 $value = 1 if $attr eq 'secure' || $attr eq 'httponly';
25 392 100       2178 $cookies[-1]{$attr eq 'max-age' ? 'max_age' : $attr} = $value;
26             }
27             }
28              
29 1065         7689 return \@cookies;
30             }
31              
32             sub to_string {
33 161     161 1 289 my $self = shift;
34              
35             # Name and value
36 161 100 100     545 return '' unless length(my $name = $self->name // '');
37 160   100     505 my $value = $self->value // '';
38 160 100       1001 my $cookie = join '=', $name, $value =~ /[,;" ]/ ? quote $value : $value;
39              
40             # "expires"
41 160         544 my $expires = $self->expires;
42 160 100       664 $cookie .= '; expires=' . Mojo::Date->new($expires) if defined $expires;
43              
44             # "domain"
45 160 100       557 if (my $domain = $self->domain) { $cookie .= "; domain=$domain" }
  24         73  
46              
47             # "path"
48 160 100       467 if (my $path = $self->path) { $cookie .= "; path=$path" }
  80         214  
49              
50             # "secure"
51 160 100       468 $cookie .= "; secure" if $self->secure;
52              
53             # "HttpOnly"
54 160 100       502 $cookie .= "; HttpOnly" if $self->httponly;
55              
56             # "Same-Site"
57 160 100       406 if (my $samesite = $self->samesite) { $cookie .= "; SameSite=$samesite" }
  38         90  
58              
59             # "Max-Age"
60 160 100       461 if (defined(my $max = $self->max_age)) { $cookie .= "; Max-Age=$max" }
  10         18  
61              
62 160         1122 return $cookie;
63             }
64              
65             1;
66              
67             =encoding utf8
68              
69             =head1 NAME
70              
71             Mojo::Cookie::Response - HTTP response cookie
72              
73             =head1 SYNOPSIS
74              
75             use Mojo::Cookie::Response;
76              
77             my $cookie = Mojo::Cookie::Response->new;
78             $cookie->name('foo');
79             $cookie->value('bar');
80             say "$cookie";
81              
82             =head1 DESCRIPTION
83              
84             L is a container for HTTP response cookies, based on L
85             6265|https://tools.ietf.org/html/rfc6265>.
86              
87             =head1 ATTRIBUTES
88              
89             L inherits all attributes from L and implements the following new ones.
90              
91             =head2 domain
92              
93             my $domain = $cookie->domain;
94             $cookie = $cookie->domain('localhost');
95              
96             Cookie domain.
97              
98             =head2 expires
99              
100             my $expires = $cookie->expires;
101             $cookie = $cookie->expires(time + 60);
102              
103             Expiration for cookie.
104              
105             =head2 host_only
106              
107             my $bool = $cookie->host_only;
108             $cookie = $cookie->host_only($bool);
109              
110             Host-only flag, indicating that the canonicalized request-host is identical to the cookie's L.
111              
112             =head2 httponly
113              
114             my $bool = $cookie->httponly;
115             $cookie = $cookie->httponly($bool);
116              
117             HttpOnly flag, which can prevent client-side scripts from accessing this cookie.
118              
119             =head2 max_age
120              
121             my $max_age = $cookie->max_age;
122             $cookie = $cookie->max_age(60);
123              
124             Max age for cookie.
125              
126             =head2 path
127              
128             my $path = $cookie->path;
129             $cookie = $cookie->path('/test');
130              
131             Cookie path.
132              
133             =head2 samesite
134              
135             my $samesite = $cookie->samesite;
136             $cookie = $cookie->samesite('Lax');
137              
138             SameSite value.
139              
140             =head2 secure
141              
142             my $bool = $cookie->secure;
143             $cookie = $cookie->secure($bool);
144              
145             Secure flag, which instructs browsers to only send this cookie over HTTPS connections.
146              
147             =head1 METHODS
148              
149             L inherits all methods from L and implements the following new ones.
150              
151             =head2 parse
152              
153             my $cookies = Mojo::Cookie::Response->parse('f=b; path=/');
154              
155             Parse cookies.
156              
157             =head2 to_string
158              
159             my $str = $cookie->to_string;
160              
161             Render cookie.
162              
163             =head1 SEE ALSO
164              
165             L, L, L.
166              
167             =cut