diff options
author | Valerij Fredriksen <freva@users.noreply.github.com> | 2021-01-26 13:48:40 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-01-26 13:48:40 +0100 |
commit | 3602fbc2bc9530429589e5ad50c105f12fea3c49 (patch) | |
tree | 9d4af261b9954aa0a2f850c7df699520f92d422f /jdisc_http_service/src | |
parent | 8947cd201d5647cc0ebdccaa2235292ae24bac89 (diff) | |
parent | a3d4196f58534294920ee2afccdc3b639339cb96 (diff) |
Merge pull request #16228 from vespa-engine/freva/same-site
Support SameSite in cookies
Diffstat (limited to 'jdisc_http_service/src')
-rw-r--r-- | jdisc_http_service/src/main/java/com/yahoo/jdisc/http/Cookie.java | 32 | ||||
-rw-r--r-- | jdisc_http_service/src/test/java/com/yahoo/jdisc/http/CookieTestCase.java | 27 |
2 files changed, 49 insertions, 10 deletions
diff --git a/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/Cookie.java b/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/Cookie.java index ace6161653e..d882cf7a34a 100644 --- a/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/Cookie.java +++ b/jdisc_http_service/src/main/java/com/yahoo/jdisc/http/Cookie.java @@ -1,12 +1,14 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.jdisc.http; +import org.eclipse.jetty.http.HttpCookie; import org.eclipse.jetty.server.CookieCutter; import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Objects; +import java.util.Optional; import java.util.Set; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; @@ -29,6 +31,7 @@ public class Cookie { private String value; private String domain; private String path; + private SameSite sameSite; private long maxAgeSeconds = Integer.MIN_VALUE; private boolean secure; private boolean httpOnly; @@ -43,6 +46,7 @@ public class Cookie { value = cookie.value; domain = cookie.domain; path = cookie.path; + sameSite = cookie.sameSite; maxAgeSeconds = cookie.maxAgeSeconds; secure = cookie.secure; httpOnly = cookie.httpOnly; @@ -90,6 +94,15 @@ public class Cookie { return this; } + public SameSite getSameSite() { + return sameSite; + } + + public Cookie setSameSite(SameSite sameSite) { + this.sameSite = sameSite; + return this; + } + public int getMaxAge(TimeUnit unit) { return (int)unit.convert(maxAgeSeconds, TimeUnit.SECONDS); } @@ -126,6 +139,7 @@ public class Cookie { secure == cookie.secure && httpOnly == cookie.httpOnly && discard == cookie.discard && + sameSite == cookie.sameSite && Objects.equals(ports, cookie.ports) && Objects.equals(name, cookie.name) && Objects.equals(value, cookie.value) && @@ -135,7 +149,7 @@ public class Cookie { @Override public int hashCode() { - return Objects.hash(ports, name, value, domain, path, maxAgeSeconds, secure, httpOnly, discard); + return Objects.hash(ports, name, value, domain, path, sameSite, maxAgeSeconds, secure, httpOnly, discard); } @Override @@ -193,7 +207,10 @@ public class Cookie { cookie.getPath(), cookie.getMaxAge(TimeUnit.SECONDS), cookie.isHttpOnly(), - cookie.isSecure() + cookie.isSecure(), + null, /* comment */ + 0, /* version */ + Optional.ofNullable(cookie.getSameSite()).map(SameSite::jettySameSite).orElse(null) ).getRFC6265SetCookie()) .collect(toList()); } @@ -219,4 +236,15 @@ public class Cookie { .findFirst().get(); } + public enum SameSite { + NONE, STRICT, LAX; + + HttpCookie.SameSite jettySameSite() { + return HttpCookie.SameSite.valueOf(name()); + } + + static SameSite fromJettySameSite(HttpCookie.SameSite jettySameSite) { + return valueOf(jettySameSite.name()); + } + } } diff --git a/jdisc_http_service/src/test/java/com/yahoo/jdisc/http/CookieTestCase.java b/jdisc_http_service/src/test/java/com/yahoo/jdisc/http/CookieTestCase.java index 709a9484349..dbdce5c704e 100644 --- a/jdisc_http_service/src/test/java/com/yahoo/jdisc/http/CookieTestCase.java +++ b/jdisc_http_service/src/test/java/com/yahoo/jdisc/http/CookieTestCase.java @@ -3,8 +3,6 @@ package com.yahoo.jdisc.http; import org.junit.Test; -import java.util.Arrays; -import java.util.Collections; import java.util.List; import java.util.concurrent.TimeUnit; @@ -104,17 +102,19 @@ public class CookieTestCase { public void requireThatCookieCanBeEncoded() { assertEncodeCookie( "foo.name=foo.value", - Collections.singletonList(newCookie("foo"))); + List.of(newCookie("foo"))); assertEncodeCookie( "foo.name=foo.value;bar.name=bar.value", - Arrays.asList(newCookie("foo"), newCookie("bar"))); + List.of(newCookie("foo"), newCookie("bar"))); } @Test public void requireThatSetCookieCanBeEncoded() { assertEncodeSetCookie( - Collections.singletonList("foo.name=foo.value; Path=path; Domain=domain; Secure; HttpOnly"), - Collections.singletonList(newSetCookie("foo"))); + List.of("foo.name=foo.value; Path=path; Domain=domain; Secure; HttpOnly", + "foo.name=foo.value; Path=path; Domain=domain; Secure; HttpOnly; SameSite=None"), + List.of(newSetCookie("foo"), + newSetCookie("foo").setSameSite(Cookie.SameSite.NONE))); } @Test @@ -122,12 +122,12 @@ public class CookieTestCase { final Cookie foo = new Cookie(); foo.setName("foo.name"); foo.setValue("foo.value"); - assertDecodeCookie(Collections.singletonList(newCookie("foo")), "foo.name=foo.value"); + assertDecodeCookie(List.of(newCookie("foo")), "foo.name=foo.value"); final Cookie bar = new Cookie(); bar.setName("bar.name"); bar.setValue("bar.value"); - assertDecodeCookie(Arrays.asList(foo, bar),"foo.name=foo.value; bar.name=bar.value"); + assertDecodeCookie(List.of(foo, bar),"foo.name=foo.value; bar.name=bar.value"); } @Test @@ -189,6 +189,17 @@ public class CookieTestCase { "2UDMuUGZ6WkdTT2ctLQ--"); } + @Test + public void requireMappingBetweenSameSiteAndJettySameSite() { + for (var jdiscSameSite : Cookie.SameSite.values()) { + assertEquals(jdiscSameSite, Cookie.SameSite.fromJettySameSite(jdiscSameSite.jettySameSite())); + } + + for (var jettySameSite : org.eclipse.jetty.http.HttpCookie.SameSite.values()) { + assertEquals(jettySameSite, Cookie.SameSite.fromJettySameSite(jettySameSite).jettySameSite()); + } + } + private static void assertEncodeCookie(String expectedResult, List<Cookie> cookies) { String actual = Cookie.toCookieHeader(cookies); String expectedResult1 = expectedResult; |