dave08
02/16/2020, 4:18 PMsuspend fun Call.getDownloadSize(
blockingDispatcher: CoroutineDispatcher = OK_IO
)Long = withContext(blockingDispatcher) {
suspendCancellableCoroutine<Long> { cont ->
cont.invokeOnCancellation {
cancel()
}
enqueue(object : Callback {
override fun onFailure(call: Call?, e: IOException) {
cont.resumeWithException(e)
}
fun Response.getDownloadSizeFromHeader(): Long? = header("Content-Range")
?.substringAfter('/')
?.toLongOrNull()
?.also { this.body()?.close() }
fun Response.getDownloadSizeFromBody(): Long? {
body().use {
return it?.contentLength()
}
}
override fun onResponse(call: Call?, response: Response) {
if (!response.isSuccessful) {
cont.resumeWithException(IOException("Unexpected HTTP code: ${response.code()}"))
return
}
try {
val size = response.run {
getDownloadSizeFromHeader() ?: getDownloadSizeFromBody()
}
if (size != null && size != -1L) {
cont.resume(size)
} else {
cont.resumeWithException(IOException("Unknown size"))
}
} catch (e: Exception) {
cont.resumeWithException(e)
}
}
})
}
}
What's the best way to do this (that would work with all S3 compatible storages)?