diff --git a/CHANGELOG.md b/CHANGELOG.md index 8020fae..279bb5a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,10 +3,17 @@ All notable changes to this project will be documented in this file. `Firewalk` adheres to [Semantic Versioning](https://semver.org/). #### 0.x Releases -- `0.x` Releases - [0.1.0](#010) | [0.2.0](#020) | [0.3.0](#030) | [0.4.0](#040) | [0.5.0](#050) | [0.6.0](#060) | [0.6.1](#061) | [0.7.0](#070) | [0.8.0](#080) | [0.8.1](#081) | [0.8.2](#082) +- `0.x` Releases - [0.1.0](#010) | [0.2.0](#020) | [0.3.0](#030) | [0.4.0](#040) | [0.5.0](#050) | [0.6.0](#060) | [0.6.1](#061) | [0.7.0](#070) | [0.8.0](#080) | [0.8.1](#081) | [0.8.2](#082) | [0.8.3](#083) --- +## [0.8.3](https://github.com/Alamofire/Firewalk/releases/tag/0.8.3) +Released on 2022-12-10. + +#### Fixed +- Crash in streamed download responses. + - Fixed by [Jon Shier](https://github.com/jshier) in PR [#26](https://github.com/Alamofire/Firewalk/pull/26). + ## [0.8.2](https://github.com/Alamofire/Firewalk/releases/tag/0.8.2) Released on 2022-11-27. diff --git a/Package.resolved b/Package.resolved index 963c4bf..484939c 100644 --- a/Package.resolved +++ b/Package.resolved @@ -59,8 +59,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-atomics.git", "state" : { - "revision" : "919eb1d83e02121cdb434c7bfc1f0c66ef17febe", - "version" : "1.0.2" + "revision" : "ff3d2212b6b093db7f177d0855adbc4ef9c5f036", + "version" : "1.0.3" } }, { @@ -77,8 +77,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-collections.git", "state" : { - "revision" : "f504716c27d2e5d4144fa4794b12129301d17729", - "version" : "1.0.3" + "revision" : "937e904258d22af6e447a0b72c0bc67583ef64a2", + "version" : "1.0.4" } }, { @@ -86,8 +86,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-crypto.git", "state" : { - "revision" : "71ae6adf89ba5346a209ec7f48dbb571a7e8ad1e", - "version" : "2.2.1" + "revision" : "92a04c10fc5ce0504f8396aac7392126033e547c", + "version" : "2.2.2" } }, { @@ -104,8 +104,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-metrics.git", "state" : { - "revision" : "53be78637ecd165d1ddedc4e20de69b8f43ec3b7", - "version" : "2.3.2" + "revision" : "9b39d811a83cf18b79d7d5513b06f8b290198b10", + "version" : "2.3.3" } }, { diff --git a/Sources/Download.swift b/Sources/Download.swift index df22a59..a46e2ee 100644 --- a/Sources/Download.swift +++ b/Sources/Download.swift @@ -58,8 +58,8 @@ func createDownloadRoutes(for app: Application) throws { response = Response(status: .partialContent, body: .init(buffer: buffer)) response.headers.contentRange = .init(unit: .bytes, range: .within(start: totalCount - byteCount, end: totalCount)) } else { - var buffer = request.application.allocator.buffer(repeating: UInt8.random(), count: totalCount) response = Response(body: .init(stream: { writer in + var buffer = request.application.allocator.buffer(repeating: UInt8.random(), count: totalCount) var bytesToSend = totalCount let segment = (totalCount / 10) request.eventLoop.scheduleRepeatedTask(initialDelay: .seconds(0), delay: .milliseconds(1)) { task in @@ -71,7 +71,13 @@ func createDownloadRoutes(for app: Application) throws { return } - _ = writer.write(.buffer(buffer.readSlice(length: segment)!)) + guard let bytes = buffer.readSlice(length: segment) else { + request.logger.info("Failed to read \(segment) bytes from buffer with \(buffer.readableBytes) bytes, ending write.") + task.cancel() + return + } + + _ = writer.write(.buffer(bytes)) bytesToSend -= segment } })) diff --git a/Sources/Extensions.swift b/Sources/Extensions.swift index 5f4f54f..d43ff21 100644 --- a/Sources/Extensions.swift +++ b/Sources/Extensions.swift @@ -34,27 +34,27 @@ extension Request { extension Application { @discardableResult - func on(_ methods: [HTTPMethod], - _ path: PathComponent..., - body: HTTPBodyStreamStrategy = .collect, - use closure: @escaping (Request) throws -> Response) -> [Route] { + func on(_ methods: [HTTPMethod], + _ path: PathComponent..., + body: HTTPBodyStreamStrategy = .collect, + use closure: @escaping (Request) throws -> some ResponseEncodable) -> [Route] { methods.map { on($0, path, body: body, use: closure) } } @discardableResult - func onMethods(_ methods: [HTTPMethod], - body: HTTPBodyStreamStrategy = .collect, - use closure: @escaping (Request) throws -> Response) -> [Route] { + func onMethods(_ methods: [HTTPMethod], + body: HTTPBodyStreamStrategy = .collect, + use closure: @escaping (Request) throws -> some ResponseEncodable) -> [Route] { methods.map { on($0, .constant($0.rawValue.lowercased()), body: body, use: closure) } } } extension RoutesBuilder { @discardableResult - func on(_ methods: [HTTPMethod], - _ path: PathComponent..., - body: HTTPBodyStreamStrategy = .collect, - use closure: @escaping (Request) throws -> Response) -> [Route] { + func on(_ methods: [HTTPMethod], + _ path: PathComponent..., + body: HTTPBodyStreamStrategy = .collect, + use closure: @escaping (Request) throws -> some ResponseEncodable) -> [Route] { methods.map { on($0, path, body: body, use: closure) } } }