rewaso7338
rewaso7338

Reputation: 1

does okhttp check for whether the response is complete or not for chunked responses

I am receiving a big file from the server which I cannot hold in memory, hence receiving it in chunked encoded response and reading it through the okhttp Response.body().source() into a buffer and writing it to a file as below.


val downloadFileBuffer = ByteArray(1024)

client.newCall(request).enqueue(object : Callback {
            override fun onFailure(call: Call, e: IOException) {
                Log.d("DOCUMENT_CONVERSION", "FAILED", e)
            }

            override fun onResponse(call: Call, response: Response) {
                if (response.isSuccessful) {
                    val source = response.body()?.source()
                    while (!source?.exhausted()!!) {
                        source?.read(downloadFileBuffer)
                        downloadFileStream.write(downloadFileBuffer) // downloadFileStream being a FileOutputStream
                    }
                    response.close()

                } else {
                    // error handling
                    response.close()
                }
            }
        })

chunked responses will end with an empty zero byte chunk being received. In order to write the whole file on disk I need to check whether the whole response till the end zero byte chunk has been received or not.

I want to know whether okhttp have an internal mechanism to check whether the chunked response is complete or not through onFailure or any other way or it should be handle at application level by me ? What if there is a network failure during the transfer and last few bytes would not have been recieved making the files corrupt ?

Upvotes: 0

Views: 585

Answers (1)

Yuri Schimke
Yuri Schimke

Reputation: 13488

onFailure won't be called if you get a chunked response and then it fails during the response transfer.

You will receive an IOException from a call to source.read if the transfer does not complete.

A cleaner example of this loop is here https://github.com/square/okhttp/blob/c194980c7f0feee59c978766c1acf5c66167994c/okcurl/src/main/kotlin/okhttp3/curl/Main.kt#L139-L143

      val source = response.body!!.source()
      while (!source.exhausted()) {
        out.write(source.buffer, source.buffer.size)
        out.flush()
      }

Upvotes: 1

Related Questions