Closed molikuner closed 5 years ago
Hi @molikuner, thanks for the report.
It looks like charset decoding issue in kotlin-io
Caused by: kotlinx.io.charsets.MalformedInputException: Input length = 1
Fixed in ktor 1.1.3
.
Sorry, but it doesn't seems to be fixed:
Exception in thread "main" io.ktor.client.call.ReceivePipelineException: Fail to run receive pipeline: kotlinx.io.charsets.MalformedInputException: Input length = 1
at io.ktor.client.call.HttpClientCall.receive(HttpClientCall.kt:61)
at io.ktor.client.call.HttpClientCall$receive$1.invokeSuspend(HttpClientCall.kt)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:32)
at io.ktor.util.pipeline.SuspendFunctionGun.resumeRootWith(PipelineContext.kt:211)
at io.ktor.util.pipeline.SuspendFunctionGun.loop(PipelineContext.kt:186)
at io.ktor.util.pipeline.SuspendFunctionGun.access$loop(PipelineContext.kt:63)
at io.ktor.util.pipeline.SuspendFunctionGun.proceed(PipelineContext.kt:137)
at io.ktor.util.pipeline.SuspendFunctionGun.execute(PipelineContext.kt:157)
at io.ktor.util.pipeline.Pipeline.execute(Pipeline.kt:23)
at io.ktor.client.call.HttpClientCall.receive(HttpClientCall.kt:55)
at com.molikuner.spotify.MainKt$main$1.invokeSuspend(Main.kt:109)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:32)
at io.ktor.util.pipeline.SuspendFunctionGun.resumeRootWith(PipelineContext.kt:211)
at io.ktor.util.pipeline.SuspendFunctionGun.loop(PipelineContext.kt:168)
at io.ktor.util.pipeline.SuspendFunctionGun.access$loop(PipelineContext.kt:63)
at io.ktor.util.pipeline.SuspendFunctionGun$continuation$1.resumeWith(PipelineContext.kt:118)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:45)
at io.ktor.util.pipeline.SuspendFunctionGun.resumeRootWith(PipelineContext.kt:211)
at io.ktor.util.pipeline.SuspendFunctionGun.loop(PipelineContext.kt:168)
at io.ktor.util.pipeline.SuspendFunctionGun.access$loop(PipelineContext.kt:63)
at io.ktor.util.pipeline.SuspendFunctionGun$continuation$1.resumeWith(PipelineContext.kt:118)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:45)
at kotlinx.coroutines.DispatchedTask.run(Dispatched.kt:233)
at kotlinx.coroutines.EventLoopImplBase.processNextEvent(EventLoop.kt:116)
at kotlinx.coroutines.BlockingCoroutine.joinBlocking(Builders.kt:76)
at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking(Builders.kt:53)
at kotlinx.coroutines.BuildersKt.runBlocking(Unknown Source)
at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking$default(Builders.kt:35)
at kotlinx.coroutines.BuildersKt.runBlocking$default(Unknown Source)
at com.molikuner.spotify.MainKt.main(Main.kt:18)
Caused by: kotlinx.io.charsets.MalformedInputException: Input length = 1
at kotlinx.io.charsets.CharsetJVMKt.throwExceptionWrapped(CharsetJVM.kt:287)
at kotlinx.io.charsets.CharsetJVMKt.decode(CharsetJVM.kt:166)
at kotlinx.io.charsets.EncodingKt.decode(Encoding.kt:104)
at kotlinx.io.core.StringsKt.readText(Strings.kt:351)
at kotlinx.io.core.StringsKt.readText$default(Strings.kt:350)
at io.ktor.client.response.HttpResponseKt.readText(HttpResponse.kt:77)
at io.ktor.client.features.HttpPlainText.read$ktor_client_core(HttpPlainText.kt:23)
at io.ktor.client.features.HttpPlainText$Feature$install$2.invokeSuspend(HttpPlainText.kt:48)
at io.ktor.client.features.HttpPlainText$Feature$install$2.invoke(HttpPlainText.kt)
at io.ktor.util.pipeline.SuspendFunctionGun.loop(PipelineContext.kt:278)
... 25 more
my build.gradle
contains:
compile group: 'io.ktor', name: 'ktor-client', version: '1.1.3'
compile group: 'io.ktor', name: 'ktor-client-cio', version: '1.1.3'
@cy6erGn0m
Any news?
@molikuner No reproducer so far. I guess it's index.php producing from time to time something that we can't handle for some reason. Is there any way to make failure stable or to make it fail more frequently?
EDIT: I get this error every time I request the specified URL.
Now that I've been struggling for a few hours, I've finally made it work. It seems that the ISO-8859-1
encoding doesn't work properly. The server does not respond with the encoding in Content-Type
, but in html (via meta). As I found out, I could make the request work by manually specifying the encoding. Although I don't know exactly which other encoding is used if I don't specify it. In HttpResponseConfig.kt
I found out that actually ISO-8859-1
is the default encoding. However, this does not work properly.
My current code:
val httpClient = HttpClient(CIO)
fun makeCall() = runBlocking {
httpClient.call {
url {
protocol = URLProtocol.HTTPS
host = "playlisten.rbb-online.de"
encodedPath = "/radioberlin/main/index.php"
}
}
}
val call: HttpClientCall
get() = makeCall()
fun main() = runBlocking<Unit> {
call.also {
println("requesting with specified charset:\ncharset should be: ${it.response.charset() ?: it.responseConfig.defaultCharset}")
try {
println("response length: ${it.response.readText(Charsets.ISO_8859_1).length}")
} catch (e: Throwable) {
println("Got error with specified charset:")
e.printStackTrace()
}
}
call.also {
println("\nrequesting with self-specified charset:\ncharset should be: ${it.response.charset() ?: it.responseConfig.defaultCharset}")
try {
println("response length: ${it.response.readText(it.response.charset() ?: it.responseConfig.defaultCharset).length}")
} catch (e: Throwable) {
println("Got error with self-specified charset:")
e.printStackTrace()
}
}
call.also {
println("\nrequesting with default charset:\ncharset should be: ${it.response.charset() ?: it.responseConfig.defaultCharset}")
try {
println("response length: ${it.receive<String>().length}")
} catch (e: Throwable) {
println("Got error with default charset:")
e.printStackTrace()
}
}
}
requesting with specified charset:
charset should be: ISO-8859-1
response length: 6521
requesting with self-specified charset:
charset should be: ISO-8859-1
response length: 6521
requesting with default charset:
charset should be: ISO-8859-1
Got error with default charset:
io.ktor.client.call.ReceivePipelineException: Fail to run receive pipeline: kotlinx.io.charsets.MalformedInputException: Input length = 1
at io.ktor.client.call.HttpClientCall.receive(HttpClientCall.kt:61)
at io.ktor.client.call.HttpClientCall$receive$1.invokeSuspend(HttpClientCall.kt)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:32)
at io.ktor.util.pipeline.SuspendFunctionGun.resumeRootWith(PipelineContext.kt:211)
at io.ktor.util.pipeline.SuspendFunctionGun.loop(PipelineContext.kt:186)
at io.ktor.util.pipeline.SuspendFunctionGun.access$loop(PipelineContext.kt:63)
at io.ktor.util.pipeline.SuspendFunctionGun.proceed(PipelineContext.kt:137)
at io.ktor.util.pipeline.SuspendFunctionGun.execute(PipelineContext.kt:157)
at io.ktor.util.pipeline.Pipeline.execute(Pipeline.kt:23)
at io.ktor.client.call.HttpClientCall.receive(HttpClientCall.kt:55)
at com.molikuner.spotify.MainKt$main$1.invokeSuspend(Main.kt:154)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:32)
at kotlinx.coroutines.DispatchedTask.run(Dispatched.kt:233)
at kotlinx.coroutines.EventLoopImplBase.processNextEvent(EventLoop.kt:116)
at kotlinx.coroutines.BlockingCoroutine.joinBlocking(Builders.kt:76)
at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking(Builders.kt:53)
at kotlinx.coroutines.BuildersKt.runBlocking(Unknown Source)
at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking$default(Builders.kt:35)
at kotlinx.coroutines.BuildersKt.runBlocking$default(Unknown Source)
at com.molikuner.spotify.MainKt.main(Main.kt:35)
at com.molikuner.spotify.MainKt.main(Main.kt)
Caused by: kotlinx.io.charsets.MalformedInputException: Input length = 1
at kotlinx.io.charsets.CharsetJVMKt.throwExceptionWrapped(CharsetJVM.kt:287)
at kotlinx.io.charsets.CharsetJVMKt.decode(CharsetJVM.kt:166)
at kotlinx.io.charsets.EncodingKt.decode(Encoding.kt:104)
at kotlinx.io.core.StringsKt.readText(Strings.kt:351)
at kotlinx.io.core.StringsKt.readText$default(Strings.kt:350)
at io.ktor.client.response.HttpResponseKt.readText(HttpResponse.kt:77)
at io.ktor.client.features.HttpPlainText.read$ktor_client_core(HttpPlainText.kt:23)
at io.ktor.client.features.HttpPlainText$Feature$install$2.invokeSuspend(HttpPlainText.kt:48)
at io.ktor.client.features.HttpPlainText$Feature$install$2.invoke(HttpPlainText.kt)
at io.ktor.util.pipeline.SuspendFunctionGun.loop(PipelineContext.kt:278)
... 16 more
After testing even more:
fun main() = runBlocking<Unit> {
call.also {
println("\nrequesting with self-specified charset:\ncharset should be: ${it.response.charset() ?: it.responseConfig.defaultCharset}")
try {
println("response length: ${it.response.readText().length}")
} catch (e: Throwable) {
println("Got error with self-specified charset:")
e.printStackTrace()
}
}
call.also {
println("\nrequesting with default charset:\ncharset should be: ${it.response.charset() ?: it.responseConfig.defaultCharset}")
try {
println("response length: ${it.receive<String>().length}")
} catch (e: Throwable) {
println("Got error with default charset:")
e.printStackTrace()
}
}
}
requesting with self-specified charset:
charset should be: ISO-8859-1
response length: 6521
requesting with default charset:
charset should be: ISO-8859-1
Got error with default charset:
io.ktor.client.call.ReceivePipelineException: Fail to run receive pipeline: kotlinx.io.charsets.MalformedInputException: Input length = 1
....
So there is a difference which function is called to get the response.
For my use case, this is probably enough to get the response like this, but it's a bug...
@cy6erGn0m as I have now understood it, the problem is not completely in the charset, because it also works without any further information. So it's probably due to the pipeline, which has problems with parsing the answer to a HttpPlainText
. Shouldn't this internally call the function readText()
as I do it manually now? This function should also have ISO-8859-1
as default charset and should work with it.
I have the same problem. Unfortunately I can't set breakpoint inside HttpClientCall.receive
since when I try, my IntelliJ just freezes. I'm running Arch Linux and trying to migrate from Fuel (which works perfectly with the same request).
That's the simplest code which reproduces the bug:
fun main() = runBlocking{
val answerNumber = 50165755
val stackExchangeApiUrl = "https://api.stackexchange.com/2.2/posts"
val client = HttpClient(Apache)
val message = client.get<String> {
url(URL("$stackExchangeApiUrl/$answerNumber"))
parameter("site", "stackoverflow")
}
print(message)
}
I'm using:
implementation("io.ktor:ktor-client-apache:1.1.3")
implementation("io.ktor:ktor-client-core:1.1.3")
Stack trace:
Exception in thread "main" io.ktor.client.call.ReceivePipelineException: Fail to run receive pipeline: kotlinx.io.charsets.MalformedInputException: Input length = 1
at io.ktor.client.call.HttpClientCall.receive(HttpClientCall.kt:61)
at io.ktor.client.call.HttpClientCall$receive$1.invokeSuspend(HttpClientCall.kt)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:32)
at io.ktor.util.pipeline.SuspendFunctionGun.resumeRootWith(PipelineContext.kt:211)
at io.ktor.util.pipeline.SuspendFunctionGun.loop(PipelineContext.kt:186)
at io.ktor.util.pipeline.SuspendFunctionGun.access$loop(PipelineContext.kt:63)
at io.ktor.util.pipeline.SuspendFunctionGun.proceed(PipelineContext.kt:137)
at io.ktor.util.pipeline.SuspendFunctionGun.execute(PipelineContext.kt:157)
at io.ktor.util.pipeline.Pipeline.execute(Pipeline.kt:23)
at io.ktor.client.call.HttpClientCall.receive(HttpClientCall.kt:55)
at SampleKt$main$1.invokeSuspend(Sample.kt:49)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:32)
at io.ktor.util.pipeline.SuspendFunctionGun.resumeRootWith(PipelineContext.kt:211)
at io.ktor.util.pipeline.SuspendFunctionGun.loop(PipelineContext.kt:168)
at io.ktor.util.pipeline.SuspendFunctionGun.access$loop(PipelineContext.kt:63)
at io.ktor.util.pipeline.SuspendFunctionGun$continuation$1.resumeWith(PipelineContext.kt:118)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:45)
at io.ktor.util.pipeline.SuspendFunctionGun.resumeRootWith(PipelineContext.kt:211)
at io.ktor.util.pipeline.SuspendFunctionGun.loop(PipelineContext.kt:168)
at io.ktor.util.pipeline.SuspendFunctionGun.access$loop(PipelineContext.kt:63)
at io.ktor.util.pipeline.SuspendFunctionGun$continuation$1.resumeWith(PipelineContext.kt:118)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:45)
at kotlinx.coroutines.DispatchedTask.run(Dispatched.kt:233)
at kotlinx.coroutines.EventLoopImplBase.processNextEvent(EventLoop.kt:116)
at kotlinx.coroutines.BlockingCoroutine.joinBlocking(Builders.kt:76)
at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking(Builders.kt:53)
at kotlinx.coroutines.BuildersKt.runBlocking(Unknown Source)
at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking$default(Builders.kt:35)
at kotlinx.coroutines.BuildersKt.runBlocking$default(Unknown Source)
at SampleKt.main(Sample.kt:8)
at SampleKt.main(Sample.kt)
Caused by: kotlinx.io.charsets.MalformedInputException: Input length = 1
at kotlinx.io.charsets.CharsetJVMKt.throwExceptionWrapped(CharsetJVM.kt:287)
at kotlinx.io.charsets.CharsetJVMKt.decode(CharsetJVM.kt:166)
at kotlinx.io.charsets.EncodingKt.decode(Encoding.kt:104)
at kotlinx.io.core.StringsKt.readText(Strings.kt:351)
at kotlinx.io.core.StringsKt.readText$default(Strings.kt:350)
at io.ktor.client.response.HttpResponseKt.readText(HttpResponse.kt:77)
at io.ktor.client.features.HttpPlainText.read$ktor_client_core(HttpPlainText.kt:23)
at io.ktor.client.features.HttpPlainText$Feature$install$2.invokeSuspend(HttpPlainText.kt:48)
at io.ktor.client.features.HttpPlainText$Feature$install$2.invoke(HttpPlainText.kt)
at io.ktor.util.pipeline.SuspendFunctionGun.loop(PipelineContext.kt:278)
... 26 more
Hi all,
Any news? I have the same problem.
ktor 1.1.3
io.ktor.client.call.ReceivePipelineException: Fail to run receive pipeline
Hi @Dallanosm, it should be fixed. Could you recheck it with 1.2.2
?
Hey @e5l I just tested the code again and the issue isn't fixed:
Exception in thread "main" kotlinx.io.charsets.MalformedInputException: Input length = 1
at kotlinx.io.charsets.CharsetJVMKt.throwExceptionWrapped(CharsetJVM.kt:287)
at kotlinx.io.charsets.CharsetJVMKt.decode(CharsetJVM.kt:166)
at kotlinx.io.charsets.EncodingKt.decode(Encoding.kt:77)
at kotlinx.io.core.StringsKt.readText(Strings.kt:242)
at kotlinx.io.core.StringsKt.readText$default(Strings.kt:241)
at io.ktor.client.features.HttpPlainText.read$ktor_client_core(HttpPlainText.kt:153)
at io.ktor.client.features.HttpPlainText$Feature$install$2.invokeSuspend(HttpPlainText.kt:138)
at io.ktor.client.features.HttpPlainText$Feature$install$2.invoke(HttpPlainText.kt)
at io.ktor.util.pipeline.SuspendFunctionGun.loop(PipelineContext.kt:268)
at io.ktor.util.pipeline.SuspendFunctionGun.access$loop(PipelineContext.kt:67)
at io.ktor.util.pipeline.SuspendFunctionGun.proceed(PipelineContext.kt:141)
at io.ktor.util.pipeline.SuspendFunctionGun.proceedWith(PipelineContext.kt:151)
at io.ktor.client.features.HttpCallValidator$Companion$install$2.invokeSuspend(HttpCallValidator.kt:97)
at io.ktor.client.features.HttpCallValidator$Companion$install$2.invoke(HttpCallValidator.kt)
at io.ktor.util.pipeline.SuspendFunctionGun.loop(PipelineContext.kt:268)
at io.ktor.util.pipeline.SuspendFunctionGun.access$loop(PipelineContext.kt:67)
at io.ktor.util.pipeline.SuspendFunctionGun.proceed(PipelineContext.kt:141)
at io.ktor.util.pipeline.SuspendFunctionGun.execute(PipelineContext.kt:161)
at io.ktor.util.pipeline.Pipeline.execute(Pipeline.kt:27)
at io.ktor.client.call.HttpClientCall.receive(HttpClientCall.kt:84)
at com.molikuner.MainKt$main$1.invokeSuspend(Main.kt:46)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at io.ktor.util.pipeline.SuspendFunctionGun.resumeRootWith(PipelineContext.kt:215)
at io.ktor.util.pipeline.SuspendFunctionGun.loop(PipelineContext.kt:172)
at io.ktor.util.pipeline.SuspendFunctionGun.access$loop(PipelineContext.kt:67)
at io.ktor.util.pipeline.SuspendFunctionGun$continuation$1.resumeWith(PipelineContext.kt:122)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:46)
at io.ktor.util.pipeline.SuspendFunctionGun.resumeRootWith(PipelineContext.kt:215)
at io.ktor.util.pipeline.SuspendFunctionGun.loop(PipelineContext.kt:172)
at io.ktor.util.pipeline.SuspendFunctionGun.access$loop(PipelineContext.kt:67)
at io.ktor.util.pipeline.SuspendFunctionGun$continuation$1.resumeWith(PipelineContext.kt:122)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:46)
at io.ktor.util.pipeline.SuspendFunctionGun.resumeRootWith(PipelineContext.kt:215)
at io.ktor.util.pipeline.SuspendFunctionGun.loop(PipelineContext.kt:172)
at io.ktor.util.pipeline.SuspendFunctionGun.access$loop(PipelineContext.kt:67)
at io.ktor.util.pipeline.SuspendFunctionGun$continuation$1.resumeWith(PipelineContext.kt:122)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:46)
at kotlinx.coroutines.DispatchedTask.run(Dispatched.kt:238)
at kotlinx.coroutines.EventLoopImplBase.processNextEvent(EventLoop.kt:116)
at kotlinx.coroutines.BlockingCoroutine.joinBlocking(Builders.kt:80)
at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking(Builders.kt:54)
at kotlinx.coroutines.BuildersKt.runBlocking(Unknown Source)
at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking$default(Builders.kt:36)
at kotlinx.coroutines.BuildersKt.runBlocking$default(Unknown Source)
at com.molikuner.MainKt.main(Main.kt:24)
at com.molikuner.MainKt.main(Main.kt)
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.2.2"
implementation 'io.ktor:ktor-client:1.2.2'
implementation 'io.ktor:ktor-client-cio:1.2.2'
Hi @Dallanosm, it should be fixed. Could you recheck it with
1.2.2
?
Works fine, thanks (My apologies for the delay)
Closed
Ktor Version
1.1.2
Ktor Engine Used
CIO
JVM Version, Operating System and Relevant Context
JVM Version
:1.8
Operating System
:Debian 64bit
Feedback
I have an issue with the
ktor-client
. It breakes while simply requesting a random website. Other websites are working fine. My code looks like this:I get the stack: