Skip to content

Commit 8f2f7b1

Browse files
StrangeDaysweissi
authored andcommitted
Bugfix HTTPS SNI and IP Address (#139)
* Bugfix HTTPS SNI and IP Address Motivation: Solving the SNI Bug Modifications: Added an internal extension on String for checking if the hostname is an IP Address -- see the private extension on SNI. Additionally using the IPv4Address and IPv6Address Function from Network above 10.14 as protecting with #availabe. Adding the test for HTTPS and IP in as hostname Result: We get results with an IP as Hostname
1 parent d2d7bde commit 8f2f7b1

File tree

4 files changed

+41
-2
lines changed

4 files changed

+41
-2
lines changed

Diff for: Sources/AsyncHTTPClient/HTTPClient.swift

+1-2
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,6 @@ public class HTTPClient {
290290
channel.writeAndFlush(request)
291291
}
292292
.cascadeFailure(to: task.promise)
293-
294293
return task
295294
}
296295

@@ -501,7 +500,7 @@ private extension ChannelPipeline {
501500
do {
502501
let tlsConfiguration = tlsConfiguration ?? TLSConfiguration.forClient()
503502
let context = try NIOSSLContext(configuration: tlsConfiguration)
504-
return self.addHandler(try NIOSSLClientHandler(context: context, serverHostname: request.host),
503+
return self.addHandler(try NIOSSLClientHandler(context: context, serverHostname: request.host.isIPAddress ? nil : request.host),
505504
position: .first)
506505
} catch {
507506
return self.eventLoop.makeFailedFuture(error)

Diff for: Sources/AsyncHTTPClient/Utils.swift

+26
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,32 @@
1515
import NIO
1616
import NIOHTTP1
1717

18+
#if canImport(Network)
19+
import Network
20+
21+
internal extension String {
22+
var isIPAddress: Bool {
23+
if IPv4Address(self) != nil || IPv6Address(self) != nil {
24+
return true
25+
}
26+
return false
27+
}
28+
}
29+
30+
#else
31+
internal extension String {
32+
var isIPAddress: Bool {
33+
var ipv4Addr = in_addr()
34+
var ipv6Addr = in6_addr()
35+
36+
return self.withCString { ptr in
37+
inet_pton(AF_INET, ptr, &ipv4Addr) == 1 ||
38+
inet_pton(AF_INET6, ptr, &ipv6Addr) == 1
39+
}
40+
}
41+
}
42+
#endif
43+
1844
public final class HTTPClientCopyingDelegate: HTTPClientResponseDelegate {
1945
public typealias Response = Void
2046

Diff for: Tests/AsyncHTTPClientTests/HTTPClientTests+XCTest.swift

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ extension HTTPClientTests {
3232
("testGetWithDifferentEventLoopBackpressure", testGetWithDifferentEventLoopBackpressure),
3333
("testPost", testPost),
3434
("testGetHttps", testGetHttps),
35+
("testGetHttpsWithIP", testGetHttpsWithIP),
3536
("testPostHttps", testPostHttps),
3637
("testHttpRedirect", testHttpRedirect),
3738
("testHttpHostRedirect", testHttpHostRedirect),

Diff for: Tests/AsyncHTTPClientTests/HTTPClientTests.swift

+13
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,19 @@ class HTTPClientTests: XCTestCase {
122122
XCTAssertEqual(.ok, response.status)
123123
}
124124

125+
func testGetHttpsWithIP() throws {
126+
let httpBin = HTTPBin(ssl: true)
127+
let httpClient = HTTPClient(eventLoopGroupProvider: .createNew,
128+
configuration: HTTPClient.Configuration(certificateVerification: .none))
129+
defer {
130+
XCTAssertNoThrow(try httpClient.syncShutdown())
131+
XCTAssertNoThrow(try httpBin.shutdown())
132+
}
133+
134+
let response = try httpClient.get(url: "https://127.0.0.1:\(httpBin.port)/get").wait()
135+
XCTAssertEqual(.ok, response.status)
136+
}
137+
125138
func testPostHttps() throws {
126139
let httpBin = HTTPBin(ssl: true)
127140
let httpClient = HTTPClient(eventLoopGroupProvider: .createNew,

0 commit comments

Comments
 (0)