https://kotlinlang.org logo
#ktor
Title
# ktor
r

ribesg

06/05/2019, 8:27 AM
Why can’t I set the content type on a request? It fails saying the engine should handle the content type header, what does that mean?
e

e5l

06/05/2019, 8:28 AM
You can set
Content-type
if you’re using
OutgoingContent
as body.
r

ribesg

06/05/2019, 8:29 AM
Here is my code
Copy code
private suspend fun doUploadFile(data: ByteReadChannel, uploadUrl: String, contentType: ContentType): Unit =
        http.put(uploadUrl) {
            headers.clear() // Remove default headers for this request
            contentType(contentType)
            body = object : OutgoingContent.WriteChannelContent() {

                override suspend fun writeTo(channel: ByteWriteChannel) {
                    data.copyAndClose(channel)
                }

            }
        }
I get
Caused by: io.ktor.http.UnsafeHeaderException: Header Content-Type is controlled by the engine and cannot be set explicitly
with this code
e

e5l

06/05/2019, 8:37 AM
Could you try something like this?
Copy code
suspend fun HttpClient.doUploadFile(
        data: ByteReadChannel,
        uploadUrl: String,
        contentType: ContentType
): Unit = put(uploadUrl) {
        body = object : OutgoingContent.WriteChannelContent() {
            override val contentType: ContentType? get() = contentType

            override suspend fun writeTo(channel: ByteWriteChannel) {
                data.copyAndClose(channel)
            }

        }
    }
r

ribesg

06/05/2019, 8:38 AM
I see. I’ve been looking a bit more at the
OutgoingContent
file and I saw
ReadChannelContent
, can I use this code instead? What’s the difference?
Copy code
body = object : OutgoingContent.ReadChannelContent() {
                override fun readFrom() = data
            }
(Adding the contentType to that)
e

e5l

06/05/2019, 8:39 AM
Yes, you can also override
contentType
in any
OutgoingContent
.
r

ribesg

06/05/2019, 8:40 AM
How do you chose if you use a
ReadChannelContent
or a
WriteChannelContent
?
e

e5l

06/05/2019, 8:41 AM
ReadChannelContent
obliges you to provide generating channel.
WriteChannelContent
allows you to write content directly.
r

ribesg

06/05/2019, 8:43 AM
So if I already have a
ByteReadChannel
I use
ReadChannelContent
, while if I have something else to write like a simple
String
or an
InputStream
I could write it directly using
WriteChannelContent
, am I understanding that correctly?
👌 1
override val contentType
works, thanks.
😉 1
@e5l So I just realized that it uploads exactly 0 bytes
Maybe I need to set the content length but it doesn’t make sense as I don’t always know the length of the
ByteReadChannel
Ok that was an error on my custom logger. Wasn’t splitting the channel when trying to log it
5 Views