Skip to content

Commit 7100ea1

Browse files
authored
Merge pull request #4 from MahdiBM/mmbm-guard-against-multiple-iterations
Guard against multiple iterations
2 parents d5ac556 + 8c619d9 commit 7100ea1

File tree

2 files changed

+20
-11
lines changed

2 files changed

+20
-11
lines changed

Package.swift

+4-2
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,16 @@ let package = Package(
1515
],
1616
dependencies: [
1717
.package(url: "https://github.com/apple/swift-openapi-runtime.git", .upToNextMinor(from: "0.3.0")),
18-
.package(url: "https://github.com/vapor/vapor.git", from: "4.0.0")
18+
.package(url: "https://github.com/vapor/vapor.git", from: "4.84.4"),
19+
.package(url: "https://github.com/apple/swift-atomics", from: "1.2.0")
1920
],
2021
targets: [
2122
.target(
2223
name: "OpenAPIVapor",
2324
dependencies: [
2425
.product(name: "Vapor", package: "vapor"),
25-
.product(name: "OpenAPIRuntime", package: "swift-openapi-runtime")
26+
.product(name: "OpenAPIRuntime", package: "swift-openapi-runtime"),
27+
.product(name: "Atomics", package: "swift-atomics")
2628
]
2729
),
2830
.testTarget(

Sources/OpenAPIVapor/VaporTransport.swift

+16-9
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import OpenAPIRuntime
1717
import HTTPTypes
1818
import Vapor
1919
import NIOFoundationCompat
20+
import Atomics
2021

2122
public final class VaporTransport {
2223

@@ -58,6 +59,7 @@ enum VaporTransportError: Error {
5859
case unsupportedHTTPMethod(String)
5960
case duplicatePathParameter([String])
6061
case missingRequiredPathParameter(String)
62+
case multipleBodyIteration
6163
}
6264

6365
extension [Vapor.PathComponent] {
@@ -143,21 +145,26 @@ extension Vapor.Response.Body {
143145
self = .empty
144146
return
145147
}
148+
/// Used to guard the body from being iterated multiple times.
149+
/// https://github.com/vapor/vapor/issues/3002
150+
let iterated = ManagedAtomic(false)
146151
let stream: @Sendable (any Vapor.BodyStreamWriter) -> () = { writer in
152+
guard iterated.compareExchange(
153+
expected: false,
154+
desired: true,
155+
ordering: .relaxed
156+
).exchanged else {
157+
_ = writer.write(.error(VaporTransportError.multipleBodyIteration))
158+
return
159+
}
147160
_ = writer.eventLoop.makeFutureWithTask {
148161
do {
149162
for try await chunk in body {
150-
try await writer.eventLoop.flatSubmit {
151-
writer.write(.buffer(ByteBuffer(bytes: chunk)))
152-
}.get()
163+
try await writer.write(.buffer(ByteBuffer(bytes: chunk))).get()
153164
}
154-
try await writer.eventLoop.flatSubmit {
155-
writer.write(.end)
156-
}.get()
165+
try await writer.write(.end).get()
157166
} catch {
158-
try await writer.eventLoop.flatSubmit {
159-
writer.write(.error(error))
160-
}.get()
167+
try await writer.write(.error(error)).get()
161168
}
162169
}
163170
}

0 commit comments

Comments
 (0)