Skip to content

Commit acf8735

Browse files
authored
Backport of #6495 (#6940)
1 parent 86acfbd commit acf8735

File tree

3 files changed

+25
-19
lines changed

3 files changed

+25
-19
lines changed

okhttp/src/main/kotlin/okhttp3/Cache.kt

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616
package okhttp3
1717

18+
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
1819
import java.io.Closeable
1920
import java.io.File
2021
import java.io.Flushable
@@ -425,7 +426,7 @@ class Cache internal constructor(
425426
}
426427

427428
private class Entry {
428-
private val url: String
429+
private val url: HttpUrl
429430
private val varyHeaders: Headers
430431
private val requestMethod: String
431432
private val protocol: Protocol
@@ -436,7 +437,7 @@ class Cache internal constructor(
436437
private val sentRequestMillis: Long
437438
private val receivedResponseMillis: Long
438439

439-
private val isHttps: Boolean get() = url.startsWith("https://")
440+
private val isHttps: Boolean get() = url.scheme == "https"
440441

441442
/**
442443
* Reads an entry from an input stream. A typical entry looks like this:
@@ -490,9 +491,14 @@ class Cache internal constructor(
490491
* optional. If present, it contains the TLS version.
491492
*/
492493
@Throws(IOException::class) constructor(rawSource: Source) {
493-
try {
494+
rawSource.use {
494495
val source = rawSource.buffer()
495-
url = source.readUtf8LineStrict()
496+
val urlLine = source.readUtf8LineStrict()
497+
// Choice here is between failing with a correct RuntimeException
498+
// or mostly silently with an IOException
499+
url = urlLine.toHttpUrlOrNull() ?: throw IOException("Cache corruption for $urlLine").also {
500+
Platform.get().log("cache corruption", Platform.WARN, it)
501+
}
496502
requestMethod = source.readUtf8LineStrict()
497503
val varyHeadersBuilder = Headers.Builder()
498504
val varyRequestHeaderLineCount = readInt(source)
@@ -536,13 +542,11 @@ class Cache internal constructor(
536542
} else {
537543
handshake = null
538544
}
539-
} finally {
540-
rawSource.close()
541545
}
542546
}
543547

544548
constructor(response: Response) {
545-
this.url = response.request.url.toString()
549+
this.url = response.request.url
546550
this.varyHeaders = response.varyHeaders()
547551
this.requestMethod = response.request.method
548552
this.protocol = response.protocol
@@ -557,7 +561,7 @@ class Cache internal constructor(
557561
@Throws(IOException::class)
558562
fun writeTo(editor: DiskLruCache.Editor) {
559563
editor.newSink(ENTRY_METADATA).buffer().use { sink ->
560-
sink.writeUtf8(url).writeByte('\n'.toInt())
564+
sink.writeUtf8(url.toString()).writeByte('\n'.toInt())
561565
sink.writeUtf8(requestMethod).writeByte('\n'.toInt())
562566
sink.writeDecimalLong(varyHeaders.size.toLong()).writeByte('\n'.toInt())
563567
for (i in 0 until varyHeaders.size) {
@@ -618,8 +622,8 @@ class Cache internal constructor(
618622
private fun writeCertList(sink: BufferedSink, certificates: List<Certificate>) {
619623
try {
620624
sink.writeDecimalLong(certificates.size.toLong()).writeByte('\n'.toInt())
621-
for (i in 0 until certificates.size) {
622-
val bytes = certificates[i].encoded
625+
for (element in certificates) {
626+
val bytes = element.encoded
623627
val line = bytes.toByteString().base64()
624628
sink.writeUtf8(line).writeByte('\n'.toInt())
625629
}
@@ -629,7 +633,7 @@ class Cache internal constructor(
629633
}
630634

631635
fun matches(request: Request, response: Response): Boolean {
632-
return url == request.url.toString() &&
636+
return url == request.url &&
633637
requestMethod == request.method &&
634638
varyMatches(response, varyHeaders, request)
635639
}

okhttp/src/main/kotlin/okhttp3/HttpUrl.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1257,8 +1257,9 @@ class HttpUrl internal constructor(
12571257
} else if (base != null) {
12581258
this.scheme = base.scheme
12591259
} else {
1260+
val truncated = if (input.length > 6) input.take(6) + "..." else input
12601261
throw IllegalArgumentException(
1261-
"Expected URL scheme 'http' or 'https' but no colon was found")
1262+
"Expected URL scheme 'http' or 'https' but no scheme was found for $truncated")
12621263
}
12631264

12641265
// Authority.

okhttp/src/test/java/okhttp3/HttpUrlTest.java

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -144,20 +144,21 @@ HttpUrl parse(String url) {
144144

145145
assertInvalid("image640://480.png", "Expected URL scheme 'http' or 'https' but was 'image640'");
146146
assertInvalid("httpp://host/", "Expected URL scheme 'http' or 'https' but was 'httpp'");
147-
assertInvalid("0ttp://host/", "Expected URL scheme 'http' or 'https' but no colon was found");
147+
assertInvalid("0ttp://host/", "Expected URL scheme 'http' or 'https' but no scheme was found for 0ttp:/...");
148148
assertInvalid("ht+tp://host/", "Expected URL scheme 'http' or 'https' but was 'ht+tp'");
149149
assertInvalid("ht.tp://host/", "Expected URL scheme 'http' or 'https' but was 'ht.tp'");
150150
assertInvalid("ht-tp://host/", "Expected URL scheme 'http' or 'https' but was 'ht-tp'");
151151
assertInvalid("ht1tp://host/", "Expected URL scheme 'http' or 'https' but was 'ht1tp'");
152152
assertInvalid("httpss://host/", "Expected URL scheme 'http' or 'https' but was 'httpss'");
153153
}
154154

155-
@Test public void parseNoScheme() throws Exception {
156-
assertInvalid("//host", "Expected URL scheme 'http' or 'https' but no colon was found");
157-
assertInvalid("/path", "Expected URL scheme 'http' or 'https' but no colon was found");
158-
assertInvalid("path", "Expected URL scheme 'http' or 'https' but no colon was found");
159-
assertInvalid("?query", "Expected URL scheme 'http' or 'https' but no colon was found");
160-
assertInvalid("#fragment", "Expected URL scheme 'http' or 'https' but no colon was found");
155+
@Test
156+
public void parseNoScheme() throws Exception {
157+
assertInvalid("//host", "Expected URL scheme 'http' or 'https' but no scheme was found for //host");
158+
assertInvalid("/path", "Expected URL scheme 'http' or 'https' but no scheme was found for /path");
159+
assertInvalid("path", "Expected URL scheme 'http' or 'https' but no scheme was found for path");
160+
assertInvalid("?query", "Expected URL scheme 'http' or 'https' but no scheme was found for ?query");
161+
assertInvalid("#fragment", "Expected URL scheme 'http' or 'https' but no scheme was found for #fragm...");
161162
}
162163

163164
@Test public void newBuilderResolve() throws Exception {

0 commit comments

Comments
 (0)