Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion okhttp/api/android/okhttp.api
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ public final class okhttp3/Cookie {
public final fun -deprecated_persistent ()Z
public final fun -deprecated_secure ()Z
public final fun -deprecated_value ()Ljava/lang/String;
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;JLjava/lang/String;Ljava/lang/String;ZZZZLjava/lang/String;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;JLjava/lang/String;Ljava/lang/String;ZZZZLjava/lang/String;ZLkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun domain ()Ljava/lang/String;
public fun equals (Ljava/lang/Object;)Z
public final fun expiresAt ()J
Expand All @@ -414,6 +414,7 @@ public final class okhttp3/Cookie {
public final fun newBuilder ()Lokhttp3/Cookie$Builder;
public static final fun parse (Lokhttp3/HttpUrl;Ljava/lang/String;)Lokhttp3/Cookie;
public static final fun parseAll (Lokhttp3/HttpUrl;Lokhttp3/Headers;)Ljava/util/List;
public final fun partitioned ()Z
public final fun path ()Ljava/lang/String;
public final fun persistent ()Z
public final fun sameSite ()Ljava/lang/String;
Expand All @@ -430,6 +431,7 @@ public final class okhttp3/Cookie$Builder {
public final fun hostOnlyDomain (Ljava/lang/String;)Lokhttp3/Cookie$Builder;
public final fun httpOnly ()Lokhttp3/Cookie$Builder;
public final fun name (Ljava/lang/String;)Lokhttp3/Cookie$Builder;
public final fun partitioned ()Lokhttp3/Cookie$Builder;
public final fun path (Ljava/lang/String;)Lokhttp3/Cookie$Builder;
public final fun sameSite (Ljava/lang/String;)Lokhttp3/Cookie$Builder;
public final fun secure ()Lokhttp3/Cookie$Builder;
Expand Down
4 changes: 3 additions & 1 deletion okhttp/api/jvm/okhttp.api
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ public final class okhttp3/Cookie {
public final fun -deprecated_persistent ()Z
public final fun -deprecated_secure ()Z
public final fun -deprecated_value ()Ljava/lang/String;
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;JLjava/lang/String;Ljava/lang/String;ZZZZLjava/lang/String;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;JLjava/lang/String;Ljava/lang/String;ZZZZLjava/lang/String;ZLkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun domain ()Ljava/lang/String;
public fun equals (Ljava/lang/Object;)Z
public final fun expiresAt ()J
Expand All @@ -414,6 +414,7 @@ public final class okhttp3/Cookie {
public final fun newBuilder ()Lokhttp3/Cookie$Builder;
public static final fun parse (Lokhttp3/HttpUrl;Ljava/lang/String;)Lokhttp3/Cookie;
public static final fun parseAll (Lokhttp3/HttpUrl;Lokhttp3/Headers;)Ljava/util/List;
public final fun partitioned ()Z
public final fun path ()Ljava/lang/String;
public final fun persistent ()Z
public final fun sameSite ()Ljava/lang/String;
Expand All @@ -430,6 +431,7 @@ public final class okhttp3/Cookie$Builder {
public final fun hostOnlyDomain (Ljava/lang/String;)Lokhttp3/Cookie$Builder;
public final fun httpOnly ()Lokhttp3/Cookie$Builder;
public final fun name (Ljava/lang/String;)Lokhttp3/Cookie$Builder;
public final fun partitioned ()Lokhttp3/Cookie$Builder;
public final fun path (Ljava/lang/String;)Lokhttp3/Cookie$Builder;
public final fun sameSite (Ljava/lang/String;)Lokhttp3/Cookie$Builder;
public final fun secure ()Lokhttp3/Cookie$Builder;
Expand Down
28 changes: 27 additions & 1 deletion okhttp/src/commonJvmAndroid/kotlin/okhttp3/Cookie.kt
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,12 @@ class Cookie private constructor(
*/
@get:JvmName("sameSite")
val sameSite: String?,
/**
* Returns true if this cookie has the `Partitioned` attribute set. In web browsers this restricts
* the cookie to a separate storage jar per top-level site (CHIPS). Browsers require [secure] to
* also be true before honoring this attribute.
*/
@get:JvmName("partitioned") val partitioned: Boolean,
) {
/**
* Returns true if this cookie should be included on a request to [url]. In addition to this
Expand Down Expand Up @@ -149,7 +155,8 @@ class Cookie private constructor(
other.httpOnly == httpOnly &&
other.persistent == persistent &&
other.hostOnly == hostOnly &&
other.sameSite == sameSite
other.sameSite == sameSite &&
other.partitioned == partitioned

@IgnoreJRERequirement // As of AGP 3.4.1, D8 desugars API 24 hashCode methods.
override fun hashCode(): Int {
Expand All @@ -164,6 +171,7 @@ class Cookie private constructor(
result = 31 * result + persistent.hashCode()
result = 31 * result + hostOnly.hashCode()
result = 31 * result + sameSite.hashCode()
result = 31 * result + partitioned.hashCode()
return result
}

Expand Down Expand Up @@ -282,6 +290,10 @@ class Cookie private constructor(
append("; samesite=").append(sameSite)
}

if (partitioned) {
append("; partitioned")
}

return toString()
}
}
Expand All @@ -303,6 +315,7 @@ class Cookie private constructor(
private var persistent = false
private var hostOnly = false
private var sameSite: String? = null
private var partitioned = false

internal constructor(cookie: Cookie) : this() {
this.name = cookie.name
Expand All @@ -315,6 +328,7 @@ class Cookie private constructor(
this.persistent = cookie.persistent
this.hostOnly = cookie.hostOnly
this.sameSite = cookie.sameSite
this.partitioned = cookie.partitioned
}

fun name(name: String) =
Expand Down Expand Up @@ -383,6 +397,11 @@ class Cookie private constructor(
this.sameSite = sameSite
}

fun partitioned() =
apply {
this.partitioned = true
}

fun build(): Cookie =
Cookie(
name ?: throw NullPointerException("builder.name == null"),
Expand All @@ -395,6 +414,7 @@ class Cookie private constructor(
persistent,
hostOnly,
sameSite,
partitioned,
)
}

Expand Down Expand Up @@ -472,6 +492,7 @@ class Cookie private constructor(
var hostOnly = true
var persistent = false
var sameSite: String? = null
var partitioned = false

var pos = cookiePairEnd + 1
val limit = setCookie.length
Expand Down Expand Up @@ -530,6 +551,10 @@ class Cookie private constructor(
attributeName.equals("samesite", ignoreCase = true) -> {
sameSite = attributeValue
}

attributeName.equals("partitioned", ignoreCase = true) -> {
partitioned = true
}
}

pos = attributePairEnd + 1
Expand Down Expand Up @@ -586,6 +611,7 @@ class Cookie private constructor(
persistent,
hostOnly,
sameSite,
partitioned,
)
}

Expand Down
27 changes: 27 additions & 0 deletions okhttp/src/jvmTest/kotlin/okhttp3/CookieTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,18 @@ class CookieTest {
assertThat(parse(url, "a=b; Secure")!!.secure).isTrue()
}

@Test fun partitioned() {
assertThat(parse(url, "a=b")!!.partitioned).isFalse()
assertThat(parse(url, "a=b; Partitioned")!!.partitioned).isTrue()
}

@Test fun securePartitioned() {
val cookie = parse(url, "a=b; Secure; SameSite=None; Partitioned")
assertThat(cookie!!.secure).isTrue()
assertThat(cookie.partitioned).isTrue()
assertThat(cookie.toString()).isEqualTo("a=b; path=/; secure; samesite=None; partitioned")
}

@Test fun maxAgeTakesPrecedenceOverExpires() {
// Max-Age = 1, Expires = 2. In either order.
assertThat(parseCookie(0L, url, "a=b; Max-Age=1; Expires=Thu, 01 Jan 1970 00:00:02 GMT")!!.expiresAt)
Expand Down Expand Up @@ -434,6 +446,7 @@ class CookieTest {
assertThat(cookie.persistent).isFalse()
assertThat(cookie.hostOnly).isFalse()
assertThat(cookie.sameSite).isNull()
assertThat(cookie.partitioned).isFalse()
}

@Test fun newBuilder() {
Expand Down Expand Up @@ -565,6 +578,18 @@ class CookieTest {
assertThat(cookie.httpOnly).isTrue()
}

@Test fun builderPartitioned() {
val cookie =
Cookie
.Builder()
.name("a")
.value("b")
.hostOnlyDomain("example.com")
.partitioned()
.build()
assertThat(cookie.partitioned).isTrue()
}

@Test fun builderIpv6() {
val cookie =
Cookie
Expand Down Expand Up @@ -658,6 +683,8 @@ class CookieTest {
"a=b; Path=/c; Domain=example.com; Secure; HttpOnly; SameSite=Lax",
"a=b; Path=/c; Domain=example.com; Max-Age=5; HttpOnly; SameSite=Lax",
"a=b; Path=/c; Domain=example.com; Max-Age=5; Secure; ; SameSite=Lax",
"a=b; Path=/c; Domain=example.com; Max-Age=5; Secure; HttpOnly; Partitioned",
"a=b; Path=/c; Domain=example.com; Max-Age=5; Secure; HttpOnly; SameSite=None; Partitioned",
)
for (stringA in cookieStrings) {
val cookieA = parseCookie(0, url, stringA!!)
Expand Down
2 changes: 2 additions & 0 deletions okhttp/src/jvmTest/kotlin/okhttp3/KotlinSourceModernTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,7 @@ class KotlinSourceModernTest {
val path: String = cookie.path
val httpOnly: Boolean = cookie.httpOnly
val secure: Boolean = cookie.secure
val partitioned: Boolean = cookie.partitioned
val matches: Boolean = cookie.matches("".toHttpUrl())
val parsedCookie: Cookie? = Cookie.parse("".toHttpUrl(), "")
val cookies: List<Cookie> = Cookie.parseAll("".toHttpUrl(), headersOf())
Expand All @@ -360,6 +361,7 @@ class KotlinSourceModernTest {
builder = builder.secure()
builder = builder.httpOnly()
builder = builder.sameSite("None")
builder = builder.partitioned()
val cookie: Cookie = builder.build()
}

Expand Down