@@ -29,19 +29,42 @@ extension HTTPConnectionPool {
29
29
}
30
30
31
31
final class ConnectionFactory {
32
+
33
+ struct Timeouts {
34
+ /// the `TimeAmount` waited before the TCP connection creation is failed with a timeout error
35
+ var connect : TimeAmount = . seconds( 10 )
36
+
37
+ /// the `TimeAmount` waited before the SOCKS proxy connection creation is failed with a timeout error
38
+ var socksProxyHandshake : TimeAmount = . seconds( 10 )
39
+
40
+ /// the `TimeAmount` waited before the HTTP proxy connection creation is failed with a timeout error
41
+ var httpProxyHandshake : TimeAmount = . seconds( 10 )
42
+
43
+ /// the `TimeAmount` waited before we the TLS handshake is failed with a timeout error
44
+ var tlsHandshake : TimeAmount = . seconds( 10 )
45
+ }
46
+
32
47
let key : ConnectionPool . Key
33
48
let clientConfiguration : HTTPClient . Configuration
34
49
let tlsConfiguration : TLSConfiguration
35
50
let sslContextCache : SSLContextCache
51
+ let timeouts : Timeouts
36
52
37
53
init ( key: ConnectionPool . Key ,
38
54
tlsConfiguration: TLSConfiguration ? ,
39
55
clientConfiguration: HTTPClient . Configuration ,
40
- sslContextCache: SSLContextCache ) {
56
+ sslContextCache: SSLContextCache ,
57
+ timeouts: Timeouts = . init( ) ) {
41
58
self . key = key
42
59
self . clientConfiguration = clientConfiguration
43
60
self . sslContextCache = sslContextCache
44
61
self . tlsConfiguration = tlsConfiguration ?? clientConfiguration. tlsConfiguration ?? . forClient( )
62
+
63
+ var timeouts = timeouts
64
+ if let connect = clientConfiguration. timeout. connect {
65
+ timeouts. connect = connect
66
+ }
67
+ self . timeouts = timeouts
45
68
}
46
69
}
47
70
}
@@ -103,7 +126,7 @@ extension HTTPConnectionPool.ConnectionFactory {
103
126
targetHost: self . key. host,
104
127
targetPort: self . key. port,
105
128
proxyAuthorization: proxy. authorization,
106
- deadline: . now( ) + . seconds ( 10 )
129
+ deadline: . now( ) + self . timeouts . httpProxyHandshake
107
130
)
108
131
109
132
do {
@@ -138,7 +161,7 @@ extension HTTPConnectionPool.ConnectionFactory {
138
161
let bootstrap = self . makePlainBootstrap ( eventLoop: eventLoop)
139
162
return bootstrap. connect ( host: proxy. host, port: proxy. port) . flatMap { channel in
140
163
let socksConnectHandler = SOCKSClientHandler ( targetAddress: . domain( self . key. host, port: self . key. port) )
141
- let socksEventHandler = SOCKSEventsHandler ( deadline: . now( ) + . seconds ( 10 ) )
164
+ let socksEventHandler = SOCKSEventsHandler ( deadline: . now( ) + self . timeouts . socksProxyHandshake )
142
165
143
166
do {
144
167
try channel. pipeline. syncOperations. addHandler ( socksConnectHandler)
@@ -167,7 +190,7 @@ extension HTTPConnectionPool.ConnectionFactory {
167
190
var tlsConfig = self . tlsConfiguration
168
191
// since we can support h2, we need to advertise this in alpn
169
192
tlsConfig. applicationProtocols = [ " http/1.1 " /* , "h2" */ ]
170
- let tlsEventHandler = TLSEventsHandler ( deadline: . now( ) + . seconds ( 10 ) )
193
+ let tlsEventHandler = TLSEventsHandler ( deadline: . now( ) + self . timeouts . tlsHandshake )
171
194
172
195
let sslContextFuture = self . sslContextCache. sslContext (
173
196
tlsConfiguration: tlsConfig,
@@ -204,7 +227,7 @@ extension HTTPConnectionPool.ConnectionFactory {
204
227
#if canImport(Network)
205
228
if #available( OSX 10 . 14 , iOS 12 . 0 , tvOS 12 . 0 , watchOS 6 . 0 , * ) , let tsBootstrap = NIOTSConnectionBootstrap ( validatingGroup: eventLoop) {
206
229
return tsBootstrap
207
- . addTimeoutIfNeeded ( self . clientConfiguration . timeout )
230
+ . connectTimeout ( self . timeouts . connect )
208
231
. channelInitializer { channel in
209
232
do {
210
233
try channel. pipeline. syncOperations. addHandler ( HTTPClient . NWErrorHandler ( ) )
@@ -218,7 +241,7 @@ extension HTTPConnectionPool.ConnectionFactory {
218
241
219
242
if let nioBootstrap = ClientBootstrap ( validatingGroup: eventLoop) {
220
243
return nioBootstrap
221
- . addTimeoutIfNeeded ( self . clientConfiguration . timeout )
244
+ . connectTimeout ( self . timeouts . connect )
222
245
}
223
246
224
247
preconditionFailure ( " No matching bootstrap found " )
@@ -269,7 +292,7 @@ extension HTTPConnectionPool.ConnectionFactory {
269
292
options -> NIOClientTCPBootstrapProtocol in
270
293
271
294
tsBootstrap
272
- . addTimeoutIfNeeded ( self . clientConfiguration . timeout )
295
+ . connectTimeout ( self . timeouts . connect )
273
296
. tlsOptions ( options)
274
297
. channelInitializer { channel in
275
298
do {
@@ -298,7 +321,7 @@ extension HTTPConnectionPool.ConnectionFactory {
298
321
)
299
322
300
323
let bootstrap = ClientBootstrap ( group: eventLoop)
301
- . addTimeoutIfNeeded ( self . clientConfiguration . timeout )
324
+ . connectTimeout ( self . timeouts . connect )
302
325
. channelInitializer { channel in
303
326
sslContextFuture. flatMap { ( sslContext) -> EventLoopFuture < Void > in
304
327
do {
@@ -307,7 +330,7 @@ extension HTTPConnectionPool.ConnectionFactory {
307
330
context: sslContext,
308
331
serverHostname: hostname
309
332
)
310
- let tlsEventHandler = TLSEventsHandler ( deadline: . now( ) + . seconds ( 10 ) )
333
+ let tlsEventHandler = TLSEventsHandler ( deadline: . now( ) + self . timeouts . tlsHandshake )
311
334
312
335
try sync. addHandler ( sslHandler)
313
336
try sync. addHandler ( tlsEventHandler)
@@ -333,16 +356,6 @@ extension ConnectionPool.Key.Scheme {
333
356
}
334
357
}
335
358
336
- extension NIOClientTCPBootstrapProtocol {
337
- func addTimeoutIfNeeded( _ config: HTTPClient . Configuration . Timeout ? ) -> Self {
338
- guard let connectTimeamount = config? . connect else {
339
- return self
340
- }
341
-
342
- return self . connectTimeout ( connectTimeamount)
343
- }
344
- }
345
-
346
359
private extension String {
347
360
var isIPAddress : Bool {
348
361
var ipv4Addr = in_addr ( )
0 commit comments