Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 37 additions & 29 deletions Tests/NIOHTTPServerTests/NIOHTTPServer+ServiceLifecycleTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@ struct NIOHTTPServiceLifecycleTests {

let serverAddress = try await server.listeningAddress

let client = try await setUpClient(host: serverAddress.host, port: serverAddress.port)
let client = try await ClientBootstrap(group: .singletonMultiThreadedEventLoopGroup)
.connectToTestHTTP1Server(at: serverAddress)

try await client.executeThenClose { inbound, outbound in
try await outbound.write(Self.reqHead)
Expand Down Expand Up @@ -160,7 +161,8 @@ struct NIOHTTPServiceLifecycleTests {

let serverAddress = try await server.listeningAddress

let client = try await setUpClient(host: serverAddress.host, port: serverAddress.port)
let client = try await ClientBootstrap(group: .singletonMultiThreadedEventLoopGroup)
.connectToTestHTTP1Server(at: serverAddress)

try await client.executeThenClose { inbound, outbound in
try await outbound.write(Self.reqHead)
Expand Down Expand Up @@ -191,7 +193,6 @@ struct NIOHTTPServiceLifecycleTests {
@available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *)
func testActiveHTTP2ConnectionIsShutDownAfterGraceTimeout() async throws {
let serverChain = try TestCA.makeSelfSignedChain()
let clientChain = try TestCA.makeSelfSignedChain()

let server = NIOHTTPServer(
logger: self.serverLogger,
Expand Down Expand Up @@ -235,34 +236,41 @@ struct NIOHTTPServiceLifecycleTests {

let serverAddress = try await server.listeningAddress

let client = try await setUpClientWithMTLS(
at: serverAddress,
chain: clientChain,
trustRoots: [serverChain.ca],
applicationProtocol: "h2"
)

try await client.executeThenClose { inbound, outbound in
try await outbound.write(Self.reqHead)
try await outbound.write(Self.reqBody)

// Wait until the server has received the request.
try await firstChunkReadPromise.futureResult.get()

// Now trigger graceful shutdown. This should propagate down to the server. The server will
// start the 500ms grace timer after which all connections that are still open will be
// forcefully closed.
trigger.triggerGracefulShutdown()

// The server should shut down after 500ms. Wait for this.
try await group.waitForAll()
let client = try await ClientBootstrap(group: .singletonMultiThreadedEventLoopGroup)
.connectToTestSecureUpgradeHTTPServer(
at: serverAddress,
trustRoots: [serverChain.ca],
applicationProtocol: "h2"
)

switch client {
case .http1:
Issue.record("Unexpectedly negotiated a HTTP/2 connection")

case .http2(let streamManager):
let streamChannel = try await streamManager.openStream()
try await streamChannel.executeThenClose { inbound, outbound in
try await outbound.write(Self.reqHead)
try await outbound.write(Self.reqBody)

// Wait until the server has received the request.
try await firstChunkReadPromise.futureResult.get()

// Now trigger graceful shutdown. This should propagate down to the server. The server will
// start the 500ms grace timer after which all connections that are still open will be
// forcefully closed.
trigger.triggerGracefulShutdown()

// The server should shut down after 500ms. Wait for this.
try await group.waitForAll()

// The connection should have been closed: we should get an `ioOnClosedChannel` error.
await #expect(throws: ChannelError.ioOnClosedChannel) {
try await outbound.write(Self.reqEnd)
}

// The connection should have been closed: we should get an `ioOnClosedChannel` error.
await #expect(throws: ChannelError.ioOnClosedChannel) {
try await outbound.write(Self.reqEnd)
connectionForcefullyShutdown()
}

connectionForcefullyShutdown()
}
}
}
Expand Down
23 changes: 13 additions & 10 deletions Tests/NIOHTTPServerTests/NIOHTTPServerEndToEndTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

import HTTPServer
import HTTPTypes
import Logging
import NIOCore
import NIOEmbedded
import NIOHTTP1
Expand All @@ -31,7 +32,8 @@ struct NIOHTTPServerEndToEndTests {
@available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *)
@Test("HTTP/1.1 request and response")
func testHTTP1_1() async throws {
try await HTTP1ClientServerProvider.withProvider(
try await TestingChannelHTTP1Server.serve(
logger: Logger(label: "NIOHTTPServerEndToEndTests"),
handler: HTTPServerClosureRequestHandler { request, reqContext, reqReader, resSender in
let sender = try await resSender.send(.init(status: .ok))

Expand All @@ -41,9 +43,9 @@ struct NIOHTTPServerEndToEndTests {
return [.serverTiming: "test"]
}
}
) { clientServerProvider in
try await clientServerProvider.withConnectedClient { client in
try await client.executeThenClose { inbound, outbound in
) { server in
try await server.withConnectedClient { connectionChannel in
try await connectionChannel.executeThenClose { inbound, outbound in
try await outbound.write(.head(.init(method: .get, scheme: "", authority: "", path: "/")))
try await outbound.write(.end(nil))

Expand Down Expand Up @@ -77,7 +79,7 @@ struct NIOHTTPServerEndToEndTests {

@available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *)
@Test("HTTP/2 negotiation")
func testSecureUpgradeNegotiation() async throws {
func testHTTP2Negotiation() async throws {
let serverChain = try TestCA.makeSelfSignedChain()
var serverTLSConfig = TLSConfiguration.makeServerConfiguration(
certificateChain: [try .init(serverChain.leaf)],
Expand All @@ -90,7 +92,8 @@ struct NIOHTTPServerEndToEndTests {
clientTLSConfig.certificateVerification = .noHostnameVerification
clientTLSConfig.applicationProtocols = ["h2"]

try await HTTPSecureUpgradeClientServerProvider.withProvider(
try await TestingChannelSecureUpgradeServer.serve(
logger: Logger(label: "NIOHTTPServerEndToEndTests"),
tlsConfiguration: serverTLSConfig,
handler: HTTPServerClosureRequestHandler { request, reqContext, reqReader, resSender in
let sender = try await resSender.send(.init(status: .ok))
Expand All @@ -101,12 +104,12 @@ struct NIOHTTPServerEndToEndTests {
return [.serverTiming: "test"]
}
}
) { clientServerProvider in
try await clientServerProvider.withConnectedClient(clientTLSConfiguration: clientTLSConfig) {
negotiatedConnection in
switch negotiatedConnection {
) { server in
try await server.withConnectedClient(clientTLSConfig: clientTLSConfig) { negotiatedConnectionChannel in
switch negotiatedConnectionChannel {
case .http1(_):
Issue.record("Failed to negotiate HTTP/2 despite the client requiring HTTP/2.")

case .http2(let http2StreamManager):
let http2AsyncChannel = try await http2StreamManager.openStream()

Expand Down
Loading
Loading