ktorio / ktor

Framework for quickly creating connected applications in Kotlin with minimal effort
https://ktor.io
Apache License 2.0
13.09k stars 1.07k forks source link

Ktor 1.3.1 Fails File Upload with MalformedInputException #1845

Closed namig-tahmazli closed 4 years ago

namig-tahmazli commented 4 years ago

Hi. I am using Ktor Client with version 1.3.1 for MPP

I have been using Ktor version 1.2.6 in my MPP project with Kotlin version 1.3.61 and it was working fine, so I was able to upload files without a problem. Later I update Kotlin version to 1.3.72 which forced me to update Ktor version 1.3.1 as version 1.2.6 was compiled with Kotlin version 1.3.61 which IDE can not compile with Kotlin plugin 1.3.72. After that file upload call started to give me the following exception.

2020-05-02 17:35:35.186 14564-14671/com.inivo.client.debug E/AndroidRuntime: FATAL EXCEPTION: ktor-android-dispatcher-worker-2
    Process: com.inivo.client.debug, PID: 14564
    io.ktor.utils.io.charsets.MalformedInputException: Input length = 1
        at io.ktor.utils.io.charsets.CharsetJVMKt.throwExceptionWrapped(CharsetJVM.kt:323)
        at io.ktor.utils.io.charsets.CharsetJVMKt.decode(CharsetJVM.kt:199)
        at io.ktor.utils.io.charsets.EncodingKt.decode(Encoding.kt:101)
        at io.ktor.utils.io.core.StringsKt.readText(Strings.kt:251)
        at io.ktor.utils.io.core.StringsKt.readText$default(Strings.kt:250)
        at io.ktor.client.features.logging.Logging$logRequestBody$2$1.invokeSuspend(Logging.kt:111)
        at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
        at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:56)
        at kotlinx.coroutines.EventLoop.processUnconfinedEvent(EventLoop.common.kt:69)
        at kotlinx.coroutines.DispatchedTaskKt.resumeUnconfined(DispatchedTask.kt:184)
        at kotlinx.coroutines.DispatchedTaskKt.dispatch(DispatchedTask.kt:108)
        at kotlinx.coroutines.CancellableContinuationImpl.dispatchResume(CancellableContinuationImpl.kt:307)
        at kotlinx.coroutines.CancellableContinuationImpl.resumeImpl(CancellableContinuationImpl.kt:317)
        at kotlinx.coroutines.CancellableContinuationImpl.resumeWith(CancellableContinuationImpl.kt:249)
        at io.ktor.utils.io.ByteBufferChannel.resumeWriteOp(ByteBufferChannel.kt:2210)
        at io.ktor.utils.io.ByteBufferChannel.bytesRead(ByteBufferChannel.kt:930)
        at io.ktor.utils.io.ByteBufferChannel.readAsMuchAsPossible(ByteBufferChannel.kt:544)
        at io.ktor.utils.io.ByteBufferChannel.readAvailable$suspendImpl(ByteBufferChannel.kt:606)
        at io.ktor.utils.io.ByteBufferChannel.readAvailable(Unknown Source:0)
        at io.ktor.utils.io.jvm.javaio.WritingKt.copyTo(Writing.kt:21)
        at io.ktor.utils.io.jvm.javaio.WritingKt.copyTo$default(Writing.kt:12)
        at io.ktor.client.engine.android.AndroidClientEngineKt.writeTo(AndroidClientEngine.kt:112)
        at io.ktor.client.engine.android.AndroidClientEngine.execute(AndroidClientEngine.kt:79)
        at io.ktor.client.engine.HttpClientEngine$executeWithinCallContext$2.invokeSuspend(HttpClientEngine.kt:83)
        at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
        at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:56)
        at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:571)
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:738)
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:678)
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:665)

I am uploading a file like this.

override suspend fun sendImageAsync(
        token: String,
        file: File,
        fileType: String,
        id: Long
    ): Unit = client.request {
        fullUrl("${RestApi.SEND_IMAGE}/${id}")
        method = HttpMethod.Post
        body = MultiPartFormDataContent(
            formData {
                append(
                    "image",
                    file.fileData.bytes,
                    headers = Headers.build {
                        append(HttpHeaders.ContentType, "image/jpg")
                        append(
                            HttpHeaders.ContentDisposition,
                            "filename=${file.name}"
                        )
                        append("Connection", "Close")
                    }
                )
            }
        )
        header(HttpHeaders.Connection, "close")
        header(HttpHeaders.Authorization, makeAuthToken(token))
    }

Here file data is just an object which keeps File data as a byte array so by that I can convert image to byte array (either from Android / IOS) and upload it.

Thank you very much for your help in advanced.

hikkidev commented 4 years ago

Related: https://github.com/ktorio/ktor/issues/1766

e5l commented 4 years ago

Hi @namig-accenture, thanks for the report. Could you receive the response as ByteArray and post it here?

panda-banda commented 4 years ago

Hi! I have the same problem while loading pdf MultiPartFormData Response as ByteArray is: println("response bytes as HEX String: " + response.readBytes().toHexString()) println("response size: " + response.readBytes().size) Output: response bytes as HEX String: response size: 0 Turning logging off fixes the problem but I can't use it as workaround.

namig-tahmazli commented 4 years ago

Hi @e5l Sorry for the late reply, I was uploading the file as a byte array, I was not receiving it as a byte array. As far as I understood when Ktor logs request data (in this case images as a byte array) it crashes. Because if I disable logging for Ktor uploading file as a byte array works fine.

e5l commented 4 years ago

Could you reproduce it with 1.3.2? We muted all logging exceptions.

namig-tahmazli commented 4 years ago

Hi @e5l , I am sorry for the late reply. I can confirm that the issue still appears with Ktor version 1.3.2.

oleg-larshin commented 4 years ago

Please check the following ticket on YouTrack for follow-ups to this issue. GitHub issues will be closed in the coming weeks.

rsinukov commented 4 years ago

fixed by https://github.com/ktorio/ktor/pull/2064