Skip to content

Commit

Permalink
Add partitioned cookies
Browse files Browse the repository at this point in the history
  • Loading branch information
rawleyfowler committed Aug 28, 2024
1 parent ecb44cf commit 3644d5b
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 10 deletions.
9 changes: 6 additions & 3 deletions lib/Mojo/Cookie/Response.pm
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ use Mojo::Base 'Mojo::Cookie';
use Mojo::Date;
use Mojo::Util qw(quote split_cookie_header);

has [qw(domain expires host_only httponly max_age path samesite secure)];
has [qw(domain expires host_only httponly max_age path samesite secure partitioned)];

my %ATTRS = map { $_ => 1 } qw(domain expires httponly max-age path samesite secure);
my %ATTRS = map { $_ => 1 } qw(domain expires httponly max-age path samesite secure partitioned);

sub parse {
my ($self, $str) = @_;
Expand All @@ -21,7 +21,7 @@ sub parse {
next unless $ATTRS{my $attr = lc $name};
$value =~ s/^\.// if $attr eq 'domain' && defined $value;
$value = Mojo::Date->new($value // '')->epoch if $attr eq 'expires';
$value = 1 if $attr eq 'secure' || $attr eq 'httponly';
$value = 1 if $attr eq 'secure' || $attr eq 'httponly' || $attr eq 'partitioned';
$cookies[-1]{$attr eq 'max-age' ? 'max_age' : $attr} = $value;
}
}
Expand Down Expand Up @@ -53,6 +53,9 @@ sub to_string {
# "HttpOnly"
$cookie .= "; HttpOnly" if $self->httponly;

# "Partitioned"
$cookie .= "; Partitioned" if $self->partitioned;

# "Same-Site"
if (my $samesite = $self->samesite) { $cookie .= "; SameSite=$samesite" }

Expand Down
14 changes: 8 additions & 6 deletions lib/Mojolicious/Sessions.pm
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ has default_expiration => 3600;
has deserialize => sub { \&_deserialize };
has samesite => 'Lax';
has serialize => sub { \&_serialize };
has partitioned => 0;

sub load {
my ($self, $c) = @_;
Expand Down Expand Up @@ -51,12 +52,13 @@ sub store {
my $value = b64_encode $self->serialize->($session), '';
$value =~ y/=/-/;
my $options = {
domain => $self->cookie_domain,
expires => $session->{expires},
httponly => 1,
path => $self->cookie_path,
samesite => $self->samesite,
secure => $self->secure
domain => $self->cookie_domain,
expires => $session->{expires},
httponly => 1,
path => $self->cookie_path,
samesite => $self->samesite,
secure => $self->secure,
partitioned => $self->partitioned
};
$c->signed_cookie($self->cookie_name, $value, $options);
}
Expand Down
15 changes: 14 additions & 1 deletion t/mojo/cookie.t
Original file line number Diff line number Diff line change
Expand Up @@ -173,8 +173,9 @@ subtest 'Full response cookie as string' => sub {
$cookie->secure(1);
$cookie->httponly(1);
$cookie->samesite('Lax');
$cookie->partitioned(1);
is $cookie->to_string, '0="ba r"; expires=Thu, 07 Aug 2008 07:07:59 GMT; domain=example.com;'
. ' path=/test; secure; HttpOnly; SameSite=Lax; Max-Age=60', 'right format';
. ' path=/test; secure; HttpOnly; Partitioned; SameSite=Lax; Max-Age=60', 'right format';
};

subtest 'Empty response cookie' => sub {
Expand Down Expand Up @@ -216,6 +217,18 @@ subtest 'Parse response cookie (RFC 6265)' => sub {
is $cookies->[1], undef, 'no more cookies';
};

subtest 'Partitioned cookie (RFC 6265 CHIPS)' => sub {
my $cookies
= Mojo::Cookie::Response->parse(
'foo="bar"; Domain=example.com; Path=/test; Max-Age=60; Partitioned; Expires=Thu, 07 Aug 2008 07:07:59 GMT; Secure;'
);
is $cookies->[0]->partitioned, 1, 'partitioned set?';

$cookies = Mojo::Cookie::Response->parse(
'foo="bar"; Domain=example.com; Path=/test; Max-Age=60; Expires=Thu, 07 Aug 2008 07:07:59 GMT; Secure;');
is $cookies->[0]->partitioned, undef, 'partitioned not set?';
};

subtest 'Parse response cookie with invalid flag (RFC 6265)' => sub {
my $cookies = Mojo::Cookie::Response->parse(
'foo="ba r"; Domain=.example.com; Path=/test; Max-Age=60;' . ' Expires=Thu, 07 Aug 2008 07:07:59 GMT; InSecure;');
Expand Down

0 comments on commit 3644d5b

Please sign in to comment.