Hello folks! I am trying to upload a file to S3 vi...
# ktor
i
Hello folks! I am trying to upload a file to S3 via a pre-signed URL, using a PUT. I thought it could be done via
Copy code
setBody(File("some_file.large").readChannel())
unfortunately Ktor sets some headers that upset S3. So the only way out is to specify
contentType
and
contentLength
but I don't see how I can do this and keep the logic of
readChannel
. Any suggestions? Thanks!
what I have come up with is
Copy code
setBody(
                object : OutgoingContent.WriteChannelContent() {
                    override val contentType = OctetStream
                    override val contentLength = archive.fileSize()
                    override suspend fun writeTo(channel: ByteWriteChannel) {
                        val readChannel = archive.readChannel()
                        channel.use {
                            while (!readChannel.isClosedForRead) {
                                val packet = readChannel.readRemaining(1024)
                                while (!packet.isEmpty) {
                                    channel.writePacket(packet)
                                }
                            }
                        }
                    }
                },
            )
but I keep running out of memory while uploading a 1G file.
a
Could you please try to send a request body this way?
Copy code
setBody(object : OutgoingContent.ReadChannelContent() {
    override val contentType: ContentType = ContentType.Application.OctetStream
    override val contentLength: Long = archive.fileSize()
    override fun readFrom(): ByteReadChannel = archive.readChannel()
})
i
trying it now
although I think I may have already given that a go..let's see 🙂
btw I am on a memory limited device 😞 only have 2G to play with.
nope, I ran out of memory
I am using the Apache engine, maybe CIO will behave better..
no joy I am running out of heap
I'm uploading a 1G file, I am really hoping it's not trying to load all of it to memory 🙂 any suggestions @Aleksei Tirman [JB]?
a
Unfortunately, I cannot reproduce your problem. I’ve test it with the following code and the profiler showed that peak heap memory usage is about 350 MB:
Copy code
val client = HttpClient(Apache) {
    install(HttpTimeout) {
        socketTimeoutMillis = 9999999
        requestTimeoutMillis = 9999999
    }
}

val archive = File("temp_1GB_file")
<http://client.post|client.post>("<https://httpbin.org/post>") {
    setBody(object : OutgoingContent.ReadChannelContent() {
        override val contentType: ContentType = ContentType.Application.OctetStream
        override val contentLength: Long = archive.length()
        override fun readFrom(): ByteReadChannel = archive.readChannel()
    })
}
Could you please file an issue with a sample project attached?
i
@Aleksei Tirman [JB] thanks. Unfortunately that 350MB is nearly 1/5th of the available RAM on the device and there are other things running..
I do exactly as you did, the only constraint is the RAM.
AH, and running Java8 😭
a
I’ve created this issue to address this problem.
❤️ 1
i
you're a star. Apologies I couldn't provide something more representative, our project is commercial.
I think the CIO engine suffers from the same issue btw.
148 Views