Skip to content

Commit

Permalink
Fix duplicate network call for chunked responses (#2363)
Browse files Browse the repository at this point in the history
* Fix duplicate network call for chunked responses

* Avoid allocating a new peek source

Co-authored-by: Colin White <colin@colinwhite.me>

---------

Co-authored-by: Colin White <colin@colinwhite.me>
  • Loading branch information
ferinagy and colinrtwhite authored Jul 10, 2024
1 parent 2f64ffd commit 9135616
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 1 deletion.
2 changes: 1 addition & 1 deletion coil-base/src/main/java/coil/fetch/HttpUriFetcher.kt
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ internal class HttpUriFetcher(
}

// If we failed to read a new snapshot then read the response body if it's not empty.
if (responseBody.contentLength() > 0) {
if (responseBody.source().request(1L)) {
return SourceResult(
source = responseBody.toImageSource(),
mimeType = getMimeType(url, responseBody.contentType()),
Expand Down
21 changes: 21 additions & 0 deletions coil-base/src/test/java/coil/fetch/HttpUriFetcherTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient
import okhttp3.mockwebserver.MockResponse
import okhttp3.mockwebserver.MockWebServer
import okio.Buffer
import okio.FileSystem
import okio.blackholeSink
import okio.buffer
Expand Down Expand Up @@ -147,6 +148,18 @@ class HttpUriFetcherTest {
assertEquals(expectedSize, result.source.use { it.source().readAll(blackholeSink()) })
}

@Test
fun `no disk cache and chunked response - fetcher calls network just once`() = runTestAsync {
val url = server.url(IMAGE).toString()

server.enqueueChunkedImage(IMAGE)
server.enqueueChunkedImage(IMAGE)

newFetcher(url, diskCache = null).fetch()

assertEquals(1, server.requestCount)
}

@Test
fun `request on main thread with network cache policy disabled executes without throwing`() = runTestAsync {
val expectedSize = server.enqueueImage(IMAGE)
Expand Down Expand Up @@ -458,6 +471,14 @@ class HttpUriFetcherTest {
assertEquals(expectedSize, result.source.use { it.source().readAll(blackholeSink()) })
}

fun MockWebServer.enqueueChunkedImage(image: String) {
val buffer = Buffer()
val context = ApplicationProvider.getApplicationContext<Context>()
context.assets.open(image).source().buffer().readAll(buffer)
val response = MockResponse().setChunkedBody(buffer, 100)
enqueue(response)
}

private fun newFetcher(
url: String,
options: Options = Options(context),
Expand Down

0 comments on commit 9135616

Please sign in to comment.