Skip to content

Commit

Permalink
Return empty ResponseBody in FileIO for empty files (#532)
Browse files Browse the repository at this point in the history
  • Loading branch information
andreasley authored Aug 26, 2024
1 parent b990a10 commit 39362b4
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 0 deletions.
2 changes: 2 additions & 0 deletions Sources/Hummingbird/Files/FileIO.swift
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public struct FileIO: Sendable {
public func loadFile(path: String, context: some RequestContext, chunkLength: Int = NonBlockingFileIO.defaultChunkSize) async throws -> ResponseBody {
do {
let stat = try await fileIO.lstat(path: path)
guard stat.st_size > 0 else { return .init() }
return self.readFile(path: path, range: 0...numericCast(stat.st_size - 1), context: context, chunkLength: chunkLength)
} catch {
throw HTTPError(.notFound)
Expand All @@ -58,6 +59,7 @@ public struct FileIO: Sendable {
public func loadFile(path: String, range: ClosedRange<Int>, context: some RequestContext, chunkLength: Int = NonBlockingFileIO.defaultChunkSize) async throws -> ResponseBody {
do {
let stat = try await fileIO.lstat(path: path)
guard stat.st_size > 0 else { return .init() }
let fileRange: ClosedRange<Int> = 0...numericCast(stat.st_size - 1)
let range = range.clamped(to: fileRange)
return self.readFile(path: path, range: range, context: context, chunkLength: chunkLength)
Expand Down
42 changes: 42 additions & 0 deletions Tests/HummingbirdTests/FileIOTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -90,4 +90,46 @@ class FileIOTests: XCTestCase {
XCTAssertEqual(Data(buffer: buffer), data)
}
}

func testReadEmptyFile() async throws {
let router = Router()
router.get("empty.txt") { _, context -> Response in
let fileIO = FileIO(threadPool: .singleton)
let body = try await fileIO.loadFile(path: "empty.txt", context: context)
return .init(status: .ok, headers: [:], body: body)
}
let data = Data()
let fileURL = URL(fileURLWithPath: "empty.txt")
XCTAssertNoThrow(try data.write(to: fileURL))
defer { XCTAssertNoThrow(try FileManager.default.removeItem(at: fileURL)) }

let app = Application(responder: router.buildResponder())

try await app.test(.router) { client in
try await client.execute(uri: "/empty.txt", method: .get) { response in
XCTAssertEqual(response.status, .ok)
}
}
}

func testReadEmptyFilePart() async throws {
let router = Router()
router.get("empty.txt") { _, context -> Response in
let fileIO = FileIO(threadPool: .singleton)
let body = try await fileIO.loadFile(path: "empty.txt", range: 0...10, context: context)
return .init(status: .ok, headers: [:], body: body)
}
let data = Data()
let fileURL = URL(fileURLWithPath: "empty.txt")
XCTAssertNoThrow(try data.write(to: fileURL))
defer { XCTAssertNoThrow(try FileManager.default.removeItem(at: fileURL)) }

let app = Application(responder: router.buildResponder())

try await app.test(.router) { client in
try await client.execute(uri: "/empty.txt", method: .get) { response in
XCTAssertEqual(response.status, .ok)
}
}
}
}

0 comments on commit 39362b4

Please sign in to comment.