mirror of
https://github.com/square/okhttp.git
synced 2026-01-14 07:22:20 +03:00
Implement date formatting and parsing as extensions (#5134)
This commit is contained in:
committed by
Yuri Schimke
parent
0b12ed2bb0
commit
96eb1111eb
@@ -18,7 +18,8 @@ package okhttp3
|
||||
import okhttp3.internal.UTC
|
||||
import okhttp3.internal.canParseAsIpAddress
|
||||
import okhttp3.internal.delimiterOffset
|
||||
import okhttp3.internal.http.HttpDate
|
||||
import okhttp3.internal.http.MAX_DATE
|
||||
import okhttp3.internal.http.toHttpDateString
|
||||
import okhttp3.internal.indexOfControlOrNonAscii
|
||||
import okhttp3.internal.publicsuffix.PublicSuffixDatabase
|
||||
import okhttp3.internal.toCanonicalHost
|
||||
@@ -217,7 +218,7 @@ class Cookie private constructor(
|
||||
if (expiresAt == Long.MIN_VALUE) {
|
||||
append("; max-age=0")
|
||||
} else {
|
||||
append("; expires=").append(HttpDate.format(Date(expiresAt)))
|
||||
append("; expires=").append(Date(expiresAt).toHttpDateString())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -250,7 +251,7 @@ class Cookie private constructor(
|
||||
class Builder {
|
||||
private var name: String? = null
|
||||
private var value: String? = null
|
||||
private var expiresAt = HttpDate.MAX_DATE
|
||||
private var expiresAt = MAX_DATE
|
||||
private var domain: String? = null
|
||||
private var path = "/"
|
||||
private var secure = false
|
||||
@@ -271,7 +272,7 @@ class Cookie private constructor(
|
||||
fun expiresAt(expiresAt: Long) = apply {
|
||||
var expiresAt = expiresAt
|
||||
if (expiresAt <= 0L) expiresAt = Long.MIN_VALUE
|
||||
if (expiresAt > HttpDate.MAX_DATE) expiresAt = HttpDate.MAX_DATE
|
||||
if (expiresAt > MAX_DATE) expiresAt = MAX_DATE
|
||||
this.expiresAt = expiresAt
|
||||
this.persistent = true
|
||||
}
|
||||
@@ -374,7 +375,7 @@ class Cookie private constructor(
|
||||
val cookieValue = setCookie.trimSubstring(pairEqualsSign + 1, cookiePairEnd)
|
||||
if (cookieValue.indexOfControlOrNonAscii() != -1) return null
|
||||
|
||||
var expiresAt = HttpDate.MAX_DATE
|
||||
var expiresAt = MAX_DATE
|
||||
var deltaSeconds = -1L
|
||||
var domain: String? = null
|
||||
var path: String? = null
|
||||
@@ -446,8 +447,8 @@ class Cookie private constructor(
|
||||
Long.MAX_VALUE
|
||||
}
|
||||
expiresAt = currentTimeMillis + deltaMilliseconds
|
||||
if (expiresAt < currentTimeMillis || expiresAt > HttpDate.MAX_DATE) {
|
||||
expiresAt = HttpDate.MAX_DATE // Handle overflow & limit the date range.
|
||||
if (expiresAt < currentTimeMillis || expiresAt > MAX_DATE) {
|
||||
expiresAt = MAX_DATE // Handle overflow & limit the date range.
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,8 @@ package okhttp3
|
||||
|
||||
import okhttp3.Headers.Builder
|
||||
import okhttp3.internal.format
|
||||
import okhttp3.internal.http.HttpDate
|
||||
import okhttp3.internal.http.toHttpDateOrNull
|
||||
import okhttp3.internal.http.toHttpDateString
|
||||
import org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement
|
||||
import java.time.Instant
|
||||
import java.util.ArrayList
|
||||
@@ -56,10 +57,7 @@ class Headers private constructor(
|
||||
* Returns the last value corresponding to the specified field parsed as an HTTP date, or null if
|
||||
* either the field is absent or cannot be parsed as a date.
|
||||
*/
|
||||
fun getDate(name: String): Date? {
|
||||
val value = get(name)
|
||||
return if (value != null) HttpDate.parse(value) else null
|
||||
}
|
||||
fun getDate(name: String): Date? = get(name)?.toHttpDateOrNull()
|
||||
|
||||
/**
|
||||
* Returns the last value corresponding to the specified field parsed as an HTTP date, or null if
|
||||
@@ -271,7 +269,7 @@ class Headers private constructor(
|
||||
* value.
|
||||
*/
|
||||
fun add(name: String, value: Date) = apply {
|
||||
add(name, HttpDate.format(value))
|
||||
add(name, value.toHttpDateString())
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -288,7 +286,7 @@ class Headers private constructor(
|
||||
* found, the existing values are replaced.
|
||||
*/
|
||||
operator fun set(name: String, value: Date) = apply {
|
||||
set(name, HttpDate.format(value))
|
||||
set(name, value.toHttpDateString())
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -17,8 +17,8 @@ package okhttp3.internal.cache
|
||||
|
||||
import okhttp3.Request
|
||||
import okhttp3.Response
|
||||
import okhttp3.internal.http.HttpDate
|
||||
import okhttp3.internal.http.StatusLine
|
||||
import okhttp3.internal.http.toHttpDateOrNull
|
||||
import okhttp3.internal.toNonNegativeInt
|
||||
import java.net.HttpURLConnection.HTTP_BAD_METHOD
|
||||
import java.net.HttpURLConnection.HTTP_GONE
|
||||
@@ -104,14 +104,14 @@ class CacheStrategy internal constructor(
|
||||
val value = headers.value(i)
|
||||
when {
|
||||
fieldName.equals("Date", ignoreCase = true) -> {
|
||||
servedDate = HttpDate.parse(value)
|
||||
servedDate = value.toHttpDateOrNull()
|
||||
servedDateString = value
|
||||
}
|
||||
fieldName.equals("Expires", ignoreCase = true) -> {
|
||||
expires = HttpDate.parse(value)
|
||||
expires = value.toHttpDateOrNull()
|
||||
}
|
||||
fieldName.equals("Last-Modified", ignoreCase = true) -> {
|
||||
lastModified = HttpDate.parse(value)
|
||||
lastModified = value.toHttpDateOrNull()
|
||||
lastModifiedString = value
|
||||
}
|
||||
fieldName.equals("ETag", ignoreCase = true) -> {
|
||||
|
||||
@@ -1,114 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package okhttp3.internal.http
|
||||
|
||||
import okhttp3.internal.UTC
|
||||
import java.text.DateFormat
|
||||
import java.text.ParsePosition
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Date
|
||||
import java.util.Locale
|
||||
|
||||
/**
|
||||
* Best-effort parser for HTTP dates.
|
||||
*/
|
||||
object HttpDate {
|
||||
/** The last four-digit year: "Fri, 31 Dec 9999 23:59:59 GMT". */
|
||||
const val MAX_DATE = 253402300799999L
|
||||
|
||||
/**
|
||||
* Most websites serve cookies in the blessed format. Eagerly create the parser to ensure such
|
||||
* cookies are on the fast path.
|
||||
*/
|
||||
private val STANDARD_DATE_FORMAT = object : ThreadLocal<DateFormat>() {
|
||||
override fun initialValue(): DateFormat {
|
||||
// Date format specified by RFC 7231 section 7.1.1.1.
|
||||
return SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss 'GMT'", Locale.US).apply {
|
||||
isLenient = false
|
||||
timeZone = UTC
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** If we fail to parse a date in a non-standard format, try each of these formats in sequence. */
|
||||
private val BROWSER_COMPATIBLE_DATE_FORMAT_STRINGS = arrayOf(
|
||||
// HTTP formats required by RFC2616 but with any timezone.
|
||||
"EEE, dd MMM yyyy HH:mm:ss zzz", // RFC 822, updated by RFC 1123 with any TZ
|
||||
"EEEE, dd-MMM-yy HH:mm:ss zzz", // RFC 850, obsoleted by RFC 1036 with any TZ.
|
||||
"EEE MMM d HH:mm:ss yyyy", // ANSI C's asctime() format
|
||||
// Alternative formats.
|
||||
"EEE, dd-MMM-yyyy HH:mm:ss z",
|
||||
"EEE, dd-MMM-yyyy HH-mm-ss z",
|
||||
"EEE, dd MMM yy HH:mm:ss z",
|
||||
"EEE dd-MMM-yyyy HH:mm:ss z",
|
||||
"EEE dd MMM yyyy HH:mm:ss z",
|
||||
"EEE dd-MMM-yyyy HH-mm-ss z",
|
||||
"EEE dd-MMM-yy HH:mm:ss z",
|
||||
"EEE dd MMM yy HH:mm:ss z",
|
||||
"EEE,dd-MMM-yy HH:mm:ss z",
|
||||
"EEE,dd-MMM-yyyy HH:mm:ss z",
|
||||
"EEE, dd-MM-yyyy HH:mm:ss z",
|
||||
|
||||
/* RI bug 6641315 claims a cookie of this format was once served by www.yahoo.com */
|
||||
"EEE MMM d yyyy HH:mm:ss z"
|
||||
)
|
||||
|
||||
private val BROWSER_COMPATIBLE_DATE_FORMATS = arrayOfNulls<DateFormat>(BROWSER_COMPATIBLE_DATE_FORMAT_STRINGS.size)
|
||||
|
||||
/** Returns the date for [value]. Returns null if the value couldn't be parsed. */
|
||||
fun parse(value: String): Date? {
|
||||
if (value.isEmpty()) {
|
||||
return null
|
||||
}
|
||||
|
||||
val position = ParsePosition(0)
|
||||
var result = STANDARD_DATE_FORMAT.get().parse(value, position)
|
||||
if (position.index == value.length) {
|
||||
// STANDARD_DATE_FORMAT must match exactly; all text must be consumed, e.g. no ignored
|
||||
// non-standard trailing "+01:00". Those cases are covered below.
|
||||
return result
|
||||
}
|
||||
synchronized(BROWSER_COMPATIBLE_DATE_FORMAT_STRINGS) {
|
||||
for (i in 0 until BROWSER_COMPATIBLE_DATE_FORMAT_STRINGS.size) {
|
||||
var format: DateFormat? = BROWSER_COMPATIBLE_DATE_FORMATS[i]
|
||||
if (format == null) {
|
||||
format = SimpleDateFormat(BROWSER_COMPATIBLE_DATE_FORMAT_STRINGS[i], Locale.US).apply {
|
||||
// Set the timezone to use when interpreting formats that don't have a timezone. GMT is
|
||||
// specified by RFC 7231.
|
||||
timeZone = UTC
|
||||
}
|
||||
BROWSER_COMPATIBLE_DATE_FORMATS[i] = format
|
||||
}
|
||||
position.index = 0
|
||||
result = format.parse(value, position)
|
||||
if (position.index != 0) {
|
||||
// Something was parsed. It's possible the entire string was not consumed but we ignore
|
||||
// that. If any of the BROWSER_COMPATIBLE_DATE_FORMAT_STRINGS ended in "'GMT'" we'd have
|
||||
// to also check that position.getIndex() == value.length() otherwise parsing might have
|
||||
// terminated early, ignoring things like "+01:00". Leaving this as != 0 means that any
|
||||
// trailing junk is ignored.
|
||||
return result
|
||||
}
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
/** Returns the string for [value]. */
|
||||
fun format(value: Date): String {
|
||||
return STANDARD_DATE_FORMAT.get().format(value)
|
||||
}
|
||||
}
|
||||
106
okhttp/src/main/java/okhttp3/internal/http/dates.kt
Normal file
106
okhttp/src/main/java/okhttp3/internal/http/dates.kt
Normal file
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package okhttp3.internal.http
|
||||
|
||||
import okhttp3.internal.UTC
|
||||
import java.text.DateFormat
|
||||
import java.text.ParsePosition
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Date
|
||||
import java.util.Locale
|
||||
|
||||
/** The last four-digit year: "Fri, 31 Dec 9999 23:59:59 GMT". */
|
||||
internal const val MAX_DATE = 253402300799999L
|
||||
|
||||
/**
|
||||
* Most websites serve cookies in the blessed format. Eagerly create the parser to ensure such
|
||||
* cookies are on the fast path.
|
||||
*/
|
||||
private val STANDARD_DATE_FORMAT = object : ThreadLocal<DateFormat>() {
|
||||
override fun initialValue(): DateFormat {
|
||||
// Date format specified by RFC 7231 section 7.1.1.1.
|
||||
return SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss 'GMT'", Locale.US).apply {
|
||||
isLenient = false
|
||||
timeZone = UTC
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** If we fail to parse a date in a non-standard format, try each of these formats in sequence. */
|
||||
private val BROWSER_COMPATIBLE_DATE_FORMAT_STRINGS = arrayOf(
|
||||
// HTTP formats required by RFC2616 but with any timezone.
|
||||
"EEE, dd MMM yyyy HH:mm:ss zzz", // RFC 822, updated by RFC 1123 with any TZ
|
||||
"EEEE, dd-MMM-yy HH:mm:ss zzz", // RFC 850, obsoleted by RFC 1036 with any TZ.
|
||||
"EEE MMM d HH:mm:ss yyyy", // ANSI C's asctime() format
|
||||
// Alternative formats.
|
||||
"EEE, dd-MMM-yyyy HH:mm:ss z",
|
||||
"EEE, dd-MMM-yyyy HH-mm-ss z",
|
||||
"EEE, dd MMM yy HH:mm:ss z",
|
||||
"EEE dd-MMM-yyyy HH:mm:ss z",
|
||||
"EEE dd MMM yyyy HH:mm:ss z",
|
||||
"EEE dd-MMM-yyyy HH-mm-ss z",
|
||||
"EEE dd-MMM-yy HH:mm:ss z",
|
||||
"EEE dd MMM yy HH:mm:ss z",
|
||||
"EEE,dd-MMM-yy HH:mm:ss z",
|
||||
"EEE,dd-MMM-yyyy HH:mm:ss z",
|
||||
"EEE, dd-MM-yyyy HH:mm:ss z",
|
||||
|
||||
/* RI bug 6641315 claims a cookie of this format was once served by www.yahoo.com */
|
||||
"EEE MMM d yyyy HH:mm:ss z"
|
||||
)
|
||||
|
||||
private val BROWSER_COMPATIBLE_DATE_FORMATS =
|
||||
arrayOfNulls<DateFormat>(BROWSER_COMPATIBLE_DATE_FORMAT_STRINGS.size)
|
||||
|
||||
/** Returns the date for this string, or null if the value couldn't be parsed. */
|
||||
internal fun String.toHttpDateOrNull(): Date? {
|
||||
if (isEmpty()) return null
|
||||
|
||||
val position = ParsePosition(0)
|
||||
var result = STANDARD_DATE_FORMAT.get().parse(this, position)
|
||||
if (position.index == length) {
|
||||
// STANDARD_DATE_FORMAT must match exactly; all text must be consumed, e.g. no ignored
|
||||
// non-standard trailing "+01:00". Those cases are covered below.
|
||||
return result
|
||||
}
|
||||
synchronized(BROWSER_COMPATIBLE_DATE_FORMAT_STRINGS) {
|
||||
for (i in 0 until BROWSER_COMPATIBLE_DATE_FORMAT_STRINGS.size) {
|
||||
var format: DateFormat? = BROWSER_COMPATIBLE_DATE_FORMATS[i]
|
||||
if (format == null) {
|
||||
format = SimpleDateFormat(BROWSER_COMPATIBLE_DATE_FORMAT_STRINGS[i], Locale.US).apply {
|
||||
// Set the timezone to use when interpreting formats that don't have a timezone. GMT is
|
||||
// specified by RFC 7231.
|
||||
timeZone = UTC
|
||||
}
|
||||
BROWSER_COMPATIBLE_DATE_FORMATS[i] = format
|
||||
}
|
||||
position.index = 0
|
||||
result = format.parse(this, position)
|
||||
if (position.index != 0) {
|
||||
// Something was parsed. It's possible the entire string was not consumed but we ignore
|
||||
// that. If any of the BROWSER_COMPATIBLE_DATE_FORMAT_STRINGS ended in "'GMT'" we'd have
|
||||
// to also check that position.getIndex() == value.length() otherwise parsing might have
|
||||
// terminated early, ignoring things like "+01:00". Leaving this as != 0 means that any
|
||||
// trailing junk is ignored.
|
||||
return result
|
||||
}
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
/** Returns the string for this date. */
|
||||
internal fun Date.toHttpDateString(): String = STANDARD_DATE_FORMAT.get().format(this)
|
||||
@@ -21,11 +21,11 @@ import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import okhttp3.internal.Util;
|
||||
import okhttp3.internal.http.HttpDate;
|
||||
import org.junit.Test;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static okhttp3.internal.Internal.parseCookie;
|
||||
import static okhttp3.internal.http.DatesKt.MAX_DATE;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
@@ -93,32 +93,35 @@ public final class CookieTest {
|
||||
}
|
||||
|
||||
@Test public void maxAge() throws Exception {
|
||||
assertThat(parseCookie(50000L, url, "a=b; Max-Age=1").expiresAt()).isEqualTo(51000L);
|
||||
assertThat(parseCookie(50000L, url, "a=b; Max-Age=9223372036854724").expiresAt()).isEqualTo(
|
||||
HttpDate.MAX_DATE);
|
||||
assertThat(parseCookie(50000L, url, "a=b; Max-Age=9223372036854725").expiresAt()).isEqualTo(
|
||||
HttpDate.MAX_DATE);
|
||||
assertThat(parseCookie(50000L, url, "a=b; Max-Age=9223372036854726").expiresAt()).isEqualTo(
|
||||
HttpDate.MAX_DATE);
|
||||
assertThat(parseCookie(9223372036854773807L, url, "a=b; Max-Age=1").expiresAt()).isEqualTo(
|
||||
HttpDate.MAX_DATE);
|
||||
assertThat(parseCookie(9223372036854773807L, url, "a=b; Max-Age=2").expiresAt()).isEqualTo(
|
||||
HttpDate.MAX_DATE);
|
||||
assertThat(parseCookie(9223372036854773807L, url, "a=b; Max-Age=3").expiresAt()).isEqualTo(
|
||||
HttpDate.MAX_DATE);
|
||||
assertThat(parseCookie(50000L, url, "a=b; Max-Age=10000000000000000000").expiresAt()).isEqualTo(
|
||||
HttpDate.MAX_DATE);
|
||||
assertThat(parseCookie(50000L, url, "a=b; Max-Age=1").expiresAt())
|
||||
.isEqualTo(51000L);
|
||||
assertThat(parseCookie(50000L, url, "a=b; Max-Age=9223372036854724").expiresAt())
|
||||
.isEqualTo(MAX_DATE);
|
||||
assertThat(parseCookie(50000L, url, "a=b; Max-Age=9223372036854725").expiresAt())
|
||||
.isEqualTo(MAX_DATE);
|
||||
assertThat(parseCookie(50000L, url, "a=b; Max-Age=9223372036854726").expiresAt())
|
||||
.isEqualTo(MAX_DATE);
|
||||
assertThat(parseCookie(9223372036854773807L, url, "a=b; Max-Age=1").expiresAt())
|
||||
.isEqualTo(MAX_DATE);
|
||||
assertThat(parseCookie(9223372036854773807L, url, "a=b; Max-Age=2").expiresAt())
|
||||
.isEqualTo(MAX_DATE);
|
||||
assertThat(parseCookie(9223372036854773807L, url, "a=b; Max-Age=3").expiresAt())
|
||||
.isEqualTo(MAX_DATE);
|
||||
assertThat(parseCookie(50000L, url, "a=b; Max-Age=10000000000000000000").expiresAt())
|
||||
.isEqualTo(MAX_DATE);
|
||||
}
|
||||
|
||||
@Test public void maxAgeNonPositive() throws Exception {
|
||||
assertThat(parseCookie(50000L, url, "a=b; Max-Age=-1").expiresAt()).isEqualTo(Long.MIN_VALUE);
|
||||
assertThat(parseCookie(50000L, url, "a=b; Max-Age=0").expiresAt()).isEqualTo(Long.MIN_VALUE);
|
||||
assertThat(parseCookie(50000L, url, "a=b; Max-Age=-9223372036854775808").expiresAt()).isEqualTo(
|
||||
Long.MIN_VALUE);
|
||||
assertThat(parseCookie(50000L, url, "a=b; Max-Age=-9223372036854775809").expiresAt()).isEqualTo(
|
||||
Long.MIN_VALUE);
|
||||
assertThat(parseCookie(50000L, url, "a=b; Max-Age=-10000000000000000000").expiresAt()).isEqualTo(
|
||||
Long.MIN_VALUE);
|
||||
assertThat(parseCookie(50000L, url, "a=b; Max-Age=-1").expiresAt())
|
||||
.isEqualTo(Long.MIN_VALUE);
|
||||
assertThat(parseCookie(50000L, url, "a=b; Max-Age=0").expiresAt())
|
||||
.isEqualTo(Long.MIN_VALUE);
|
||||
assertThat(parseCookie(50000L, url, "a=b; Max-Age=-9223372036854775808").expiresAt())
|
||||
.isEqualTo(Long.MIN_VALUE);
|
||||
assertThat(parseCookie(50000L, url, "a=b; Max-Age=-9223372036854775809").expiresAt())
|
||||
.isEqualTo(Long.MIN_VALUE);
|
||||
assertThat(parseCookie(50000L, url, "a=b; Max-Age=-10000000000000000000").expiresAt())
|
||||
.isEqualTo(Long.MIN_VALUE);
|
||||
}
|
||||
|
||||
@Test public void domainAndPath() throws Exception {
|
||||
@@ -139,76 +142,75 @@ public final class CookieTest {
|
||||
}
|
||||
|
||||
@Test public void expiresDate() throws Exception {
|
||||
assertThat(new Date(
|
||||
Cookie.parse(url, "a=b; Expires=Thu, 01 Jan 1970 00:00:00 GMT").expiresAt())).isEqualTo(
|
||||
date("1970-01-01T00:00:00.000+0000"));
|
||||
assertThat(new Date(
|
||||
Cookie.parse(url, "a=b; Expires=Wed, 09 Jun 2021 10:18:14 GMT").expiresAt())).isEqualTo(
|
||||
date("2021-06-09T10:18:14.000+0000"));
|
||||
assertThat(new Date(
|
||||
Cookie.parse(url, "a=b; Expires=Sun, 06 Nov 1994 08:49:37 GMT").expiresAt())).isEqualTo(
|
||||
date("1994-11-06T08:49:37.000+0000"));
|
||||
assertThat(new Date(Cookie.parse(url, "a=b; Expires=Thu, 01 Jan 1970 00:00:00 GMT")
|
||||
.expiresAt())).isEqualTo(date("1970-01-01T00:00:00.000+0000"));
|
||||
assertThat(new Date(Cookie.parse(url, "a=b; Expires=Wed, 09 Jun 2021 10:18:14 GMT")
|
||||
.expiresAt())).isEqualTo(date("2021-06-09T10:18:14.000+0000"));
|
||||
assertThat(new Date(Cookie.parse(url, "a=b; Expires=Sun, 06 Nov 1994 08:49:37 GMT")
|
||||
.expiresAt())).isEqualTo(date("1994-11-06T08:49:37.000+0000"));
|
||||
}
|
||||
|
||||
@Test public void awkwardDates() throws Exception {
|
||||
assertThat(Cookie.parse(url, "a=b; Expires=Thu, 01 Jan 70 00:00:00 GMT").expiresAt()).isEqualTo(
|
||||
0L);
|
||||
assertThat(Cookie.parse(url, "a=b; Expires=Thu, 01 January 1970 00:00:00 GMT").expiresAt()).isEqualTo(
|
||||
0L);
|
||||
assertThat(Cookie.parse(url, "a=b; Expires=Thu, 01 Janucember 1970 00:00:00 GMT").expiresAt()).isEqualTo(
|
||||
0L);
|
||||
assertThat(Cookie.parse(url, "a=b; Expires=Thu, 1 Jan 1970 00:00:00 GMT").expiresAt()).isEqualTo(
|
||||
0L);
|
||||
assertThat(Cookie.parse(url, "a=b; Expires=Thu, 01 Jan 1970 0:00:00 GMT").expiresAt()).isEqualTo(
|
||||
0L);
|
||||
assertThat(Cookie.parse(url, "a=b; Expires=Thu, 01 Jan 1970 00:0:00 GMT").expiresAt()).isEqualTo(
|
||||
0L);
|
||||
assertThat(Cookie.parse(url, "a=b; Expires=Thu, 01 Jan 1970 00:00:0 GMT").expiresAt()).isEqualTo(
|
||||
0L);
|
||||
assertThat(Cookie.parse(url, "a=b; Expires=00:00:00 Thu, 01 Jan 1970 GMT").expiresAt()).isEqualTo(
|
||||
0L);
|
||||
assertThat(Cookie.parse(url, "a=b; Expires=00:00:00 1970 Jan 01").expiresAt()).isEqualTo(0L);
|
||||
assertThat(Cookie.parse(url, "a=b; Expires=00:00:00 1970 Jan 1").expiresAt()).isEqualTo(0L);
|
||||
assertThat(Cookie.parse(url, "a=b; Expires=Thu, 01 Jan 70 00:00:00 GMT").expiresAt())
|
||||
.isEqualTo(0L);
|
||||
assertThat(Cookie.parse(url, "a=b; Expires=Thu, 01 January 1970 00:00:00 GMT").expiresAt())
|
||||
.isEqualTo(0L);
|
||||
assertThat(Cookie.parse(url, "a=b; Expires=Thu, 01 Janucember 1970 00:00:00 GMT").expiresAt())
|
||||
.isEqualTo(0L);
|
||||
assertThat(Cookie.parse(url, "a=b; Expires=Thu, 1 Jan 1970 00:00:00 GMT").expiresAt())
|
||||
.isEqualTo(0L);
|
||||
assertThat(Cookie.parse(url, "a=b; Expires=Thu, 01 Jan 1970 0:00:00 GMT").expiresAt())
|
||||
.isEqualTo(0L);
|
||||
assertThat(Cookie.parse(url, "a=b; Expires=Thu, 01 Jan 1970 00:0:00 GMT").expiresAt())
|
||||
.isEqualTo(0L);
|
||||
assertThat(Cookie.parse(url, "a=b; Expires=Thu, 01 Jan 1970 00:00:0 GMT").expiresAt())
|
||||
.isEqualTo(0L);
|
||||
assertThat(Cookie.parse(url, "a=b; Expires=00:00:00 Thu, 01 Jan 1970 GMT").expiresAt())
|
||||
.isEqualTo(0L);
|
||||
assertThat(Cookie.parse(url, "a=b; Expires=00:00:00 1970 Jan 01").expiresAt())
|
||||
.isEqualTo(0L);
|
||||
assertThat(Cookie.parse(url, "a=b; Expires=00:00:00 1970 Jan 1").expiresAt())
|
||||
.isEqualTo(0L);
|
||||
}
|
||||
|
||||
@Test public void invalidYear() throws Exception {
|
||||
assertThat(Cookie.parse(url, "a=b; Expires=Thu, 01 Jan 1600 00:00:00 GMT").expiresAt()).isEqualTo(
|
||||
HttpDate.MAX_DATE);
|
||||
assertThat(Cookie.parse(url, "a=b; Expires=Thu, 01 Jan 19999 00:00:00 GMT").expiresAt()).isEqualTo(
|
||||
HttpDate.MAX_DATE);
|
||||
assertThat(Cookie.parse(url, "a=b; Expires=Thu, 01 Jan 00:00:00 GMT").expiresAt()).isEqualTo(
|
||||
HttpDate.MAX_DATE);
|
||||
assertThat(Cookie.parse(url, "a=b; Expires=Thu, 01 Jan 1600 00:00:00 GMT").expiresAt())
|
||||
.isEqualTo(MAX_DATE);
|
||||
assertThat(Cookie.parse(url, "a=b; Expires=Thu, 01 Jan 19999 00:00:00 GMT").expiresAt())
|
||||
.isEqualTo(MAX_DATE);
|
||||
assertThat(Cookie.parse(url, "a=b; Expires=Thu, 01 Jan 00:00:00 GMT").expiresAt())
|
||||
.isEqualTo(MAX_DATE);
|
||||
}
|
||||
|
||||
@Test public void invalidMonth() throws Exception {
|
||||
assertThat(Cookie.parse(url, "a=b; Expires=Thu, 01 Foo 1970 00:00:00 GMT").expiresAt()).isEqualTo(
|
||||
HttpDate.MAX_DATE);
|
||||
assertThat(Cookie.parse(url, "a=b; Expires=Thu, 01 Foocember 1970 00:00:00 GMT").expiresAt()).isEqualTo(
|
||||
HttpDate.MAX_DATE);
|
||||
assertThat(Cookie.parse(url, "a=b; Expires=Thu, 01 1970 00:00:00 GMT").expiresAt()).isEqualTo(
|
||||
HttpDate.MAX_DATE);
|
||||
assertThat(Cookie.parse(url, "a=b; Expires=Thu, 01 Foo 1970 00:00:00 GMT").expiresAt())
|
||||
.isEqualTo(MAX_DATE);
|
||||
assertThat(Cookie.parse(url, "a=b; Expires=Thu, 01 Foocember 1970 00:00:00 GMT").expiresAt())
|
||||
.isEqualTo(MAX_DATE);
|
||||
assertThat(Cookie.parse(url, "a=b; Expires=Thu, 01 1970 00:00:00 GMT").expiresAt())
|
||||
.isEqualTo(MAX_DATE);
|
||||
}
|
||||
|
||||
@Test public void invalidDayOfMonth() throws Exception {
|
||||
assertThat(Cookie.parse(url, "a=b; Expires=Thu, 32 Jan 1970 00:00:00 GMT").expiresAt()).isEqualTo(
|
||||
HttpDate.MAX_DATE);
|
||||
assertThat(Cookie.parse(url, "a=b; Expires=Thu, Jan 1970 00:00:00 GMT").expiresAt()).isEqualTo(
|
||||
HttpDate.MAX_DATE);
|
||||
assertThat(Cookie.parse(url, "a=b; Expires=Thu, 32 Jan 1970 00:00:00 GMT").expiresAt())
|
||||
.isEqualTo(MAX_DATE);
|
||||
assertThat(Cookie.parse(url, "a=b; Expires=Thu, Jan 1970 00:00:00 GMT").expiresAt())
|
||||
.isEqualTo(MAX_DATE);
|
||||
}
|
||||
|
||||
@Test public void invalidHour() throws Exception {
|
||||
assertThat(Cookie.parse(url, "a=b; Expires=Thu, 01 Jan 1970 24:00:00 GMT").expiresAt()).isEqualTo(
|
||||
HttpDate.MAX_DATE);
|
||||
assertThat(Cookie.parse(url, "a=b; Expires=Thu, 01 Jan 1970 24:00:00 GMT").expiresAt())
|
||||
.isEqualTo(MAX_DATE);
|
||||
}
|
||||
|
||||
@Test public void invalidMinute() throws Exception {
|
||||
assertThat(Cookie.parse(url, "a=b; Expires=Thu, 01 Jan 1970 00:60:00 GMT").expiresAt()).isEqualTo(
|
||||
HttpDate.MAX_DATE);
|
||||
assertThat(Cookie.parse(url, "a=b; Expires=Thu, 01 Jan 1970 00:60:00 GMT").expiresAt())
|
||||
.isEqualTo(MAX_DATE);
|
||||
}
|
||||
|
||||
@Test public void invalidSecond() throws Exception {
|
||||
assertThat(Cookie.parse(url, "a=b; Expires=Thu, 01 Jan 1970 00:00:60 GMT").expiresAt()).isEqualTo(
|
||||
HttpDate.MAX_DATE);
|
||||
assertThat(Cookie.parse(url, "a=b; Expires=Thu, 01 Jan 1970 00:00:60 GMT").expiresAt())
|
||||
.isEqualTo(MAX_DATE);
|
||||
}
|
||||
|
||||
@Test public void domainMatches() throws Exception {
|
||||
@@ -389,7 +391,8 @@ public final class CookieTest {
|
||||
@Test public void maxAgeOrExpiresMakesCookiePersistent() throws Exception {
|
||||
assertThat(parseCookie(0L, url, "a=b").persistent()).isFalse();
|
||||
assertThat(parseCookie(0L, url, "a=b; Max-Age=1").persistent()).isTrue();
|
||||
assertThat(parseCookie(0L, url, "a=b; Expires=Thu, 01 Jan 1970 00:00:01 GMT").persistent()).isTrue();
|
||||
assertThat(parseCookie(0L, url, "a=b; Expires=Thu, 01 Jan 1970 00:00:01 GMT").persistent())
|
||||
.isTrue();
|
||||
}
|
||||
|
||||
@Test public void parseAll() throws Exception {
|
||||
@@ -411,7 +414,7 @@ public final class CookieTest {
|
||||
.build();
|
||||
assertThat(cookie.name()).isEqualTo("a");
|
||||
assertThat(cookie.value()).isEqualTo("b");
|
||||
assertThat(cookie.expiresAt()).isEqualTo(HttpDate.MAX_DATE);
|
||||
assertThat(cookie.expiresAt()).isEqualTo(MAX_DATE);
|
||||
assertThat(cookie.domain()).isEqualTo("example.com");
|
||||
assertThat(cookie.path()).isEqualTo("/");
|
||||
assertThat(cookie.secure()).isFalse();
|
||||
|
||||
@@ -44,53 +44,53 @@ class HttpDateTest {
|
||||
@Test @Throws(Exception::class)
|
||||
fun parseStandardFormats() {
|
||||
// RFC 822, updated by RFC 1123 with GMT.
|
||||
assertThat(HttpDate.parse("Thu, 01 Jan 1970 00:00:00 GMT")!!.time).isEqualTo(0L)
|
||||
assertThat(HttpDate.parse("Fri, 06 Jun 2014 12:30:30 GMT")!!.time).isEqualTo(1402057830000L)
|
||||
assertThat("Thu, 01 Jan 1970 00:00:00 GMT".toHttpDateOrNull()!!.time).isEqualTo(0L)
|
||||
assertThat("Fri, 06 Jun 2014 12:30:30 GMT".toHttpDateOrNull()!!.time).isEqualTo(1402057830000L)
|
||||
|
||||
// RFC 850, obsoleted by RFC 1036 with GMT.
|
||||
assertThat(HttpDate.parse("Thursday, 01-Jan-70 00:00:00 GMT")!!.time).isEqualTo(0L)
|
||||
assertThat(HttpDate.parse("Friday, 06-Jun-14 12:30:30 GMT")!!.time).isEqualTo(1402057830000L)
|
||||
assertThat("Thursday, 01-Jan-70 00:00:00 GMT".toHttpDateOrNull()!!.time).isEqualTo(0L)
|
||||
assertThat("Friday, 06-Jun-14 12:30:30 GMT".toHttpDateOrNull()!!.time).isEqualTo(1402057830000L)
|
||||
|
||||
// ANSI C's asctime(): should use GMT, not platform default.
|
||||
assertThat(HttpDate.parse("Thu Jan 1 00:00:00 1970")!!.time).isEqualTo(0L)
|
||||
assertThat(HttpDate.parse("Fri Jun 6 12:30:30 2014")!!.time).isEqualTo(1402057830000L)
|
||||
assertThat("Thu Jan 1 00:00:00 1970".toHttpDateOrNull()!!.time).isEqualTo(0L)
|
||||
assertThat("Fri Jun 6 12:30:30 2014".toHttpDateOrNull()!!.time).isEqualTo(1402057830000L)
|
||||
}
|
||||
|
||||
@Test @Throws(Exception::class)
|
||||
fun format() {
|
||||
assertThat(HttpDate.format(Date(0L))).isEqualTo("Thu, 01 Jan 1970 00:00:00 GMT")
|
||||
assertThat(HttpDate.format(Date(1402057830000L))).isEqualTo("Fri, 06 Jun 2014 12:30:30 GMT")
|
||||
assertThat(Date(0L).toHttpDateString()).isEqualTo("Thu, 01 Jan 1970 00:00:00 GMT")
|
||||
assertThat(Date(1402057830000L).toHttpDateString()).isEqualTo("Fri, 06 Jun 2014 12:30:30 GMT")
|
||||
}
|
||||
|
||||
@Test @Throws(Exception::class)
|
||||
fun parseNonStandardStrings() {
|
||||
// RFC 822, updated by RFC 1123 with any TZ
|
||||
assertThat(HttpDate.parse("Thu, 01 Jan 1970 00:00:00 GMT-01:00")!!.time).isEqualTo(3600000L)
|
||||
assertThat(HttpDate.parse("Thu, 01 Jan 1970 00:00:00 PST")!!.time).isEqualTo(28800000L)
|
||||
assertThat("Thu, 01 Jan 1970 00:00:00 GMT-01:00".toHttpDateOrNull()!!.time).isEqualTo(3600000L)
|
||||
assertThat("Thu, 01 Jan 1970 00:00:00 PST".toHttpDateOrNull()!!.time).isEqualTo(28800000L)
|
||||
// Ignore trailing junk
|
||||
assertThat(HttpDate.parse("Thu, 01 Jan 1970 00:00:00 GMT JUNK")!!.time).isEqualTo(0L)
|
||||
assertThat("Thu, 01 Jan 1970 00:00:00 GMT JUNK".toHttpDateOrNull()!!.time).isEqualTo(0L)
|
||||
// Missing timezones treated as bad.
|
||||
assertThat(HttpDate.parse("Thu, 01 Jan 1970 00:00:00")).isNull()
|
||||
assertThat("Thu, 01 Jan 1970 00:00:00".toHttpDateOrNull()).isNull()
|
||||
// Missing seconds treated as bad.
|
||||
assertThat(HttpDate.parse("Thu, 01 Jan 1970 00:00 GMT")).isNull()
|
||||
assertThat("Thu, 01 Jan 1970 00:00 GMT".toHttpDateOrNull()).isNull()
|
||||
// Extra spaces treated as bad.
|
||||
assertThat(HttpDate.parse("Thu, 01 Jan 1970 00:00 GMT")).isNull()
|
||||
assertThat("Thu, 01 Jan 1970 00:00 GMT".toHttpDateOrNull()).isNull()
|
||||
// Missing leading zero treated as bad.
|
||||
assertThat(HttpDate.parse("Thu, 1 Jan 1970 00:00 GMT")).isNull()
|
||||
assertThat("Thu, 1 Jan 1970 00:00 GMT".toHttpDateOrNull()).isNull()
|
||||
|
||||
// RFC 850, obsoleted by RFC 1036 with any TZ.
|
||||
assertThat(HttpDate.parse("Thursday, 01-Jan-1970 00:00:00 GMT-01:00")!!.time)
|
||||
assertThat("Thursday, 01-Jan-1970 00:00:00 GMT-01:00".toHttpDateOrNull()!!.time)
|
||||
.isEqualTo(3600000L)
|
||||
assertThat(HttpDate.parse("Thursday, 01-Jan-1970 00:00:00 PST")!!.time)
|
||||
assertThat("Thursday, 01-Jan-1970 00:00:00 PST".toHttpDateOrNull()!!.time)
|
||||
.isEqualTo(28800000L)
|
||||
// Ignore trailing junk
|
||||
assertThat(HttpDate.parse("Thursday, 01-Jan-1970 00:00:00 PST JUNK")!!.time)
|
||||
assertThat("Thursday, 01-Jan-1970 00:00:00 PST JUNK".toHttpDateOrNull()!!.time)
|
||||
.isEqualTo(28800000L)
|
||||
|
||||
// ANSI C's asctime() format
|
||||
// This format ignores the timezone entirely even if it is present and uses GMT.
|
||||
assertThat(HttpDate.parse("Fri Jun 6 12:30:30 2014 PST")!!.time).isEqualTo(1402057830000L)
|
||||
assertThat("Fri Jun 6 12:30:30 2014 PST".toHttpDateOrNull()!!.time).isEqualTo(1402057830000L)
|
||||
// Ignore trailing junk.
|
||||
assertThat(HttpDate.parse("Fri Jun 6 12:30:30 2014 JUNK")!!.time).isEqualTo(1402057830000L)
|
||||
assertThat("Fri Jun 6 12:30:30 2014 JUNK".toHttpDateOrNull()!!.time).isEqualTo(1402057830000L)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user