Skip to content

Commit 5237768

Browse files
committed
Add SSL handler when needed in makeConnection
There was an issue where only the initial connection added the SSL Handler, but HTTP1ConnectionProvider wouldn't ever add the right handler if needed when it makes a new connection
1 parent e47a9cd commit 5237768

File tree

4 files changed

+36
-5
lines changed

4 files changed

+36
-5
lines changed

Sources/AsyncHTTPClient/ConnectionPool.swift

+4-2
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ class ConnectionPool {
148148
}
149149

150150
if request.useTLS {
151-
_ = channel.pipeline.addSSLHandlerIfNeeded(for: request, tlsConfiguration: self.configuration.tlsConfiguration).flatMap { _ in
151+
_ = channel.pipeline.addSSLHandlerIfNeeded(for: key, tlsConfiguration: self.configuration.tlsConfiguration).flatMap { _ in
152152
channel.pipeline.configureHTTP2SecureUpgrade(h2PipelineConfigurator: h2PipelineConfigurator, http1PipelineConfigurator: http1PipelineConfigurator)
153153
}
154154
} else {
@@ -357,7 +357,9 @@ class ConnectionPool {
357357

358358
private func makeConnection(preference: HTTPClient.EventLoopPreference) -> EventLoopFuture<Connection> {
359359
let bootstrap = ClientBootstrap.makeHTTPClientBootstrapBase(group: self.loopGroup, host: self.key.host, port: self.key.port, configuration: self.configuration) { channel in
360-
channel.pipeline.addHTTPClientHandlers(leftOverBytesStrategy: .forwardBytes)
360+
channel.pipeline.addSSLHandlerIfNeeded(for: self.key, tlsConfiguration: self.configuration.tlsConfiguration).flatMap {
361+
channel.pipeline.addHTTPClientHandlers(leftOverBytesStrategy: .forwardBytes)
362+
}
361363
}
362364
let address = HTTPClient.resolveAddress(host: self.key.host, port: self.key.port, proxy: self.configuration.proxy)
363365
return bootstrap.connect(host: address.host, port: address.port).map { channel in

Sources/AsyncHTTPClient/HTTPClient.swift

+3-3
Original file line numberDiff line numberDiff line change
@@ -358,15 +358,15 @@ extension ChannelPipeline {
358358
return addHandlers([encoder, decoder, handler])
359359
}
360360

361-
func addSSLHandlerIfNeeded(for request: HTTPClient.Request, tlsConfiguration: TLSConfiguration?) -> EventLoopFuture<Void> {
362-
guard request.useTLS else {
361+
func addSSLHandlerIfNeeded(for key: ConnectionPool.Key, tlsConfiguration: TLSConfiguration?) -> EventLoopFuture<Void> {
362+
guard key.scheme == .https else {
363363
return self.eventLoop.makeSucceededFuture(())
364364
}
365365

366366
do {
367367
let tlsConfiguration = tlsConfiguration ?? TLSConfiguration.forClient(applicationProtocols: NIOHTTP2SupportedALPNProtocols)
368368
let context = try NIOSSLContext(configuration: tlsConfiguration)
369-
return self.addHandler(try NIOSSLClientHandler(context: context, serverHostname: request.host))
369+
return self.addHandler(try NIOSSLClientHandler(context: context, serverHostname: key.host))
370370
} catch {
371371
return self.eventLoop.makeFailedFuture(error)
372372
}

Tests/AsyncHTTPClientTests/HTTPClientTests+XCTest.swift

+1
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ extension HTTPClientTests {
5757
("testWrongContentLengthForSSLUncleanShutdown", testWrongContentLengthForSSLUncleanShutdown),
5858
("testWrongContentLengthWithIgnoreErrorForSSLUncleanShutdown", testWrongContentLengthWithIgnoreErrorForSSLUncleanShutdown),
5959
("testEventLoopArgument", testEventLoopArgument),
60+
("testStressGetHttps", testStressGetHttps),
6061
]
6162
}
6263
}

Tests/AsyncHTTPClientTests/HTTPClientTests.swift

+28
Original file line numberDiff line numberDiff line change
@@ -562,4 +562,32 @@ class HTTPClientTests: XCTestCase {
562562
response = try httpClient.execute(request: request, delegate: delegate, eventLoop: .prefers(eventLoop)).wait()
563563
XCTAssertEqual(true, response)
564564
}
565+
566+
func testStressGetHttps() {
567+
let httpBin = HTTPBin(ssl: true)
568+
let httpClient = HTTPClient(eventLoopGroupProvider: .createNew,
569+
configuration: HTTPClient.Configuration(certificateVerification: .none))
570+
defer {
571+
XCTAssertNoThrow(try httpClient.syncShutdown())
572+
XCTAssertNoThrow(try httpBin.shutdown())
573+
}
574+
575+
let eventLoop = httpClient.eventLoopGroup
576+
let lastReqPromise = eventLoop.next().makePromise(of: Void.self)
577+
let requestCount = 5000
578+
for i in 1 ... requestCount {
579+
httpClient.get(url: "https://localhost:\(httpBin.port)/get").whenComplete { result in
580+
switch result {
581+
case .success(let response):
582+
XCTAssertEqual(.ok, response.status)
583+
case .failure(let error):
584+
XCTFail("\(error)")
585+
}
586+
if i == requestCount {
587+
lastReqPromise.succeed(())
588+
}
589+
}
590+
}
591+
try! lastReqPromise.futureResult.wait()
592+
}
565593
}

0 commit comments

Comments
 (0)