1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 package org.apache.hc.client5.http.impl.nio;
29
30 import java.net.InetAddress;
31 import java.net.InetSocketAddress;
32 import java.net.SocketAddress;
33 import java.util.concurrent.Future;
34
35 import org.apache.hc.client5.http.DnsResolver;
36 import org.apache.hc.client5.http.SchemePortResolver;
37 import org.apache.hc.client5.http.impl.DefaultSchemePortResolver;
38 import org.apache.hc.client5.http.nio.AsyncClientConnectionOperator;
39 import org.apache.hc.client5.http.nio.ManagedAsyncClientConnection;
40 import org.apache.hc.client5.http.routing.RoutingSupport;
41 import org.apache.hc.core5.concurrent.ComplexFuture;
42 import org.apache.hc.core5.concurrent.FutureCallback;
43 import org.apache.hc.core5.http.HttpHost;
44 import org.apache.hc.core5.http.config.Lookup;
45 import org.apache.hc.core5.http.nio.ssl.TlsStrategy;
46 import org.apache.hc.core5.reactor.ConnectionInitiator;
47 import org.apache.hc.core5.reactor.IOSession;
48 import org.apache.hc.core5.util.Args;
49 import org.apache.hc.core5.util.Timeout;
50
51 final class DefaultAsyncClientConnectionOperator implements AsyncClientConnectionOperator {
52
53 private final SchemePortResolver schemePortResolver;
54 private final MultihomeIOSessionRequester sessionRequester;
55 private final Lookup<TlsStrategy> tlsStrategyLookup;
56
57 DefaultAsyncClientConnectionOperator(
58 final Lookup<TlsStrategy> tlsStrategyLookup,
59 final SchemePortResolver schemePortResolver,
60 final DnsResolver dnsResolver) {
61 this.tlsStrategyLookup = Args.notNull(tlsStrategyLookup, "TLS strategy lookup");
62 this.schemePortResolver = schemePortResolver != null ? schemePortResolver : DefaultSchemePortResolver.INSTANCE;
63 this.sessionRequester = new MultihomeIOSessionRequester(dnsResolver);
64 }
65
66 @Override
67 public Future<ManagedAsyncClientConnection> connect(
68 final ConnectionInitiator connectionInitiator,
69 final HttpHost host,
70 final SocketAddress localAddress,
71 final Timeout connectTimeout,
72 final Object attachment,
73 final FutureCallback<ManagedAsyncClientConnection> callback) {
74 Args.notNull(connectionInitiator, "Connection initiator");
75 Args.notNull(host, "Host");
76 final ComplexFuture<ManagedAsyncClientConnection> future = new ComplexFuture<>(callback);
77 final HttpHost remoteEndpoint = RoutingSupport.normalize(host, schemePortResolver);
78 final InetAddress remoteAddress = host.getAddress();
79 final TlsStrategy tlsStrategy = tlsStrategyLookup != null ? tlsStrategyLookup.lookup(host.getSchemeName()) : null;
80 final Future<IOSession> sessionFuture = sessionRequester.connect(
81 connectionInitiator,
82 remoteEndpoint,
83 remoteAddress != null ? new InetSocketAddress(remoteAddress, remoteEndpoint.getPort()) : null,
84 localAddress,
85 connectTimeout,
86 attachment,
87 new FutureCallback<IOSession>() {
88
89 @Override
90 public void completed(final IOSession session) {
91 final DefaultManagedAsyncClientConnectionyncClientConnection.html#DefaultManagedAsyncClientConnection">DefaultManagedAsyncClientConnection connection = new DefaultManagedAsyncClientConnection(session);
92 if (tlsStrategy != null) {
93 try {
94 tlsStrategy.upgrade(
95 connection,
96 host,
97 session.getLocalAddress(),
98 session.getRemoteAddress(),
99 attachment,
100 connectTimeout);
101 } catch (final Exception ex) {
102 future.failed(ex);
103 return;
104 }
105 }
106 future.completed(connection);
107 }
108
109 @Override
110 public void failed(final Exception ex) {
111 future.failed(ex);
112 }
113
114 @Override
115 public void cancelled() {
116 future.cancel();
117 }
118
119 });
120 future.setDependency(sessionFuture);
121 return future;
122 }
123
124 @Override
125 public void upgrade(final ManagedAsyncClientConnection connection, final HttpHost host, final Object attachment) {
126 final TlsStrategy tlsStrategy = tlsStrategyLookup != null ? tlsStrategyLookup.lookup(host.getSchemeName()) : null;
127 if (tlsStrategy != null) {
128 tlsStrategy.upgrade(
129 connection,
130 host,
131 connection.getLocalAddress(),
132 connection.getRemoteAddress(),
133 attachment,
134 null);
135 }
136
137 }
138 }