diff --git a/Frameworks/Core/ERExtensions/Sources/com/webobjects/appserver/WOCookie.java b/Frameworks/Core/ERExtensions/Sources/com/webobjects/appserver/WOCookie.java index de872d32673..abecdcf6a7c 100644 --- a/Frameworks/Core/ERExtensions/Sources/com/webobjects/appserver/WOCookie.java +++ b/Frameworks/Core/ERExtensions/Sources/com/webobjects/appserver/WOCookie.java @@ -13,10 +13,10 @@ import com.webobjects.foundation.NSTimeZone; import com.webobjects.foundation.NSTimestamp; -public class WOCookie implements NSKeyValueCoding, com.webobjects.foundation.NSKeyValueCoding.ErrorHandling, +public class WOCookie implements NSKeyValueCoding, NSKeyValueCoding.ErrorHandling, NSKeyValueCodingAdditions, Serializable { - static final long serialVersionUID = 310727495L; + static final long serialVersionUID = 1L; String _name; String _value; String _domain; @@ -25,6 +25,7 @@ public class WOCookie implements NSKeyValueCoding, com.webobjects.foundation.NSK NSTimestamp _expires; int _timeout; boolean _isHttpOnly; + SameSite _sameSite; @Deprecated static final SimpleDateFormat TheDateFormat; @@ -80,8 +81,8 @@ public WOCookie(final String name, final String value, final String path, final _expires = expires; _isSecure = isSecure; _isHttpOnly = httpOnly; + _sameSite = SameSite.NORMAL; setTimeOut(-1); - return; } public WOCookie(final String name, final String value, final String path, final String domain, final int timeout, @@ -101,7 +102,7 @@ public WOCookie(final String name, final String value, final String path, final setTimeOut(timeout); _isSecure = isSecure; _isHttpOnly = httpOnly; - return; + _sameSite = SameSite.NORMAL; } public WOCookie(final String name, final String value) { @@ -113,11 +114,13 @@ public String toString() { String expiresString = _expires != null ? new StringBuilder().append(" expires=") .append(TIMESTAMP_FORMATTER.get().format(_expires)).toString() : ""; String expires = _timeout < 0 ? "" : new StringBuilder().append(" max-age=").append(_timeout).toString(); + String sameSite = _sameSite == SameSite.NORMAL ? "" : + new StringBuilder().append(" SameSite=").append(_sameSite.toString().toLowerCase()).toString(); return new StringBuilder().append('<').append(getClass().getName()).append(" name=").append(_name) .append(" value=").append(_value).append(" path=").append(_path).append(" domain=").append(_domain) .append(expiresString).append(expires).append(" isSecure=").append(_isSecure) - .append(" isHttpOnly=").append(_isHttpOnly).append('>').toString(); + .append(" isHttpOnly=").append(_isHttpOnly).append(sameSite).append('>').toString(); } public String headerString() { @@ -168,6 +171,10 @@ String _headerString(final boolean isRequest) { if (_isHttpOnly) { header.append("; HttpOnly"); } + if (_sameSite != SameSite.NORMAL) { + header.append("; SameSite="); + header.append(_sameSite.toString().toLowerCase()); + } } return header.toString(); } @@ -236,36 +243,44 @@ public void setIsHttpOnly(final boolean isHttpOnly) { _isHttpOnly = isHttpOnly; } + public SameSite sameSite() { + return _sameSite; + } + + public void setSameSite(final SameSite sameSite) { + _sameSite = sameSite; + } + public static boolean canAccessFieldsDirectly() { return true; } public Object valueForKey(final String key) { - return com.webobjects.foundation.NSKeyValueCoding.DefaultImplementation.valueForKey(this, key); + return NSKeyValueCoding.DefaultImplementation.valueForKey(this, key); } public void takeValueForKey(final Object value, final String key) { - com.webobjects.foundation.NSKeyValueCoding.DefaultImplementation.takeValueForKey(this, value, key); + NSKeyValueCoding.DefaultImplementation.takeValueForKey(this, value, key); } public Object handleQueryWithUnboundKey(final String key) { - return com.webobjects.foundation.NSKeyValueCoding.DefaultImplementation.handleQueryWithUnboundKey(this, key); + return NSKeyValueCoding.DefaultImplementation.handleQueryWithUnboundKey(this, key); } public void handleTakeValueForUnboundKey(final Object value, final String key) { - com.webobjects.foundation.NSKeyValueCoding.DefaultImplementation.handleTakeValueForUnboundKey(this, value, key); + NSKeyValueCoding.DefaultImplementation.handleTakeValueForUnboundKey(this, value, key); } public void unableToSetNullForKey(final String key) { - com.webobjects.foundation.NSKeyValueCoding.DefaultImplementation.unableToSetNullForKey(this, key); + NSKeyValueCoding.DefaultImplementation.unableToSetNullForKey(this, key); } public Object valueForKeyPath(final String key) { - return com.webobjects.foundation.NSKeyValueCodingAdditions.DefaultImplementation.valueForKeyPath(this, key); + return NSKeyValueCodingAdditions.DefaultImplementation.valueForKeyPath(this, key); } public void takeValueForKeyPath(final Object value, final String key) { - com.webobjects.foundation.NSKeyValueCodingAdditions.DefaultImplementation.takeValueForKeyPath(this, value, key); + NSKeyValueCodingAdditions.DefaultImplementation.takeValueForKeyPath(this, value, key); } private void writeObject(final ObjectOutputStream out) throws IOException { @@ -277,6 +292,7 @@ private void writeObject(final ObjectOutputStream out) throws IOException { out.writeBoolean(_isSecure); out.writeObject(_expires); out.writeBoolean(_isHttpOnly); + out.writeObject(_sameSite); } private void readObject(final ObjectInputStream out) throws IOException, ClassNotFoundException { @@ -288,5 +304,17 @@ private void readObject(final ObjectInputStream out) throws IOException, ClassNo _isSecure = out.readBoolean(); _expires = (NSTimestamp) out.readObject(); _isHttpOnly = out.readBoolean(); + _sameSite = (SameSite) out.readObject(); + } + + /** + * Possible values for same-site cookie setting. + * + * @see RFC draft + */ + public static enum SameSite { + NORMAL, + LAX, + STRICT } }