diff --git a/Package.swift b/Package.swift index 50eec46..be6d235 100644 --- a/Package.swift +++ b/Package.swift @@ -49,11 +49,11 @@ let package = Package( dependencies: [ .package( url: "https://github.com/apple/swift-http-api-proposal.git", - revision: "140b8c2aa773514e2464c15db8d94f4eca46d4a1" + revision: "d58fd6fa157e08bff44aa360ff83ebd424783392" ), .package( url: "https://github.com/apple/swift-async-algorithms.git", - from: "1.1.4", + revision: "3bd2de010e30f8d41481e6c7a49a7e7222a878cf", traits: ["UnstableAsyncStreaming"] ), .package(url: "https://github.com/apple/swift-http-types.git", from: "1.0.0"), diff --git a/Sources/Example/Example.swift b/Sources/Example/Example.swift index 25c3e67..d7b3bc8 100644 --- a/Sources/Example/Example.swift +++ b/Sources/Example/Example.swift @@ -22,7 +22,7 @@ import NIOHTTPServer import X509 @main -@available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) +@available(anyAppleOS 26.0, *) struct Example { static func main() async throws { try await serve() diff --git a/Sources/NIOHTTPServer/Configuration/NIOHTTPServer+SwiftConfiguration.swift b/Sources/NIOHTTPServer/Configuration/NIOHTTPServer+SwiftConfiguration.swift index 79d4bbe..11dcdbb 100644 --- a/Sources/NIOHTTPServer/Configuration/NIOHTTPServer+SwiftConfiguration.swift +++ b/Sources/NIOHTTPServer/Configuration/NIOHTTPServer+SwiftConfiguration.swift @@ -20,7 +20,7 @@ import NIOHTTP2 import SwiftASN1 public import X509 -@available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) +@available(anyAppleOS 26.0, *) extension NIOHTTPServerConfiguration { /// Initialize the server configuration from a config reader. /// @@ -110,7 +110,7 @@ extension NIOHTTPServerConfiguration { } } -@available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) +@available(anyAppleOS 26.0, *) extension NIOHTTPServerConfiguration.BindTarget { /// Initialize a bind target configuration from a config reader. /// @@ -134,7 +134,7 @@ private enum HTTPVersionKind: String { case http2 } -@available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) +@available(anyAppleOS 26.0, *) extension Set where Element == NIOHTTPServerConfiguration.HTTPVersion { /// Initialize a supported HTTP versions configuration from a config reader. /// @@ -171,7 +171,7 @@ extension Set where Element == NIOHTTPServerConfiguration.HTTPVersion { } } -@available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) +@available(anyAppleOS 26.0, *) extension NIOHTTPServerConfiguration.TransportSecurity { /// Initialize a transport security configuration from a config reader. /// @@ -242,7 +242,7 @@ extension NIOHTTPServerConfiguration.TransportSecurity { } } -@available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) +@available(anyAppleOS 26.0, *) extension NIOHTTPServerConfiguration.TransportSecurity.TLSCredentials { /// Initialize TLS credentials (certificate chain and private key) from a config reader. /// @@ -288,7 +288,7 @@ extension NIOHTTPServerConfiguration.TransportSecurity.TLSCredentials { } } -@available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) +@available(anyAppleOS 26.0, *) extension NIOHTTPServerConfiguration.TransportSecurity.MTLSTrustConfiguration { /// Initialize an mTLS trust configuration from a config reader. /// @@ -360,7 +360,7 @@ extension NIOHTTPServerConfiguration.TransportSecurity.MTLSTrustConfiguration { } } -@available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) +@available(anyAppleOS 26.0, *) extension NIOHTTPServerConfiguration.BackPressureStrategy { /// Initialize the backpressure strategy configuration from a config reader. /// @@ -387,7 +387,7 @@ extension NIOHTTPServerConfiguration.BackPressureStrategy { } } -@available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) +@available(anyAppleOS 26.0, *) extension NIOHTTPServerConfiguration.HTTP2 { /// Initialize a HTTP/2 configuration from a config reader. /// @@ -420,7 +420,7 @@ extension NIOHTTPServerConfiguration.HTTP2 { } } -@available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) +@available(anyAppleOS 26.0, *) extension NIOHTTPServerConfiguration.HTTP2.GracefulShutdownConfiguration { /// Initialize a HTTP/2 graceful shutdown configuration from a config reader. /// @@ -436,7 +436,7 @@ extension NIOHTTPServerConfiguration.HTTP2.GracefulShutdownConfiguration { } } -@available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) +@available(anyAppleOS 26.0, *) extension Set where Element == NIOHTTPServerConfiguration.HTTPVersion { fileprivate enum HTTPVersionKind: String { case http1_1 @@ -444,7 +444,7 @@ extension Set where Element == NIOHTTPServerConfiguration.HTTPVersion { } } -@available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) +@available(anyAppleOS 26.0, *) extension NIOHTTPServerConfiguration.TransportSecurity { fileprivate enum TransportSecurityMode: String { case plaintext @@ -458,7 +458,7 @@ extension NIOHTTPServerConfiguration.TransportSecurity { } } -@available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) +@available(anyAppleOS 26.0, *) extension NIOHTTPServerConfiguration.TransportSecurity.MTLSTrustConfiguration { /// The supported sources for trust roots. fileprivate enum TrustRootsSource: String { @@ -475,7 +475,7 @@ extension NIOHTTPServerConfiguration.TransportSecurity.MTLSTrustConfiguration { } } -@available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) +@available(anyAppleOS 26.0, *) extension CertificateVerificationMode { fileprivate init(_ mode: NIOHTTPServerConfiguration.TransportSecurity.MTLSTrustConfiguration.VerificationMode) { switch mode { diff --git a/Sources/NIOHTTPServer/Configuration/NIOHTTPServerConfiguration.swift b/Sources/NIOHTTPServer/Configuration/NIOHTTPServerConfiguration.swift index d39e39c..d2c7f56 100644 --- a/Sources/NIOHTTPServer/Configuration/NIOHTTPServerConfiguration.swift +++ b/Sources/NIOHTTPServer/Configuration/NIOHTTPServerConfiguration.swift @@ -20,7 +20,7 @@ public import X509 /// /// This structure contains all the necessary configuration options for setting up /// and running ``NIOHTTPServer``, including network binding and TLS settings. -@available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) +@available(anyAppleOS 26.0, *) public struct NIOHTTPServerConfiguration: Sendable { /// Specifies where the server should bind and listen for incoming connections. /// @@ -303,7 +303,7 @@ public struct NIOHTTPServerConfiguration: Sendable { /// /// Indicates whether certificate verification succeeded or failed, and provides associated metadata when verification /// is successful. -@available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) +@available(anyAppleOS 26.0, *) public enum CertificateVerificationResult: Sendable, Hashable { /// Metadata resulting from successful certificate verification. public struct VerificationMetadata: Sendable, Hashable { @@ -367,7 +367,7 @@ public struct CertificateVerificationMode: Sendable { } } -@available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) +@available(anyAppleOS 26.0, *) extension NIOSSL.CertificateVerification { /// Maps ``CertificateVerificationMode`` to the NIOSSL representation. init(_ verificationMode: CertificateVerificationMode) { @@ -380,7 +380,7 @@ extension NIOSSL.CertificateVerification { } } -@available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) +@available(anyAppleOS 26.0, *) extension NIOHTTPServerConfiguration { /// Represents an HTTP version. public struct HTTPVersion: Sendable, Hashable { @@ -438,7 +438,7 @@ extension NIOHTTPServerConfiguration { } } -@available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) +@available(anyAppleOS 26.0, *) extension NIOAsyncSequenceProducerBackPressureStrategies.HighLowWatermark { init(_ backpressureStrategy: NIOHTTPServerConfiguration.BackPressureStrategy) { switch backpressureStrategy.backing { @@ -448,7 +448,7 @@ extension NIOAsyncSequenceProducerBackPressureStrategies.HighLowWatermark { } } -@available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) +@available(anyAppleOS 26.0, *) extension Set where Element == NIOHTTPServerConfiguration.HTTPVersion { /// The ALPN protocol identifiers to advertise during the TLS handshake, derived from the supported HTTP versions. /// diff --git a/Sources/NIOHTTPServer/Configuration/TransportSecurity+MTLSTrustConfiguration.swift b/Sources/NIOHTTPServer/Configuration/TransportSecurity+MTLSTrustConfiguration.swift index 62ad9dc..4e5fec7 100644 --- a/Sources/NIOHTTPServer/Configuration/TransportSecurity+MTLSTrustConfiguration.swift +++ b/Sources/NIOHTTPServer/Configuration/TransportSecurity+MTLSTrustConfiguration.swift @@ -16,7 +16,7 @@ import NIOCore import NIOSSL public import X509 -@available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) +@available(anyAppleOS 26.0, *) extension NIOHTTPServerConfiguration.TransportSecurity { /// Configures how the server verifies client certificates during mTLS. public struct MTLSTrustConfiguration: Sendable { diff --git a/Sources/NIOHTTPServer/Configuration/TransportSecurity+NIOSSL.swift b/Sources/NIOHTTPServer/Configuration/TransportSecurity+NIOSSL.swift index 50692f0..87154de 100644 --- a/Sources/NIOHTTPServer/Configuration/TransportSecurity+NIOSSL.swift +++ b/Sources/NIOHTTPServer/Configuration/TransportSecurity+NIOSSL.swift @@ -16,7 +16,7 @@ import NIOCertificateReloading import NIOSSL import X509 -@available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) +@available(anyAppleOS 26.0, *) extension NIOSSL.TLSConfiguration { /// Creates a `NIOSSL.TLSConfiguration` from the server's TLS credentials and mTLS trust configuration. static func makeServerConfiguration( diff --git a/Sources/NIOHTTPServer/Configuration/TransportSecurity+TLSCredentials.swift b/Sources/NIOHTTPServer/Configuration/TransportSecurity+TLSCredentials.swift index 2928635..735913e 100644 --- a/Sources/NIOHTTPServer/Configuration/TransportSecurity+TLSCredentials.swift +++ b/Sources/NIOHTTPServer/Configuration/TransportSecurity+TLSCredentials.swift @@ -15,7 +15,7 @@ public import NIOCertificateReloading public import X509 -@available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) +@available(anyAppleOS 26.0, *) extension NIOHTTPServerConfiguration.TransportSecurity { /// Represents the server's TLS credentials: a certificate chain and its corresponding private key. /// diff --git a/Sources/NIOHTTPServer/HTTPKeepAliveHandler.swift b/Sources/NIOHTTPServer/HTTPKeepAliveHandler.swift index c51636c..4647f6b 100644 --- a/Sources/NIOHTTPServer/HTTPKeepAliveHandler.swift +++ b/Sources/NIOHTTPServer/HTTPKeepAliveHandler.swift @@ -37,7 +37,7 @@ import NIOHTTPTypes /// /// Informational (1xx) responses pass through unchanged and do not affect buffering /// state. -@available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) +@available(anyAppleOS 26.0, *) final class HTTPKeepAliveHandler: ChannelDuplexHandler { typealias InboundIn = HTTPRequestPart typealias InboundOut = HTTPRequestPart diff --git a/Sources/NIOHTTPServer/HTTPRequestConcludingAsyncReader.swift b/Sources/NIOHTTPServer/HTTPRequestConcludingAsyncReader.swift index d3d609c..40e4b3b 100644 --- a/Sources/NIOHTTPServer/HTTPRequestConcludingAsyncReader.swift +++ b/Sources/NIOHTTPServer/HTTPRequestConcludingAsyncReader.swift @@ -27,7 +27,7 @@ import Synchronization /// and concluding with the HTTP trailer fields received at the end of the request. This type /// follows the ``ConcludingAsyncReader`` pattern, which allows for asynchronous consumption of /// a stream with a conclusive final element. -@available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) +@available(anyAppleOS 26.0, *) public struct HTTPRequestConcludingAsyncReader: ConcludingAsyncReader, ~Copyable { /// A reader for HTTP request body chunks that implements the ``AsyncReader`` protocol. /// diff --git a/Sources/NIOHTTPServer/HTTPResponseConcludingAsyncWriter.swift b/Sources/NIOHTTPServer/HTTPResponseConcludingAsyncWriter.swift index 7e36128..97ddf01 100644 --- a/Sources/NIOHTTPServer/HTTPResponseConcludingAsyncWriter.swift +++ b/Sources/NIOHTTPServer/HTTPResponseConcludingAsyncWriter.swift @@ -29,7 +29,7 @@ import Synchronization /// /// This writer is designed to work with HTTP responses where the body is streamed in chunks /// and potentially followed by trailer fields. -@available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) +@available(anyAppleOS 26.0, *) public struct HTTPResponseConcludingAsyncWriter: ConcludingAsyncWriter, ~Copyable { /// A writer for HTTP response body chunks that implements the ``AsyncWriter`` protocol. /// diff --git a/Sources/NIOHTTPServer/NIOHTTPServer+ConnectionContext.swift b/Sources/NIOHTTPServer/NIOHTTPServer+ConnectionContext.swift index 5f51b67..38fcfe2 100644 --- a/Sources/NIOHTTPServer/NIOHTTPServer+ConnectionContext.swift +++ b/Sources/NIOHTTPServer/NIOHTTPServer+ConnectionContext.swift @@ -16,7 +16,7 @@ import NIOCore import NIOSSL public import X509 -@available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) +@available(anyAppleOS 26.0, *) extension NIOHTTPServer { /// Connection-specific information available during request handling. /// diff --git a/Sources/NIOHTTPServer/NIOHTTPServer+HTTP1_1.swift b/Sources/NIOHTTPServer/NIOHTTPServer+HTTP1_1.swift index c7444c0..625078a 100644 --- a/Sources/NIOHTTPServer/NIOHTTPServer+HTTP1_1.swift +++ b/Sources/NIOHTTPServer/NIOHTTPServer+HTTP1_1.swift @@ -21,7 +21,7 @@ import NIOHTTPTypes import NIOHTTPTypesHTTP1 import NIOPosix -@available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) +@available(anyAppleOS 26.0, *) extension NIOHTTPServer { /// Serves incoming plaintext HTTP/1.1 connections. /// diff --git a/Sources/NIOHTTPServer/NIOHTTPServer+ListeningAddress.swift b/Sources/NIOHTTPServer/NIOHTTPServer+ListeningAddress.swift index 8d2b66f..f3462c9 100644 --- a/Sources/NIOHTTPServer/NIOHTTPServer+ListeningAddress.swift +++ b/Sources/NIOHTTPServer/NIOHTTPServer+ListeningAddress.swift @@ -35,7 +35,7 @@ enum ListeningAddressError: CustomStringConvertible, Error { } } -@available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) +@available(anyAppleOS 26.0, *) extension NIOHTTPServer { func addressesBound(_ addresses: [NIOCore.SocketAddress?]) throws { switch self.listeningAddressState.withLockedValue({ $0.addressesBound(addresses) }) { @@ -63,7 +63,7 @@ extension NIOHTTPServer { } } -@available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) +@available(anyAppleOS 26.0, *) extension NIOHTTPServer { enum State { case idle(EventLoopPromise<[SocketAddress]>) @@ -131,7 +131,7 @@ extension NIOHTTPServer { } } -@available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) +@available(anyAppleOS 26.0, *) extension NIOHTTPServer.SocketAddress { fileprivate init(_ address: NIOCore.SocketAddress?) throws(ListeningAddressError) { guard let address, let port = address.port else { diff --git a/Sources/NIOHTTPServer/NIOHTTPServer+SecureUpgrade.swift b/Sources/NIOHTTPServer/NIOHTTPServer+SecureUpgrade.swift index 8e38c28..0fd8451 100644 --- a/Sources/NIOHTTPServer/NIOHTTPServer+SecureUpgrade.swift +++ b/Sources/NIOHTTPServer/NIOHTTPServer+SecureUpgrade.swift @@ -28,7 +28,7 @@ import NIOSSL import NIOTLS import X509 -@available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) +@available(anyAppleOS 26.0, *) extension NIOHTTPServer { typealias NegotiatedChannel = NIONegotiatedHTTPVersion< NIOAsyncChannel, @@ -354,7 +354,7 @@ extension NIOHTTPServer { } } -@available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) +@available(anyAppleOS 26.0, *) extension NIOHTTPServer { func makeSSLServerHandler( _ tlsConfiguration: TLSConfiguration, diff --git a/Sources/NIOHTTPServer/NIOHTTPServer.swift b/Sources/NIOHTTPServer/NIOHTTPServer.swift index 454b381..cac5e8f 100644 --- a/Sources/NIOHTTPServer/NIOHTTPServer.swift +++ b/Sources/NIOHTTPServer/NIOHTTPServer.swift @@ -79,7 +79,7 @@ import X509 /// } /// } /// ``` -@available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) +@available(anyAppleOS 26.0, *) public struct NIOHTTPServer: HTTPServer { public typealias RequestConcludingReader = HTTPRequestConcludingAsyncReader public typealias ResponseConcludingWriter = HTTPResponseConcludingAsyncWriter @@ -330,7 +330,7 @@ public struct NIOHTTPServer: HTTPServer { } } -@available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) +@available(anyAppleOS 26.0, *) extension NIOHTTP2Handler.Configuration { init(httpServerHTTP2Configuration http2Config: NIOHTTPServerConfiguration.HTTP2) { let clampedTargetWindowSize = Self.clampTargetWindowSize(http2Config.targetWindowSize) diff --git a/Sources/NIOHTTPServer/ServerChannel.swift b/Sources/NIOHTTPServer/ServerChannel.swift index 3cb81ee..339be9a 100644 --- a/Sources/NIOHTTPServer/ServerChannel.swift +++ b/Sources/NIOHTTPServer/ServerChannel.swift @@ -15,7 +15,7 @@ import NIOCore import NIOHTTPTypes -@available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) +@available(anyAppleOS 26.0, *) extension NIOHTTPServer { /// Abstracts over the two types of server channels ``NIOHTTPServer`` can create: plaintext HTTP/1.1 and Secure /// Upgrade. diff --git a/Sources/NIOHTTPServer/SocketAddress.swift b/Sources/NIOHTTPServer/SocketAddress.swift index 98ecc73..3e2384d 100644 --- a/Sources/NIOHTTPServer/SocketAddress.swift +++ b/Sources/NIOHTTPServer/SocketAddress.swift @@ -12,7 +12,7 @@ // //===----------------------------------------------------------------------===// -@available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) +@available(anyAppleOS 26.0, *) extension NIOHTTPServer { /// Represents an IPv4 address. public struct IPv4: Hashable, Sendable { diff --git a/Tests/NIOHTTPServerTests/HTTPKeepAliveHandlerTests.swift b/Tests/NIOHTTPServerTests/HTTPKeepAliveHandlerTests.swift index ceab345..7b3aac8 100644 --- a/Tests/NIOHTTPServerTests/HTTPKeepAliveHandlerTests.swift +++ b/Tests/NIOHTTPServerTests/HTTPKeepAliveHandlerTests.swift @@ -30,7 +30,7 @@ struct HTTPKeepAliveHandlerTests { /// Verifies the happy case: when a client pipelines multiple HTTP/1.1 requests /// on a single connection, all responses are returned in order and the connection /// stays alive (no `Connection: close`). - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) @Test("Pipelined requests on a single connection all succeed") func testPipelinedRequests() async throws { let server = NIOHTTPServer( @@ -100,7 +100,7 @@ struct HTTPKeepAliveHandlerTests { /// Verifies that when the handler writes a short response (head + end, no body) /// before the request `.end` has arrived, the response head includes a /// `Connection: close` header and the server closes the connection. - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) @Test("Server sends head+end (no body) before request .end — Connection: close in header") func testShortResponseBeforeRequestEnd() async throws { let server = NIOHTTPServer( @@ -181,7 +181,7 @@ struct HTTPKeepAliveHandlerTests { /// the request `.end` has arrived; the client must receive that informational /// response immediately (without waiting for request `.end`), and the connection /// must remain alive after the final response. - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) @Test("Informational (1xx) responses pass through without buffering or closing") func testInformationalResponsePassesThrough() async throws { let server = NIOHTTPServer( @@ -294,7 +294,7 @@ struct HTTPKeepAliveHandlerTests { /// everything until request `.end` arrives. Because the head is flushed before /// request `.end` arrives, the response carries `Connection: close` and the /// server closes the connection after writing response `.end`. - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) @Test("Bidirectional streaming works — head is flushed (with Connection: close) when a body part is written") func testBidirectionalStreamingOverHTTP1() async throws { let server = NIOHTTPServer( @@ -390,7 +390,7 @@ struct HTTPKeepAliveHandlerTests { /// server reads the body chunk, the read cycle ends with the head still /// buffered and request `.end` still missing — the keep-alive handler must add /// `Connection: close`. - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) @Test("Read cycle ends without request .end while head is buffered — Connection: close added") func testReadCycleEndsWithoutRequestEnd_AddsConnectionClose() async throws { let server = NIOHTTPServer( diff --git a/Tests/NIOHTTPServerTests/HTTPRequestConcludingAsyncReaderTests.swift b/Tests/NIOHTTPServerTests/HTTPRequestConcludingAsyncReaderTests.swift index f32b030..ed60607 100644 --- a/Tests/NIOHTTPServerTests/HTTPRequestConcludingAsyncReaderTests.swift +++ b/Tests/NIOHTTPServerTests/HTTPRequestConcludingAsyncReaderTests.swift @@ -26,7 +26,7 @@ import Testing @Suite struct HTTPRequestConcludingAsyncReaderTests { @Test("Head request not allowed") - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) func testWriteHeadRequestPartFatalError() async throws { // The request body reader should fatal error if it receives a head part await #expect(processExitsWith: .failure) { @@ -48,7 +48,7 @@ struct HTTPRequestConcludingAsyncReaderTests { } @Test("Stream cannot be finished before writing request end part") - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) func testNotWritingRequestEndPartFatalError() async throws { await #expect(processExitsWith: .failure) { let (stream, source) = NIOAsyncChannelInboundStream.makeTestingStream() @@ -79,7 +79,7 @@ struct HTTPRequestConcludingAsyncReaderTests { HTTPFields([.init(name: .cookie, value: "first_cookie"), .init(name: .cookie, value: "second_cookie")]), ] ) - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) func testRequestWithConcludingElement(body: ByteBuffer, trailers: HTTPFields) async throws { let (stream, source) = NIOAsyncChannelInboundStream.makeTestingStream() @@ -122,7 +122,7 @@ struct HTTPRequestConcludingAsyncReaderTests { HTTPFields([.init(name: .cookie, value: "first_cookie"), .init(name: .cookie, value: "second_cookie")]), ] ) - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) func testStreamedRequestBody(bodyChunks: [ByteBuffer], trailers: HTTPFields) async throws { let (stream, source) = NIOAsyncChannelInboundStream.makeTestingStream() @@ -158,7 +158,7 @@ struct HTTPRequestConcludingAsyncReaderTests { } @Test("Throw while reading request") - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) func testThrowingWhileReadingRequest() async throws { let (stream, source) = NIOAsyncChannelInboundStream.makeTestingStream() @@ -189,7 +189,7 @@ struct HTTPRequestConcludingAsyncReaderTests { } } - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) @Test("More bytes available than consumption limit") func testCollectMoreBytesThanAvailable() async throws { let (stream, source) = NIOAsyncChannelInboundStream.makeTestingStream() diff --git a/Tests/NIOHTTPServerTests/HTTPResponseConcludingAsyncWriterTests.swift b/Tests/NIOHTTPServerTests/HTTPResponseConcludingAsyncWriterTests.swift index 6be2a18..c986b7f 100644 --- a/Tests/NIOHTTPServerTests/HTTPResponseConcludingAsyncWriterTests.swift +++ b/Tests/NIOHTTPServerTests/HTTPResponseConcludingAsyncWriterTests.swift @@ -28,7 +28,7 @@ struct HTTPResponseConcludingAsyncWriterTests { let trailerSampleTwo: HTTPFields = [.serverTiming: "test", .cookie: "cookie"] @Test("Write single body element") - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) func testSingleWriteAndConclude() async throws { let (writer, sink) = NIOAsyncChannelOutboundWriter.makeTestingWriter() let responseWriter = HTTPResponseConcludingAsyncWriter(writer: writer, writerState: .init()) @@ -46,7 +46,7 @@ struct HTTPResponseConcludingAsyncWriterTests { } @Test("Write multiple body elements") - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) func testProduceMultipleElementsAndSingleTrailer() async throws { let (writer, sink) = NIOAsyncChannelOutboundWriter.makeTestingWriter() let responseWriter = HTTPResponseConcludingAsyncWriter(writer: writer, writerState: .init()) @@ -73,7 +73,7 @@ struct HTTPResponseConcludingAsyncWriterTests { } @Test("Throw while writing response") - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) func testThrowWhileProducing() async throws { let (writer, sink) = NIOAsyncChannelOutboundWriter.makeTestingWriter() @@ -97,7 +97,7 @@ struct HTTPResponseConcludingAsyncWriterTests { } @Test("Write multiple elements and multiple trailers") - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) func testProduceMultipleElementsAndMultipleTrailers() async throws { let (writer, sink) = NIOAsyncChannelOutboundWriter.makeTestingWriter() let responseWriter = HTTPResponseConcludingAsyncWriter(writer: writer, writerState: .init()) @@ -124,7 +124,7 @@ struct HTTPResponseConcludingAsyncWriterTests { } @Test("No body, just trailers") - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) func testNoBodyJustTrailers() async throws { let (writer, sink) = NIOAsyncChannelOutboundWriter.makeTestingWriter() let responseWriter = HTTPResponseConcludingAsyncWriter(writer: writer, writerState: .init()) diff --git a/Tests/NIOHTTPServerTests/HTTPResponseSenderTests.swift b/Tests/NIOHTTPServerTests/HTTPResponseSenderTests.swift index b22303f..3a7d55f 100644 --- a/Tests/NIOHTTPServerTests/HTTPResponseSenderTests.swift +++ b/Tests/NIOHTTPServerTests/HTTPResponseSenderTests.swift @@ -23,7 +23,7 @@ import Testing @Suite struct HTTPResponseSenderTests { @Test("Informational header without informational status code") - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) func testInformationalResponseStatusCodePrecondition() async throws { // Sending an informational header with a non-1xx status code shouldn't be allowed try await #require(processExitsWith: .failure) { @@ -43,7 +43,7 @@ struct HTTPResponseSenderTests { } @Test("Multiple informational responses before final response") - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) func testSendMultipleInformationalResponses() async throws { let (outboundWriter, sink) = NIOAsyncChannelOutboundWriter.makeTestingWriter() let sender = HTTPResponseSender { response in diff --git a/Tests/NIOHTTPServerTests/HTTPServerTests.swift b/Tests/NIOHTTPServerTests/HTTPServerTests.swift index dc85fec..2c120bc 100644 --- a/Tests/NIOHTTPServerTests/HTTPServerTests.swift +++ b/Tests/NIOHTTPServerTests/HTTPServerTests.swift @@ -20,7 +20,7 @@ import Testing @Suite struct HTTPServerTests { @Test - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) func testConsumingServe() async throws { let server = NIOHTTPServer( logger: Logger(label: "Test"), diff --git a/Tests/NIOHTTPServerTests/NIOHTTPServer+ServiceLifecycleTests.swift b/Tests/NIOHTTPServerTests/NIOHTTPServer+ServiceLifecycleTests.swift index 40c9f1f..22cf55d 100644 --- a/Tests/NIOHTTPServerTests/NIOHTTPServer+ServiceLifecycleTests.swift +++ b/Tests/NIOHTTPServerTests/NIOHTTPServer+ServiceLifecycleTests.swift @@ -36,7 +36,7 @@ struct NIOHTTPServiceLifecycleTests { let serviceGroupLogger = Logger(label: "Test ServiceGroup") @Test("HTTP/1.1 active connection completes when graceful shutdown triggered", ) - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) func activeHTTP1ConnectionCanCompleteWhenGracefulShutdown() async throws { let server = NIOHTTPServer( logger: self.serverLogger, @@ -125,7 +125,7 @@ struct NIOHTTPServiceLifecycleTests { } @Test("HTTP/1.1 active connection forcefully shutdown when server task cancelled") - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) func activeHTTP1ConnectionForcefullyShutdownWhenServerTaskCancelled() async throws { let server = NIOHTTPServer( logger: self.serverLogger, @@ -206,7 +206,7 @@ struct NIOHTTPServiceLifecycleTests { } @Test("Active HTTP/2 connection is forcefully shut down upon graceful shutdown timeout") - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) func testActiveHTTP2ConnectionIsShutDownAfterGraceTimeout() async throws { let serverChain = try TestCA.makeSelfSignedChain() diff --git a/Tests/NIOHTTPServerTests/NIOHTTPServerEndToEndTests.swift b/Tests/NIOHTTPServerTests/NIOHTTPServerEndToEndTests.swift index 8bf9f74..f2fa748 100644 --- a/Tests/NIOHTTPServerTests/NIOHTTPServerEndToEndTests.swift +++ b/Tests/NIOHTTPServerTests/NIOHTTPServerEndToEndTests.swift @@ -21,7 +21,7 @@ import Testing @Suite struct NIOHTTPServerEndToEndTests { - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) @Test("HTTP/1.1 request and response") func testHTTP1_1() async throws { try await TestingChannelHTTP1Server.serve( @@ -69,7 +69,7 @@ struct NIOHTTPServerEndToEndTests { } } - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) @Test("HTTP/2 negotiation") func testHTTP2Negotiation() async throws { let serverChain = try TestCA.makeSelfSignedChain() diff --git a/Tests/NIOHTTPServerTests/NIOHTTPServerSwiftConfigurationTests.swift b/Tests/NIOHTTPServerTests/NIOHTTPServerSwiftConfigurationTests.swift index d71edb4..f910ce3 100644 --- a/Tests/NIOHTTPServerTests/NIOHTTPServerSwiftConfigurationTests.swift +++ b/Tests/NIOHTTPServerTests/NIOHTTPServerSwiftConfigurationTests.swift @@ -28,7 +28,7 @@ struct NIOHTTPServerSwiftConfigurationTests { @Suite("BindTarget") struct BindTargetTests { @Test("Valid host and port") - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) func testValidConfig() throws { let provider = InMemoryProvider(values: ["host": "localhost", "port": 8080]) @@ -45,7 +45,7 @@ struct NIOHTTPServerSwiftConfigurationTests { } @Test("Init fails with missing host") - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) func testMissingHost() throws { let provider = InMemoryProvider(values: ["port": 8080]) let config = ConfigReader(provider: provider) @@ -59,7 +59,7 @@ struct NIOHTTPServerSwiftConfigurationTests { } @Test("Init fails with missing port") - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) func testMissingPort() throws { let provider = InMemoryProvider(values: ["host": "localhost"]) let config = ConfigReader(provider: provider) @@ -76,7 +76,7 @@ struct NIOHTTPServerSwiftConfigurationTests { @Suite("Multiple bind targets via bindTargets") struct MultipleBindTargetsTests { @Test("Parallel hosts and ports produce multiple bind targets") - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) func testMultipleBindTargets() throws { let provider = InMemoryProvider( values: [ @@ -107,7 +107,7 @@ struct NIOHTTPServerSwiftConfigurationTests { } @Test("Singular bindTarget still works") - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) func testSingularBindTargetStillWorks() throws { let provider = InMemoryProvider( values: [ @@ -131,7 +131,7 @@ struct NIOHTTPServerSwiftConfigurationTests { } @Test("Providing both singular and plural throws an error") - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) func testBothSingularAndPluralThrows() throws { let provider = InMemoryProvider( values: [ @@ -151,7 +151,7 @@ struct NIOHTTPServerSwiftConfigurationTests { } @Test("Mismatched hosts and ports lengths throws an error") - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) func testMismatchedHostsAndPortsLengthsThrows() throws { let provider = InMemoryProvider( values: [ @@ -169,7 +169,7 @@ struct NIOHTTPServerSwiftConfigurationTests { } @Test("Empty bindTargets arrays throws an error") - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) func testEmptyBindTargetsArraysThrows() throws { let provider = InMemoryProvider( values: [ @@ -190,7 +190,7 @@ struct NIOHTTPServerSwiftConfigurationTests { @Suite("BackPressureStrategy") struct BackPressureStrategyTests { @Test("Default values") - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) func testDefaultValues() throws { // Don't provide anything. All values have defaults. let provider = InMemoryProvider(values: [:]) @@ -207,7 +207,7 @@ struct NIOHTTPServerSwiftConfigurationTests { } @Test("Custom values") - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) func testCustomValues() throws { let provider = InMemoryProvider(values: ["lowWatermark": 5, "highWatermark": 20]) let config = ConfigReader(provider: provider) @@ -223,7 +223,7 @@ struct NIOHTTPServerSwiftConfigurationTests { } @Test("Partial custom values") - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) func testPartialCustomValues() throws { let provider = InMemoryProvider(values: ["lowWatermark": 3]) let config = ConfigReader(provider: provider) @@ -242,7 +242,7 @@ struct NIOHTTPServerSwiftConfigurationTests { @Suite("SupportedHTTPVersions") struct SupportedHTTPVersionsTests { @Test("Empty supported version set is invalid") - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) func testEmptySupportedHTTPVersionSetFails() async { await #expect(processExitsWith: .failure) { let provider = InMemoryProvider(values: [ @@ -256,7 +256,7 @@ struct NIOHTTPServerSwiftConfigurationTests { } @Test("Unrecognized versions are ignored") - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) func testUnrecognizedHTTPVersionIgnored() throws { let provider = InMemoryProvider(values: [ "versions": .init(.stringArray(["unrecognized_version"]), isSecret: false) @@ -273,7 +273,7 @@ struct NIOHTTPServerSwiftConfigurationTests { } @Test("Default HTTP/2 configuration used when not specified") - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) func testDefaultHTTP2ConfigurationUsed() throws { let provider = InMemoryProvider(values: [ "versions": .init(.stringArray(["http1_1", "http2"]), isSecret: false) @@ -290,7 +290,7 @@ struct NIOHTTPServerSwiftConfigurationTests { @Suite("HTTP2") struct HTTP2Tests { @Test("Default values") - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) func testDefaultValues() throws { let provider = InMemoryProvider(values: [:]) let config = ConfigReader(provider: provider) @@ -305,7 +305,7 @@ struct NIOHTTPServerSwiftConfigurationTests { } @Test("Custom values") - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) func testCustomValues() throws { let provider = InMemoryProvider(values: [ "maxFrameSize": 1, @@ -325,7 +325,7 @@ struct NIOHTTPServerSwiftConfigurationTests { } @Test("Partial custom values") - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) func testPartialCustomValues() throws { let provider = InMemoryProvider(values: ["maxFrameSize": 5]) let config = ConfigReader(provider: provider) @@ -343,7 +343,7 @@ struct NIOHTTPServerSwiftConfigurationTests { @Suite("TransportSecurity") struct TransportSecurityTests { @Test("Invalid security mode") - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) func testInvalidSecurityMode() throws { let provider = InMemoryProvider(values: ["mode": ""]) let config = ConfigReader(provider: provider) @@ -357,7 +357,7 @@ struct NIOHTTPServerSwiftConfigurationTests { } @Test("Custom verification callback without mTLS being enabled") - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) func testCannotInitializeWithCustomCallbackWhenMTLSNotEnabled() throws { let provider = InMemoryProvider(values: ["mode": "tls", "credentialSource": "inline"]) let config = ConfigReader(provider: provider) @@ -382,7 +382,7 @@ struct NIOHTTPServerSwiftConfigurationTests { @Suite struct TLS { @Test("Valid config using inline credentials") - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) func testValidConfigUsingInlineCredentials() throws { let chain = try TestCA.makeSelfSignedChain() let certsPEM = try chain.chainPEMString @@ -416,7 +416,7 @@ struct NIOHTTPServerSwiftConfigurationTests { } @Test("Valid file-based credentials with reloading") - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) func testValidFileConfigWithReloading() async throws { let provider = InMemoryProvider( values: [ @@ -444,7 +444,7 @@ struct NIOHTTPServerSwiftConfigurationTests { } @Test("Valid file-based credentials without reloading") - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) func testValidFileConfigWithoutReloading() throws { let provider = InMemoryProvider( values: [ @@ -471,7 +471,7 @@ struct NIOHTTPServerSwiftConfigurationTests { } @Test("Init fails with missing certificate") - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) func testMissingCertificate() throws { let chain = try TestCA.makeSelfSignedChain() let keyPEM = try chain.privateKey.serializeAsPEM().pemString @@ -494,7 +494,7 @@ struct NIOHTTPServerSwiftConfigurationTests { } @Test("Init fails with missing private key") - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) func testMissingPrivateKey() throws { let chain = try TestCA.makeSelfSignedChain() let certsPEM = try chain.chainPEMString @@ -520,7 +520,7 @@ struct NIOHTTPServerSwiftConfigurationTests { @Suite struct MTLS { @Test("Custom verification callback") - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) func testValidConfigWithCustomVerificationCallback() throws { let serverChain = try TestCA.makeSelfSignedChain() @@ -572,7 +572,7 @@ struct NIOHTTPServerSwiftConfigurationTests { } @Test("Optional verification mode") - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) func testOptionalVerification() throws { let serverChain = try TestCA.makeSelfSignedChain() let certsPEM = try serverChain.chainPEMString @@ -614,7 +614,7 @@ struct NIOHTTPServerSwiftConfigurationTests { } @Test("Invalid verification mode") - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) func testInvalidVerificationMode() throws { let serverChain = try TestCA.makeSelfSignedChain() @@ -645,7 +645,7 @@ struct NIOHTTPServerSwiftConfigurationTests { } @Test("Default trust roots") - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) func testDefaultTrustRoots() throws { let serverChain = try TestCA.makeSelfSignedChain() @@ -687,7 +687,7 @@ struct NIOHTTPServerSwiftConfigurationTests { } @Test("Trust roots from PEM file path") - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) func testTrustRootsFromPEMFilePath() throws { let serverChain = try TestCA.makeSelfSignedChain() @@ -730,7 +730,7 @@ struct NIOHTTPServerSwiftConfigurationTests { @Suite struct ReloadingMTLS { @Test("Valid config with file credentials and reloading") - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) func testValidConfig() async throws { let chain = try TestCA.makeSelfSignedChain() let trustRootPEM = try chain.ca.serializeAsPEM().pemString @@ -774,7 +774,7 @@ struct NIOHTTPServerSwiftConfigurationTests { @Suite("End-to-End") struct EndToEndConfigurationTests { @Test("Configure all possible values") - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) func fullConfiguration() throws { let chain = try TestCA.makeSelfSignedChain() let certsPEM = try chain.chainPEMString @@ -843,7 +843,7 @@ struct NIOHTTPServerSwiftConfigurationTests { } @Test("Only HTTP/1.1 supported over plaintext") - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) func onlyHTTP1_1SupportedOverPlaintext() async { await #expect(processExitsWith: .failure) { let provider = InMemoryProvider( diff --git a/Tests/NIOHTTPServerTests/NIOHTTPServerTests.swift b/Tests/NIOHTTPServerTests/NIOHTTPServerTests.swift index 52d3fa1..efb78aa 100644 --- a/Tests/NIOHTTPServerTests/NIOHTTPServerTests.swift +++ b/Tests/NIOHTTPServerTests/NIOHTTPServerTests.swift @@ -35,7 +35,7 @@ import X509 struct NIOHTTPServerTests { let serverLogger = Logger(label: "NIOHTTPServerTests") - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) @Test("Obtain the listening address correctly") func testListeningAddress() async throws { let server = NIOHTTPServer( @@ -64,7 +64,7 @@ struct NIOHTTPServerTests { } @Test("Plaintext request-response") - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) func testPlaintext() async throws { let server = NIOHTTPServer( logger: Logger(label: "NIOHTTPServerTests"), @@ -118,7 +118,7 @@ struct NIOHTTPServerTests { ) } - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) @Test( "mTLS request-response with custom verification callback returning peer certificates", arguments: [HTTPVersion.http1_1, HTTPVersion.http2] @@ -202,7 +202,7 @@ struct NIOHTTPServerTests { } } - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) @Test("Multiple informational response headers", arguments: [HTTPVersion.http1_1, HTTPVersion.http2]) func testMultipleInformationalResponseHeaders(httpVersion: HTTPVersion) async throws { let (server, serverChain) = try self.makeSecureUpgradeServer() @@ -252,7 +252,7 @@ struct NIOHTTPServerTests { } } - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) @Test("Client closes stream without sending end part", arguments: [HTTPVersion.http1_1, HTTPVersion.http2]) func testRequestWithoutEndPart(httpVersion: HTTPVersion) async throws { let (server, serverChain) = try self.makeSecureUpgradeServer() @@ -310,7 +310,7 @@ struct NIOHTTPServerTests { } } - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) @Test("Bi-directional streaming", arguments: [HTTPVersion.http1_1, HTTPVersion.http2]) func testBidirectionalStreaming(httpVersion: HTTPVersion) async throws { let (server, serverChain) = try self.makeSecureUpgradeServer() @@ -374,7 +374,7 @@ struct NIOHTTPServerTests { ) } - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) @Test("Multiple serial HTTP/1.1 requests on the same connection") func testMultipleSerialHTTP1Requests() async throws { let server = NIOHTTPServer( @@ -428,7 +428,7 @@ struct NIOHTTPServerTests { } } - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) @Test("Multiple concurrent connections", arguments: [HTTPVersion.http1_1, HTTPVersion.http2]) func testMultipleConcurrentConnections(httpVersion: HTTPVersion) async throws { let (server, serverChain) = try self.makeSecureUpgradeServer() @@ -497,7 +497,7 @@ struct NIOHTTPServerTests { } } - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) @Test("Multiple concurrent HTTP/2 streams") func testMultipleConcurrentHTTP2Streams() async throws { let (server, serverChain) = try self.makeSecureUpgradeServer() @@ -567,7 +567,7 @@ struct NIOHTTPServerTests { } } - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) @Test("Server can still process other connections despite one failing") func testServerCanContinueDespiteFailedConnection() async throws { let server = try self.makePlaintextHTTP1Server() @@ -626,7 +626,7 @@ struct NIOHTTPServerTests { ) } - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) @Test("Bind to multiple addresses") func testMultipleBindAddresses() async throws { let server = NIOHTTPServer( @@ -651,7 +651,7 @@ struct NIOHTTPServerTests { ) } - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) @Test("Serve requests on multiple addresses independently") func testServeOnMultipleAddresses() async throws { let server = NIOHTTPServer( @@ -721,7 +721,7 @@ struct NIOHTTPServerTests { /// all bound addresses become unavailable simultaneously and ``listeningAddresses`` throws /// ``ListeningAddressError/serverClosed``. No subset of addresses continues serving after the server /// has stopped. - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) @Test("All addresses stop together and listeningAddresses throws after server stops") func testAllAddressesStopTogether() async throws { let server = NIOHTTPServer( @@ -774,7 +774,7 @@ struct NIOHTTPServerTests { } } - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) @Test("Empty bind targets throws error") func testEmptyBindTargetsThrows() throws { #expect(throws: NIOHTTPServerConfigurationError.noBindTargetsSpecified) { @@ -799,7 +799,7 @@ struct NIOHTTPServerTests { /// to for the verification. The port is below the typical ephemeral range used by `port: 0` /// allocations on Linux (32768+) and macOS (49152+), so other tests using `port: 0` cannot /// accidentally be assigned this port by the OS. - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) @Test("Previously bound channels are closed when a later bind fails") func testPreviouslyBoundChannelsAreClosedOnPartialBindFailure() async throws { let firstPort = 30_210 @@ -852,7 +852,7 @@ extension NIOHTTPServerTests { static let trailer: HTTPFields = [.trailer: "test_trailer"] static let reqEnd = HTTPRequestPart.end(trailer) - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) func makePlaintextHTTP1Server() throws -> NIOHTTPServer { let server = NIOHTTPServer( logger: self.serverLogger, @@ -866,7 +866,7 @@ extension NIOHTTPServerTests { return server } - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) func makeSecureUpgradeServer() throws -> (NIOHTTPServer, ChainPrivateKeyPair) { let serverChain = try TestCA.makeSelfSignedChain() @@ -973,7 +973,7 @@ extension NIOHTTPServerTests { /// Starts `server` with `serverHandler`, waits for it to begin listening, runs `body` with the first /// listening address, then cancels the server task. - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) static func withServer( server: NIOHTTPServer, serverHandler: some HTTPServerRequestHandler< @@ -991,7 +991,7 @@ extension NIOHTTPServerTests { /// Starts `server` with `serverHandler`, waits for it to begin listening, runs `body` with all listening /// addresses, then cancels the server task. - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) static func withServer( server: NIOHTTPServer, serverHandler: some HTTPServerRequestHandler< @@ -1014,7 +1014,7 @@ extension NIOHTTPServerTests { } /// Reads the full request body and trailers from `reader`, then sends a `200 OK` response echoing them back. - @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) + @available(anyAppleOS 26.0, *) static func echoResponse( readUpTo limit: Int, reader: consuming HTTPRequestConcludingAsyncReader, diff --git a/Tests/NIOHTTPServerTests/Utilities/NIOClient/NIOClient+HTTP1.swift b/Tests/NIOHTTPServerTests/Utilities/NIOClient/NIOClient+HTTP1.swift index 7e48726..a4dadf7 100644 --- a/Tests/NIOHTTPServerTests/Utilities/NIOClient/NIOClient+HTTP1.swift +++ b/Tests/NIOHTTPServerTests/Utilities/NIOClient/NIOClient+HTTP1.swift @@ -19,7 +19,7 @@ import NIOHTTPTypes import NIOHTTPTypesHTTP1 import NIOPosix -@available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) +@available(anyAppleOS 26.0, *) extension Channel { /// Adds HTTP/1.1 client handlers to the pipeline. func configureTestHTTP1ClientPipeline( @@ -48,7 +48,7 @@ extension Channel { } } -@available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) +@available(anyAppleOS 26.0, *) extension ClientBootstrap { /// Connects to the provided `serverAddress` and provides a `NIOAsyncChannel`. With this ``NIOAsyncChannel``, one /// can write `HTTPRequestPart`s to the server and observe `HTTPResponsePart`s from the inbound stream of the diff --git a/Tests/NIOHTTPServerTests/Utilities/NIOClient/NIOClient+SecureUpgrade.swift b/Tests/NIOHTTPServerTests/Utilities/NIOClient/NIOClient+SecureUpgrade.swift index 6631a0d..63c34a2 100644 --- a/Tests/NIOHTTPServerTests/Utilities/NIOClient/NIOClient+SecureUpgrade.swift +++ b/Tests/NIOHTTPServerTests/Utilities/NIOClient/NIOClient+SecureUpgrade.swift @@ -21,7 +21,7 @@ import X509 @testable import NIOHTTPServer -@available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) +@available(anyAppleOS 26.0, *) /// Provides a HTTP client with ALPN negotiation. extension Channel { /// Adds a ``NIOSSLClientHandler`` configured with the provided `TLSConfiguration` to the pipeline. @@ -53,7 +53,7 @@ extension Channel { } } -@available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) +@available(anyAppleOS 26.0, *) extension ClientBootstrap { /// Connects the client to the specified address using the provided TLS configuration. func connectToTestSecureUpgradeHTTPServer( diff --git a/Tests/NIOHTTPServerTests/Utilities/TestingChannelClientServer/NIOHTTPServer+HTTP1.swift b/Tests/NIOHTTPServerTests/Utilities/TestingChannelClientServer/NIOHTTPServer+HTTP1.swift index a698443..44233ce 100644 --- a/Tests/NIOHTTPServerTests/Utilities/TestingChannelClientServer/NIOHTTPServer+HTTP1.swift +++ b/Tests/NIOHTTPServerTests/Utilities/TestingChannelClientServer/NIOHTTPServer+HTTP1.swift @@ -19,7 +19,7 @@ import NIOHTTPTypes @testable import HTTPAPIs @testable import NIOHTTPServer -@available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) +@available(anyAppleOS 26.0, *) extension NIOHTTPServer { /// Starts serving plaintext HTTP/1.1 using the provided testing channel instead of using `ServerBootstrap` as /// `NIOHTTPServer` normally does. diff --git a/Tests/NIOHTTPServerTests/Utilities/TestingChannelClientServer/NIOHTTPServer+SecureUpgrade.swift b/Tests/NIOHTTPServerTests/Utilities/TestingChannelClientServer/NIOHTTPServer+SecureUpgrade.swift index 71af635..1d0a443 100644 --- a/Tests/NIOHTTPServerTests/Utilities/TestingChannelClientServer/NIOHTTPServer+SecureUpgrade.swift +++ b/Tests/NIOHTTPServerTests/Utilities/TestingChannelClientServer/NIOHTTPServer+SecureUpgrade.swift @@ -19,7 +19,7 @@ import NIOHTTPTypes @testable import HTTPAPIs @testable import NIOHTTPServer -@available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) +@available(anyAppleOS 26.0, *) extension NIOHTTPServer { /// Starts serving with the Secure Upgrade transport using the provided testing channel instead of using /// `ServerBootstrap` as `NIOHTTPServer` normally does. diff --git a/Tests/NIOHTTPServerTests/Utilities/TestingChannelClientServer/TestingChannelServer+HTTP1.swift b/Tests/NIOHTTPServerTests/Utilities/TestingChannelClientServer/TestingChannelServer+HTTP1.swift index 1892b35..3d90ff3 100644 --- a/Tests/NIOHTTPServerTests/Utilities/TestingChannelClientServer/TestingChannelServer+HTTP1.swift +++ b/Tests/NIOHTTPServerTests/Utilities/TestingChannelClientServer/TestingChannelServer+HTTP1.swift @@ -32,7 +32,7 @@ import NIOHTTPTypes /// This provider vends a HTTP client channel (also backed by a `NIOAsyncTestingChannel`) that can be used to send /// requests and observe responses in terms of HTTP types (`HTTPRequestPart` and `HTTPResponsePart`) to the server /// connection channel. -@available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) +@available(anyAppleOS 26.0, *) struct TestingChannelHTTP1Server { let server: NIOHTTPServer let serverTestChannel: NIOAsyncTestingChannel diff --git a/Tests/NIOHTTPServerTests/Utilities/TestingChannelClientServer/TestingChannelServer+SecureUpgrade.swift b/Tests/NIOHTTPServerTests/Utilities/TestingChannelClientServer/TestingChannelServer+SecureUpgrade.swift index a7b2b67..df932b1 100644 --- a/Tests/NIOHTTPServerTests/Utilities/TestingChannelClientServer/TestingChannelServer+SecureUpgrade.swift +++ b/Tests/NIOHTTPServerTests/Utilities/TestingChannelClientServer/TestingChannelServer+SecureUpgrade.swift @@ -24,7 +24,7 @@ import X509 @testable import NIOHTTPServer /// Like ``TestingChannelHTTP1Server``, but for Secure Upgrade. -@available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) +@available(anyAppleOS 26.0, *) struct TestingChannelSecureUpgradeServer { let server: NIOHTTPServer let serverTestChannel: NIOAsyncTestingChannel