|
15 | 15 | import NIO
|
16 | 16 | import NIOHTTP1
|
17 | 17 | import NIOHTTPCompression
|
| 18 | +import NIOSSL |
| 19 | +import NIOTransportServices |
18 | 20 |
|
19 | 21 | internal extension String {
|
20 | 22 | var isIPAddress: Bool {
|
@@ -46,6 +48,52 @@ public final class HTTPClientCopyingDelegate: HTTPClientResponseDelegate {
|
46 | 48 | }
|
47 | 49 | }
|
48 | 50 |
|
| 51 | +extension ClientBootstrap { |
| 52 | + fileprivate static func makeBootstrap(on eventLoop: EventLoop, host: String, requiresTLS: Bool, configuration: HTTPClient.Configuration) throws -> NIOClientTCPBootstrap { |
| 53 | + let tlsConfiguration = configuration.tlsConfiguration ?? TLSConfiguration.forClient() |
| 54 | + let sslContext = try NIOSSLContext(configuration: tlsConfiguration) |
| 55 | + let tlsProvider = try NIOSSLClientTLSProvider<ClientBootstrap>(context: sslContext, serverHostname: (!requiresTLS || host.isIPAddress) ? nil : host) |
| 56 | + return NIOClientTCPBootstrap(ClientBootstrap(group: eventLoop), tls: tlsProvider) |
| 57 | + } |
| 58 | +} |
| 59 | + |
| 60 | +extension NIOClientTCPBootstrap { |
| 61 | + /// create a TCP Bootstrap based off what type of `EventLoop` has been passed to the function. |
| 62 | + fileprivate static func makeBootstrap(on eventLoop: EventLoop, host: String, requiresTLS: Bool, configuration: HTTPClient.Configuration) throws -> NIOClientTCPBootstrap { |
| 63 | + let bootstrap: NIOClientTCPBootstrap |
| 64 | + #if canImport(Network) |
| 65 | + if #available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *), eventLoop is NIOTSEventLoop { |
| 66 | + let tlsProvider = NIOTSClientTLSProvider(tlsOptions: .init()) |
| 67 | + bootstrap = NIOClientTCPBootstrap(NIOTSConnectionBootstrap(group: eventLoop), tls: tlsProvider) |
| 68 | + } else { |
| 69 | + bootstrap = try ClientBootstrap.makeBootstrap(on: eventLoop, host: host, requiresTLS: requiresTLS, configuration: configuration) |
| 70 | + } |
| 71 | + #else |
| 72 | + bootstrap = try ClientBootstrap.makeBootstrap(on: eventLoop, host: host, requiresTLS: requiresTLS, configuration: configuration) |
| 73 | + #endif |
| 74 | + |
| 75 | + if requiresTLS { |
| 76 | + return bootstrap.enableTLS() |
| 77 | + } |
| 78 | + return bootstrap |
| 79 | + } |
| 80 | + |
| 81 | + static func makeHTTPClientBootstrapBase(on eventLoop: EventLoop, host: String, port: Int, requiresTLS: Bool, configuration: HTTPClient.Configuration) throws -> NIOClientTCPBootstrap { |
| 82 | + return try makeBootstrap(on: eventLoop, host: host, requiresTLS: requiresTLS, configuration: configuration) |
| 83 | + .channelOption(ChannelOptions.socket(SocketOptionLevel(IPPROTO_TCP), TCP_NODELAY), value: 1) |
| 84 | + .channelInitializer { channel in |
| 85 | + let channelAddedFuture: EventLoopFuture<Void> |
| 86 | + switch configuration.proxy { |
| 87 | + case .none: |
| 88 | + channelAddedFuture = eventLoop.makeSucceededFuture(()) |
| 89 | + case .some: |
| 90 | + channelAddedFuture = channel.pipeline.addProxyHandler(host: host, port: port, authorization: configuration.proxy?.authorization) |
| 91 | + } |
| 92 | + return channelAddedFuture |
| 93 | + } |
| 94 | + } |
| 95 | +} |
| 96 | + |
49 | 97 | extension CircularBuffer {
|
50 | 98 | @discardableResult
|
51 | 99 | mutating func swapWithFirstAndRemove(at index: Index) -> Element? {
|
|
0 commit comments