Skip to content

Commit 5b42b1b

Browse files
authored
Merge pull request #158 from swhitty/handle-offset-requests
Handle offset requests
2 parents 4f34966 + f281c2a commit 5b42b1b

File tree

4 files changed

+40
-7
lines changed

4 files changed

+40
-7
lines changed

FlyingFox/Sources/HTTPConnection.swift

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,15 @@ struct HTTPConnection: Sendable {
6060
switch response.payload {
6161
case .httpBody(let sequence):
6262
try await socket.write(header)
63+
var sent = 0
6364
for try await chunk in sequence {
64-
try await socket.write(chunk)
65+
do {
66+
try await socket.write(chunk)
67+
sent += chunk.count
68+
} catch {
69+
let total = sequence.count.map(String.init) ?? "unknown"
70+
throw Error("\(error.localizedDescription), sent: \(sent)/\(total).")
71+
}
6572
}
6673
case .webSocket(let handler):
6774
try await switchToWebSocket(with: handler, response: header)
@@ -82,6 +89,14 @@ struct HTTPConnection: Sendable {
8289
func close() throws {
8390
try socket.close()
8491
}
92+
93+
struct Error: LocalizedError {
94+
var errorDescription: String?
95+
96+
init(_ description: String) {
97+
self.errorDescription = description
98+
}
99+
}
85100
}
86101

87102
extension HTTPConnection: Hashable {

FlyingFox/Sources/HTTPServer.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,8 @@ extension Logging {
352352
}
353353

354354
func logRequest(_ request: HTTPRequest, on connection: HTTPConnection) {
355-
logInfo("\(connection.identifer) request: \(request.method.rawValue) \(request.path)")
355+
let suffix = request.headers[.range] != nil ? " <ranged>" : ""
356+
logInfo("\(connection.identifer) request: \(request.method.rawValue) \(request.path)\(suffix)")
356357
}
357358

358359
func logError(_ error: any Error, on connection: HTTPConnection) {

FlyingFox/Sources/Handlers/FileHTTPHandler.swift

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ public struct FileHTTPHandler: HTTPHandler {
105105
)
106106
}
107107

108-
if let range = Self.makePartialRange(for: request.headers) {
108+
if let range = Self.makePartialRange(for: request.headers, fileSize: fileSize) {
109109
headers[.contentRange] = "bytes \(range.lowerBound)-\(range.upperBound)/\(fileSize)"
110110
return try HTTPResponse(
111111
statusCode: .partialContent,
@@ -124,17 +124,19 @@ public struct FileHTTPHandler: HTTPHandler {
124124
}
125125
}
126126

127-
static func makePartialRange(for headers: [HTTPHeader: String]) -> ClosedRange<Int>? {
127+
static func makePartialRange(for headers: [HTTPHeader: String], fileSize: Int) -> ClosedRange<Int>? {
128128
guard let headerValue = headers[.range] else { return nil }
129129
let scanner = Scanner(string: headerValue)
130130
guard scanner.scanString("bytes") != nil,
131131
scanner.scanString("=") != nil,
132132
let start = scanner.scanInt(),
133-
scanner.scanString("-") != nil,
134-
let end = scanner.scanInt(),
135-
start <= end else {
133+
scanner.scanString("-") != nil else {
136134
return nil
137135
}
136+
137+
// if no end clamp at 10MB
138+
let end = scanner.scanInt() ?? min(start + 10_000_000, fileSize) - 1
139+
guard start <= end else { return nil }
138140
return start...end
139141
}
140142
}

FlyingFox/Tests/Handlers/HTTPHandlerTests.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,15 @@ struct HTTPHandlerTests {
186186
#expect(
187187
FileHTTPHandler.makePartialRange(for: [.range: "bytes=1-5"]) == 1...5
188188
)
189+
#expect(
190+
FileHTTPHandler.makePartialRange(for: [.range: "bytes=0-5100"]) == 0...5100
191+
)
192+
#expect(
193+
FileHTTPHandler.makePartialRange(for: [.range: "bytes=0-"], fileSize: 10) == 0...9
194+
)
195+
#expect(
196+
FileHTTPHandler.makePartialRange(for: [.range: "bytes=2-"], fileSize: 10) == 2...9
197+
)
189198
#expect(
190199
FileHTTPHandler.makePartialRange(for: [.range: "bytes = 8 - 10"]) == 8...10
191200
)
@@ -313,3 +322,9 @@ struct HTTPHandlerTests {
313322
#expect(response.statusCode == .ok)
314323
}
315324
}
325+
326+
private extension FileHTTPHandler {
327+
static func makePartialRange(for headers: [HTTPHeader: String]) -> ClosedRange<Int>? {
328+
makePartialRange(for: headers, fileSize: 10000)
329+
}
330+
}

0 commit comments

Comments
 (0)