diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpCookie.java b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpCookie.java index 9f47fb01c61..722704ac8be 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpCookie.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpCookie.java @@ -29,6 +29,21 @@ public class HttpCookie private static final String __COOKIE_DELIM = "\",;\\ \t"; private static final String __01Jan1970_COOKIE = DateGenerator.formatCookieDate(0).trim(); + public enum SameSite + { + EXCLUDED("Excluded"), NONE("None"), STRICT("Strict"), LAX("Lax"); + + private String attributeValue; + SameSite(String attributeValue) { + this.attributeValue = attributeValue; + } + + @Override + public String toString(){ + return this.attributeValue; + } + } + private final String _name; private final String _value; private final String _comment; @@ -39,6 +54,7 @@ public class HttpCookie private final int _version; private final boolean _httpOnly; private final long _expiration; + private final SameSite _sameSite; public HttpCookie(String name, String value) { @@ -61,6 +77,11 @@ public class HttpCookie } public HttpCookie(String name, String value, String domain, String path, long maxAge, boolean httpOnly, boolean secure, String comment, int version) + { + this(name, value, domain, path, maxAge, httpOnly, secure, comment, version, SameSite.EXCLUDED); + } + + public HttpCookie(String name, String value, String domain, String path, long maxAge, boolean httpOnly, boolean secure, String comment, int version, SameSite sameSite) { _name = name; _value = value; @@ -72,6 +93,7 @@ public class HttpCookie _comment = comment; _version = version; _expiration = maxAge < 0 ? -1 : System.nanoTime() + TimeUnit.SECONDS.toNanos(maxAge); + _sameSite = sameSite; } public HttpCookie(String setCookie) @@ -92,6 +114,8 @@ public class HttpCookie _comment = cookie.getComment(); _version = cookie.getVersion(); _expiration = _maxAge < 0 ? -1 : System.nanoTime() + TimeUnit.SECONDS.toNanos(_maxAge); + // TODO support for SameSite values has not yet been added to java.net.HttpCookie + _sameSite = SameSite.EXCLUDED; } /** @@ -158,6 +182,14 @@ public class HttpCookie return _version; } + /** + * @return the cookie SameSite enum attribute + */ + public SameSite getSameSite() + { + return _sameSite; + } + /** * @return whether the cookie is valid for the http protocol only */ @@ -366,6 +398,12 @@ public class HttpCookie buf.append("; Secure"); if (_httpOnly) buf.append("; HttpOnly"); + if (_sameSite != SameSite.EXCLUDED) + { + buf.append("; SameSite="); + buf.append(_sameSite.toString()); + } + return buf.toString(); } diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpCookieTest.java b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpCookieTest.java index e58550bee61..d69adffc3c2 100644 --- a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpCookieTest.java +++ b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpCookieTest.java @@ -90,6 +90,10 @@ public class HttpCookieTest httpCookie = new HttpCookie("everything", "value", "domain", "path", 0, true, true, null, -1); assertEquals("everything=value; Path=path; Domain=domain; Expires=Thu, 01-Jan-1970 00:00:00 GMT; Max-Age=0; Secure; HttpOnly", httpCookie.getRFC6265SetCookie()); + + httpCookie = new HttpCookie("everything", "value", "domain", "path", 0, true, true, null, -1, HttpCookie.SameSite.NONE); + assertEquals("everything=value; Path=path; Domain=domain; Expires=Thu, 01-Jan-1970 00:00:00 GMT; Max-Age=0; Secure; HttpOnly; SameSite=None", httpCookie.getRFC6265SetCookie()); + String[] badNameExamples = { "\"name\"", "name\t",