I have a Vapor server running and it's creating files. Those files are temporary files, so they should not stay on the server.
Currently I use the following:
let data = try Data(contentsOf: tempURL)
try FileManager.default.removeItem(at: tempURL)
let response = Response(status: .ok, headers: HTTPHeaders(headers), body: Response.Body(data: data))
So I read the contents of the file, delete that file (as it's temporary only) and then respond with it.
The problem that I now see is that sometimes, very hard to reproduce, the contents of that file is only submitted partially. I don't know exactly what the problem is yet, but I did some digging and at least found a Radar (https://openradar.appspot.com/39621032), saying that this function isn't working like it should on Linux (which I use.. I use it in a Docker-Container)
So just to make sure this is not the problem, I'd like to know the Vapor way of responding with a file and then deleting it afterwards?!?
If this question is still actual, I want to suggest my solution. My system is Vapor 4.49.0, Swift 5.5, macOS 11.6 (should work on Ubuntu 20.04).
I will post here small but full file routes.swift, please, look:
//
// routes.swift
//
//
// Created by Alex on 09.10.2021.
//
import Vapor
func routes(_ app: Application) throws {
app.get(":fileName") { req -> EventLoopFuture<Response> in
let badResponse = Response(status: .forbidden, version: .http1_0, headers: HTTPHeaders(), body: .empty)
guard let fileName = req.parameters.get("fileName") else {
return req.eventLoop.future(badResponse)
}
let filePath = app.directory.workingDirectory + fileName
guard let file = File(filePath: filePath) else {
return req.eventLoop.future(badResponse)
}
return req.fileio.collectFile(at: filePath).map { biteBuffer in
let body = Response.Body(buffer: biteBuffer)
let response = Response(status: .ok, headers: HTTPHeaders(), body: body)
file.delete()
return response
}
}
}
final class File {
private let fileManager = FileManager.default
private let url: URL
init?(filePath: String) {
guard let url = URL(string: "file:" + filePath) else {
return nil
}
self.url = url
}
func delete() {
do {
try fileManager.removeItem(at: url)
} catch {
}
}
}
I want to hear your reply. If you can test this code, I will be happy. Thanks.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With