From 3b8c61a87ea793085455c4a8b0ce2569c1d6bc11 Mon Sep 17 00:00:00 2001 From: Valere Date: Wed, 2 Sep 2020 16:06:48 +0200 Subject: [PATCH] FIx / interceptors and stream closed --- .../internal/network/ProgressRequestBody.kt | 11 ++--- .../internal/session/content/FileUploader.kt | 40 ++++++------------- .../session/content/UploadContentWorker.kt | 10 ++--- 3 files changed, 21 insertions(+), 40 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/ProgressRequestBody.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/ProgressRequestBody.kt index addc5b7205..98dec301ee 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/ProgressRequestBody.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/ProgressRequestBody.kt @@ -24,6 +24,7 @@ import okio.BufferedSink import okio.ForwardingSink import okio.Sink import okio.buffer +import org.matrix.android.sdk.api.extensions.tryThis import java.io.IOException internal class ProgressRequestBody(private val delegate: RequestBody, @@ -39,15 +40,9 @@ internal class ProgressRequestBody(private val delegate: RequestBody, override fun isDuplex() = delegate.isDuplex() - override fun contentLength(): Long { - try { - return delegate.contentLength() - } catch (e: IOException) { - e.printStackTrace() - } + val length = tryThis { delegate.contentLength() } ?: -1 - return -1 - } + override fun contentLength() = length @Throws(IOException::class) override fun writeTo(sink: BufferedSink) { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/content/FileUploader.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/content/FileUploader.kt index 18d3558f4b..4ddf394b00 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/content/FileUploader.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/content/FileUploader.kt @@ -32,6 +32,7 @@ import okhttp3.RequestBody.Companion.toRequestBody import okio.BufferedSink import okio.source import org.greenrobot.eventbus.EventBus +import org.matrix.android.sdk.api.extensions.tryThis import org.matrix.android.sdk.api.session.content.ContentUrlResolver import org.matrix.android.sdk.internal.di.Authenticated import org.matrix.android.sdk.internal.network.ProgressRequestBody @@ -40,7 +41,7 @@ import org.matrix.android.sdk.internal.network.toFailure import java.io.File import java.io.FileNotFoundException import java.io.IOException -import java.io.InputStream +import java.util.UUID import javax.inject.Inject internal class FileUploader @Inject constructor(@Authenticated @@ -57,11 +58,11 @@ internal class FileUploader @Inject constructor(@Authenticated filename: String?, mimeType: String?, progressListener: ProgressRequestBody.Listener? = null): ContentUploadResponse { - val uploadBody = object : RequestBody() { + val uploadBody = object : RequestBody() { override fun contentLength() = file.length() // Disable okhttp auto resend for 'large files' - override fun isOneShot() = contentLength() == 0L || contentLength() >= 1_000_000 + override fun isOneShot() = contentLength() == 0L || contentLength() >= 1_000_000 override fun contentType(): MediaType? { return mimeType?.toMediaTypeOrNull() @@ -83,37 +84,22 @@ internal class FileUploader @Inject constructor(@Authenticated return upload(uploadBody, filename, progressListener) } - suspend fun uploadInputStream(inputStream: InputStream, - filename: String?, - mimeType: String?, - progressListener: ProgressRequestBody.Listener? = null): ContentUploadResponse { - val length = inputStream.available().toLong() - val uploadBody = object : RequestBody() { - override fun contentLength() = length - - // Disable okhttp auto resend for 'large files' - override fun isOneShot() = contentLength() == 0L || contentLength() >= 1_000_000 - - override fun contentType(): MediaType? { - return mimeType?.toMediaTypeOrNull() - } - - override fun writeTo(sink: BufferedSink) { - inputStream.source().use { sink.writeAll(it) } - } - } - return upload(uploadBody, filename, progressListener) - } - suspend fun uploadFromUri(uri: Uri, filename: String?, mimeType: String?, progressListener: ProgressRequestBody.Listener? = null): ContentUploadResponse { - val inputStream = withContext(Dispatchers.IO) { + val inputStream = withContext(Dispatchers.IO) { context.contentResolver.openInputStream(uri) } ?: throw FileNotFoundException() - return uploadInputStream(inputStream, filename, mimeType, progressListener) + val workingFile = File.createTempFile(UUID.randomUUID().toString(), null, context.cacheDir) + workingFile.outputStream().use { + inputStream.copyTo(it) + } + return uploadFile(workingFile, filename, mimeType, progressListener).also { + tryThis { workingFile.delete() } + } } + private suspend fun upload(uploadBody: RequestBody, filename: String?, progressListener: ProgressRequestBody.Listener?): ContentUploadResponse { val urlBuilder = uploadUrl.toHttpUrlOrNull()?.newBuilder() ?: throw RuntimeException() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/content/UploadContentWorker.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/content/UploadContentWorker.kt index 12ded1666b..53ca720f6a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/content/UploadContentWorker.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/content/UploadContentWorker.kt @@ -178,7 +178,7 @@ internal class UploadContentWorker(val context: Context, params: WorkerParameter var uploadedFileEncryptedFileInfo: EncryptedFileInfo? = null return try { - val streamToUpload: InputStream + val fileToUplaod: File if (attachment.type == ContentAttachmentData.Type.IMAGE && params.compressBeforeSending) { // Compressor library works with File instead of Uri for now. Since Scoped Storage doesn't allow us to access files directly, we should @@ -200,9 +200,9 @@ internal class UploadContentWorker(val context: Context, params: WorkerParameter options.outHeight, fileSize ) - streamToUpload = compressedFile.inputStream() + fileToUplaod = compressedFile } else { - streamToUpload = workingFile.inputStream() + fileToUplaod = workingFile } val contentUploadResponse = if (params.isEncrypted) { @@ -211,7 +211,7 @@ internal class UploadContentWorker(val context: Context, params: WorkerParameter val tmpEncrypted = File.createTempFile(UUID.randomUUID().toString(), null, context.cacheDir) uploadedFileEncryptedFileInfo = - MXEncryptedAttachments.encrypt(streamToUpload, attachment.getSafeMimeType(), tmpEncrypted) { read, total -> + MXEncryptedAttachments.encrypt(fileToUplaod.inputStream(), attachment.getSafeMimeType(), tmpEncrypted) { read, total -> notifyTracker(params) { contentUploadStateTracker.setEncrypting(it, read.toLong(), total.toLong()) } @@ -228,7 +228,7 @@ internal class UploadContentWorker(val context: Context, params: WorkerParameter } else { Timber.v("## FileService: Clear file") fileUploader - .uploadInputStream(streamToUpload, attachment.name, attachment.getSafeMimeType(), progressListener) + .uploadFile(fileToUplaod, attachment.name, attachment.getSafeMimeType(), progressListener) } Timber.v("## FileService: Update cache storage for ${contentUploadResponse.contentUri}")