summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorValerij Fredriksen <freva@users.noreply.github.com>2021-01-26 13:48:40 +0100
committerGitHub <noreply@github.com>2021-01-26 13:48:40 +0100
commit3602fbc2bc9530429589e5ad50c105f12fea3c49 (patch)
tree9d4af261b9954aa0a2f850c7df699520f92d422f
parent8947cd201d5647cc0ebdccaa2235292ae24bac89 (diff)
parenta3d4196f58534294920ee2afccdc3b639339cb96 (diff)
Merge pull request #16228 from vespa-engine/freva/same-site
Support SameSite in cookies
-rw-r--r--jdisc_http_service/abi-spec.json20
-rw-r--r--jdisc_http_service/src/main/java/com/yahoo/jdisc/http/Cookie.java32
-rw-r--r--jdisc_http_service/src/test/java/com/yahoo/jdisc/http/CookieTestCase.java27
3 files changed, 69 insertions, 10 deletions
diff --git a/jdisc_http_service/abi-spec.json b/jdisc_http_service/abi-spec.json
index ef30a618a97..34e021eec62 100644
--- a/jdisc_http_service/abi-spec.json
+++ b/jdisc_http_service/abi-spec.json
@@ -377,6 +377,24 @@
"public static final java.lang.String[] CONFIG_DEF_SCHEMA"
]
},
+ "com.yahoo.jdisc.http.Cookie$SameSite": {
+ "superClass": "java.lang.Enum",
+ "interfaces": [],
+ "attributes": [
+ "public",
+ "final",
+ "enum"
+ ],
+ "methods": [
+ "public static com.yahoo.jdisc.http.Cookie$SameSite[] values()",
+ "public static com.yahoo.jdisc.http.Cookie$SameSite valueOf(java.lang.String)"
+ ],
+ "fields": [
+ "public static final enum com.yahoo.jdisc.http.Cookie$SameSite NONE",
+ "public static final enum com.yahoo.jdisc.http.Cookie$SameSite STRICT",
+ "public static final enum com.yahoo.jdisc.http.Cookie$SameSite LAX"
+ ]
+ },
"com.yahoo.jdisc.http.Cookie": {
"superClass": "java.lang.Object",
"interfaces": [],
@@ -395,6 +413,8 @@
"public com.yahoo.jdisc.http.Cookie setDomain(java.lang.String)",
"public java.lang.String getPath()",
"public com.yahoo.jdisc.http.Cookie setPath(java.lang.String)",
+ "public com.yahoo.jdisc.http.Cookie$SameSite getSameSite()",
+ "public com.yahoo.jdisc.http.Cookie setSameSite(com.yahoo.jdisc.http.Cookie$SameSite)",
"public int getMaxAge(java.util.concurrent.TimeUnit)",
"public com.yahoo.jdisc.http.Cookie setMaxAge(int, java.util.concurrent.TimeUnit)",
"public boolean isSecure()",
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;