Skip to content

FileDownloadDelegate can issue out-of-order writes #348

Closed
@Lukasa

Description

@Lukasa

FileDownloadDelegate writes file body parts to the filesystem in the following code:

let writeFuture: EventLoopFuture<Void>
if let fileHandleFuture = self.fileHandleFuture {
writeFuture = fileHandleFuture.flatMap {
self.io.write(fileHandle: $0, buffer: buffer, eventLoop: task.eventLoop)
}
} else {
let fileHandleFuture = self.io.openFile(
path: self.filePath,
mode: .write,
flags: .allowFileCreation(),
eventLoop: task.eventLoop
)
self.fileHandleFuture = fileHandleFuture
writeFuture = fileHandleFuture.flatMap {
self.io.write(fileHandle: $0, buffer: buffer, eventLoop: task.eventLoop)
}
}
self.writeFuture = writeFuture
return writeFuture

This code incorrectly assumes that only one write may be in flight at a given time. While the delegate protocol does exert backpressure, it is entirely possible for multiple .body chunks to be triggered on a single channelRead, particularly in the case of chunked transfer encoding. The delegate protocol does not protect against this and currently does not promise that this will not happen.

We should either fix the delegate, or fix the delegate protocol to guarantee that only one call to didReceiveHead, didReceiveBodyPart, and didFinishRequest are in flight at any given time. I'm inclined to want to clean up our use of the delegate to make it easier to program against, rather than to just fix the downloader, but I'd like to hear other opinions on the matter, particularly from @weissi and @artemredkin.

Metadata

Metadata

Assignees

No one assigned

    Labels

    kind/bugFeature doesn't work as expected.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions