"SocketException: Connection reset" with chunked transfer encoding

72 views
Skip to first unread message

Christian Kaps

unread,
Dec 12, 2017, 2:59:45 AM12/12/17
to Play Framework
Hi,

I try to stream a ZIP file from files stored in a MongoDB. To create the ZIP I use this example code. I use ReactiveMongo which provides every file as a Enumerator[Array[Byte]]. I've created a method that transforms this Enumerator into an InputStream which is used to ZIP the file:
implicit def enumeratorToInputStream(enumerator: Enumerator[Array[Byte]]): InputStream = {
val pos = new PipedOutputStream()
val pis = new PipedInputStream(pos)

val it = Iteratee.foreach[Array[Byte]](pos.write)
enumerator.onDoneEnumerating(pos.close()) |>>> it onComplete {
case Failure(e) =>
logger.error("Got exception on converting enumerator to stream", e)
case Success(_) =>
logger.info("Successfully feed all enumerator data into the input stream")
}
pis
}


My Play code looks as follow:
val filesToZip: immutable.Iterable[StreamedZip.ZipSource] = files.map { file =>
(file.filename.getOrElse(file.id.stringify + ".pdf"), () => enumeratorToInputStream(file.content))
}

val source: Source[ByteString, _] = Source[StreamedZip.ZipSource](filesToZip).via(StreamedZip())
val filename = Messages("main.zip.document.name")

Ok.chunked(source)
.as("application/zip")
.withHeaders(CONTENT_DISPOSITION -> s"attachment; filename=$filename")

But this does only work with one file. If I try to create a ZIP from multiple files then the response contains only the string java.net.SocketException: Connection reset. I do not see any stack trace in my logs or in the console. If I debug the code then I see that only one file will be processed. The others will be ignored.

If I try to materialize the stream directly in my action, then all works as expected. All files will be processed.

Does anyone have an idea what could cause this issue? Any help would be highly appreciated.

Best regards,
Christian

Christian Kaps

unread,
Dec 13, 2017, 3:01:18 AM12/13/17
to Play Framework
The issue occurs only in development mode. In production mode all works as expected. So I expect this is an issue with Play. I'll open an issue on GitHub.

Christian Kaps

unread,
Dec 13, 2017, 6:14:14 AM12/13/17
to Play Framework
It was an issue with the buffer size. MongoDB has a default chunk size from 256kb. And the buffer was only set to 64kb.
Reply all
Reply to author
Forward
0 new messages