Strict concurrency for HTTPTypes and friends

This commit is contained in:
George Barnett 2025-03-24 14:01:06 +00:00
parent dc6987e77e
commit f1862dc654
6 changed files with 26 additions and 15 deletions

View File

@ -166,33 +166,38 @@ var targets: [PackageDescription.Target] = [
dependencies: [ dependencies: [
.product(name: "HTTPTypes", package: "swift-http-types"), .product(name: "HTTPTypes", package: "swift-http-types"),
.product(name: "NIOCore", package: "swift-nio"), .product(name: "NIOCore", package: "swift-nio"),
] ],
swiftSettings: strictConcurrencySettings
), ),
.target( .target(
name: "NIOHTTPTypesHTTP1", name: "NIOHTTPTypesHTTP1",
dependencies: [ dependencies: [
"NIOHTTPTypes", "NIOHTTPTypes",
.product(name: "NIOHTTP1", package: "swift-nio"), .product(name: "NIOHTTP1", package: "swift-nio"),
] ],
swiftSettings: strictConcurrencySettings
), ),
.target( .target(
name: "NIOHTTPTypesHTTP2", name: "NIOHTTPTypesHTTP2",
dependencies: [ dependencies: [
"NIOHTTPTypes", "NIOHTTPTypes",
.product(name: "NIOHTTP2", package: "swift-nio-http2"), .product(name: "NIOHTTP2", package: "swift-nio-http2"),
] ],
swiftSettings: strictConcurrencySettings
), ),
.testTarget( .testTarget(
name: "NIOHTTPTypesHTTP1Tests", name: "NIOHTTPTypesHTTP1Tests",
dependencies: [ dependencies: [
"NIOHTTPTypesHTTP1" "NIOHTTPTypesHTTP1"
] ],
swiftSettings: strictConcurrencySettings
), ),
.testTarget( .testTarget(
name: "NIOHTTPTypesHTTP2Tests", name: "NIOHTTPTypesHTTP2Tests",
dependencies: [ dependencies: [
"NIOHTTPTypesHTTP2" "NIOHTTPTypesHTTP2"
] ],
swiftSettings: strictConcurrencySettings
), ),
.target( .target(
name: "NIOResumableUpload", name: "NIOResumableUpload",

View File

@ -19,7 +19,7 @@ import NIOHTTPTypes
/// A simple channel handler that translates HTTP/1 messages into shared HTTP types, /// A simple channel handler that translates HTTP/1 messages into shared HTTP types,
/// and vice versa, for use on the client side. /// and vice versa, for use on the client side.
public final class HTTP1ToHTTPClientCodec: ChannelDuplexHandler, RemovableChannelHandler { public final class HTTP1ToHTTPClientCodec: ChannelDuplexHandler, RemovableChannelHandler, Sendable {
public typealias InboundIn = HTTPClientResponsePart public typealias InboundIn = HTTPClientResponsePart
public typealias InboundOut = HTTPResponsePart public typealias InboundOut = HTTPResponsePart
@ -66,7 +66,7 @@ public final class HTTP1ToHTTPClientCodec: ChannelDuplexHandler, RemovableChanne
/// A simple channel handler that translates HTTP/1 messages into shared HTTP types, /// A simple channel handler that translates HTTP/1 messages into shared HTTP types,
/// and vice versa, for use on the server side. /// and vice versa, for use on the server side.
public final class HTTP1ToHTTPServerCodec: ChannelDuplexHandler, RemovableChannelHandler { public final class HTTP1ToHTTPServerCodec: ChannelDuplexHandler, RemovableChannelHandler, Sendable {
public typealias InboundIn = HTTPServerRequestPart public typealias InboundIn = HTTPServerRequestPart
public typealias InboundOut = HTTPRequestPart public typealias InboundOut = HTTPRequestPart

View File

@ -23,7 +23,7 @@ import NIOHTTPTypes
/// This is intended for compatibility purposes where a channel handler working with /// This is intended for compatibility purposes where a channel handler working with
/// HTTP/1 messages needs to work on top of the new version-independent HTTP types /// HTTP/1 messages needs to work on top of the new version-independent HTTP types
/// abstraction. /// abstraction.
public final class HTTPToHTTP1ClientCodec: ChannelDuplexHandler, RemovableChannelHandler { public final class HTTPToHTTP1ClientCodec: ChannelDuplexHandler, RemovableChannelHandler, Sendable {
public typealias InboundIn = HTTPResponsePart public typealias InboundIn = HTTPResponsePart
public typealias InboundOut = HTTPClientResponsePart public typealias InboundOut = HTTPClientResponsePart
@ -86,7 +86,7 @@ public final class HTTPToHTTP1ClientCodec: ChannelDuplexHandler, RemovableChanne
/// This is intended for compatibility purposes where a channel handler working with /// This is intended for compatibility purposes where a channel handler working with
/// HTTP/1 messages needs to work on top of the new version-independent HTTP types /// HTTP/1 messages needs to work on top of the new version-independent HTTP types
/// abstraction. /// abstraction.
public final class HTTPToHTTP1ServerCodec: ChannelDuplexHandler, RemovableChannelHandler { public final class HTTPToHTTP1ServerCodec: ChannelDuplexHandler, RemovableChannelHandler, Sendable {
public typealias InboundIn = HTTPRequestPart public typealias InboundIn = HTTPRequestPart
public typealias InboundOut = HTTPServerRequestPart public typealias InboundOut = HTTPServerRequestPart

View File

@ -162,6 +162,9 @@ public final class HTTP2FramePayloadToHTTPClientCodec: ChannelDuplexHandler, Rem
} }
} }
@available(*, unavailable)
extension HTTP2FramePayloadToHTTPClientCodec: Sendable {}
// MARK: - Server // MARK: - Server
private struct BaseServerCodec { private struct BaseServerCodec {
@ -280,6 +283,9 @@ public final class HTTP2FramePayloadToHTTPServerCodec: ChannelDuplexHandler, Rem
} }
} }
@available(*, unavailable)
extension HTTP2FramePayloadToHTTPServerCodec: Sendable {}
/// Events that can be sent by the application to be handled by the `HTTP2StreamChannel` /// Events that can be sent by the application to be handled by the `HTTP2StreamChannel`
public struct NIOHTTP2FramePayloadToHTTPEvent: Hashable, Sendable { public struct NIOHTTP2FramePayloadToHTTPEvent: Hashable, Sendable {
private enum Kind: Hashable, Sendable { private enum Kind: Hashable, Sendable {

View File

@ -115,7 +115,7 @@ final class NIOHTTPTypesHTTP1Tests: XCTestCase {
func testClientHTTP1ToHTTP() throws { func testClientHTTP1ToHTTP() throws {
let recorder = InboundRecorder<HTTPResponsePart>() let recorder = InboundRecorder<HTTPResponsePart>()
try self.channel.pipeline.addHandlers(HTTP1ToHTTPClientCodec(), recorder).wait() try self.channel.pipeline.syncOperations.addHandlers(HTTP1ToHTTPClientCodec(), recorder)
try self.channel.writeOutbound(HTTPRequestPart.head(Self.request)) try self.channel.writeOutbound(HTTPRequestPart.head(Self.request))
try self.channel.writeOutbound(HTTPRequestPart.end(Self.trailers)) try self.channel.writeOutbound(HTTPRequestPart.end(Self.trailers))
@ -135,7 +135,7 @@ final class NIOHTTPTypesHTTP1Tests: XCTestCase {
func testServerHTTP1ToHTTP() throws { func testServerHTTP1ToHTTP() throws {
let recorder = InboundRecorder<HTTPRequestPart>() let recorder = InboundRecorder<HTTPRequestPart>()
try self.channel.pipeline.addHandlers(HTTP1ToHTTPServerCodec(secure: true), recorder).wait() try self.channel.pipeline.syncOperations.addHandlers(HTTP1ToHTTPServerCodec(secure: true), recorder)
try self.channel.writeInbound(HTTPServerRequestPart.head(Self.oldRequest)) try self.channel.writeInbound(HTTPServerRequestPart.head(Self.oldRequest))
try self.channel.writeInbound(HTTPServerRequestPart.end(Self.oldTrailers)) try self.channel.writeInbound(HTTPServerRequestPart.end(Self.oldTrailers))
@ -155,7 +155,7 @@ final class NIOHTTPTypesHTTP1Tests: XCTestCase {
func testClientHTTPToHTTP1() throws { func testClientHTTPToHTTP1() throws {
let recorder = InboundRecorder<HTTPClientResponsePart>() let recorder = InboundRecorder<HTTPClientResponsePart>()
try self.channel.pipeline.addHandlers(HTTPToHTTP1ClientCodec(secure: true), recorder).wait() try self.channel.pipeline.syncOperations.addHandlers(HTTPToHTTP1ClientCodec(secure: true), recorder)
try self.channel.writeOutbound(HTTPClientRequestPart.head(Self.oldRequest)) try self.channel.writeOutbound(HTTPClientRequestPart.head(Self.oldRequest))
try self.channel.writeOutbound(HTTPClientRequestPart.end(Self.oldTrailers)) try self.channel.writeOutbound(HTTPClientRequestPart.end(Self.oldTrailers))
@ -175,7 +175,7 @@ final class NIOHTTPTypesHTTP1Tests: XCTestCase {
func testServerHTTPToHTTP1() throws { func testServerHTTPToHTTP1() throws {
let recorder = InboundRecorder<HTTPServerRequestPart>() let recorder = InboundRecorder<HTTPServerRequestPart>()
try self.channel.pipeline.addHandlers(HTTPToHTTP1ServerCodec(), recorder).wait() try self.channel.pipeline.syncOperations.addHandlers(HTTPToHTTP1ServerCodec(), recorder)
try self.channel.writeInbound(HTTPRequestPart.head(Self.request)) try self.channel.writeInbound(HTTPRequestPart.head(Self.request))
try self.channel.writeInbound(HTTPRequestPart.end(Self.trailers)) try self.channel.writeInbound(HTTPRequestPart.end(Self.trailers))

View File

@ -112,7 +112,7 @@ final class NIOHTTPTypesHTTP2Tests: XCTestCase {
func testClientHTTP2ToHTTP() throws { func testClientHTTP2ToHTTP() throws {
let recorder = InboundRecorder<HTTPResponsePart>() let recorder = InboundRecorder<HTTPResponsePart>()
try self.channel.pipeline.addHandlers(HTTP2FramePayloadToHTTPClientCodec(), recorder).wait() try self.channel.pipeline.syncOperations.addHandlers(HTTP2FramePayloadToHTTPClientCodec(), recorder)
try self.channel.writeOutbound(HTTPRequestPart.head(Self.request)) try self.channel.writeOutbound(HTTPRequestPart.head(Self.request))
try self.channel.writeOutbound(HTTPRequestPart.end(Self.trailers)) try self.channel.writeOutbound(HTTPRequestPart.end(Self.trailers))
@ -139,7 +139,7 @@ final class NIOHTTPTypesHTTP2Tests: XCTestCase {
func testServerHTTP2ToHTTP() throws { func testServerHTTP2ToHTTP() throws {
let recorder = InboundRecorder<HTTPRequestPart>() let recorder = InboundRecorder<HTTPRequestPart>()
try self.channel.pipeline.addHandlers(HTTP2FramePayloadToHTTPServerCodec(), recorder).wait() try self.channel.pipeline.syncOperations.addHandlers(HTTP2FramePayloadToHTTPServerCodec(), recorder)
try self.channel.writeInbound(HTTP2Frame.FramePayload(headers: Self.oldRequest)) try self.channel.writeInbound(HTTP2Frame.FramePayload(headers: Self.oldRequest))
try self.channel.writeInbound(HTTP2Frame.FramePayload(headers: Self.oldTrailers)) try self.channel.writeInbound(HTTP2Frame.FramePayload(headers: Self.oldTrailers))