1
0
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:
Jesse Wilson
2019-05-28 01:49:53 -04:00
committed by Yuri Schimke
parent 0b12ed2bb0
commit 96eb1111eb
7 changed files with 221 additions and 227 deletions

View File

@@ -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.
}
}

View File

@@ -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())
}
/**

View File

@@ -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) -> {

View File

@@ -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)
}
}

View 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)

View File

@@ -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();

View File

@@ -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)
}
}