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.core5.http2.impl.nio.bootstrap;
29
30 import java.util.concurrent.Future;
31
32 import org.apache.hc.core5.annotation.Internal;
33 import org.apache.hc.core5.concurrent.CallbackContribution;
34 import org.apache.hc.core5.concurrent.FutureCallback;
35 import org.apache.hc.core5.function.Callback;
36 import org.apache.hc.core5.function.Decorator;
37 import org.apache.hc.core5.http.HttpHost;
38 import org.apache.hc.core5.http.impl.bootstrap.HttpAsyncRequester;
39 import org.apache.hc.core5.http.nio.AsyncClientEndpoint;
40 import org.apache.hc.core5.http.nio.ssl.TlsStrategy;
41 import org.apache.hc.core5.http2.HttpVersionPolicy;
42 import org.apache.hc.core5.http2.ssl.ApplicationProtocol;
43 import org.apache.hc.core5.net.NamedEndpoint;
44 import org.apache.hc.core5.pool.ManagedConnPool;
45 import org.apache.hc.core5.reactor.IOEventHandlerFactory;
46 import org.apache.hc.core5.reactor.IOReactorConfig;
47 import org.apache.hc.core5.reactor.IOSession;
48 import org.apache.hc.core5.reactor.IOSessionListener;
49 import org.apache.hc.core5.reactor.ProtocolIOSession;
50 import org.apache.hc.core5.reactor.ssl.TlsDetails;
51 import org.apache.hc.core5.util.Timeout;
52
53
54
55
56
57
58
59 public class H2AsyncRequester extends HttpAsyncRequester {
60
61 private final HttpVersionPolicy versionPolicy;
62
63
64
65
66 @Internal
67 public H2AsyncRequester(
68 final HttpVersionPolicy versionPolicy,
69 final IOReactorConfig ioReactorConfig,
70 final IOEventHandlerFactory eventHandlerFactory,
71 final Decorator<IOSession> ioSessionDecorator,
72 final Callback<Exception> exceptionCallback,
73 final IOSessionListener sessionListener,
74 final ManagedConnPool<HttpHost, IOSession> connPool) {
75 super(ioReactorConfig, eventHandlerFactory, ioSessionDecorator, exceptionCallback, sessionListener, connPool);
76 this.versionPolicy = versionPolicy != null ? versionPolicy : HttpVersionPolicy.NEGOTIATE;
77 }
78
79
80
81
82
83
84 @Internal
85 public H2AsyncRequester(
86 final HttpVersionPolicy versionPolicy,
87 final IOReactorConfig ioReactorConfig,
88 final IOEventHandlerFactory eventHandlerFactory,
89 final Decorator<IOSession> ioSessionDecorator,
90 final Callback<Exception> exceptionCallback,
91 final IOSessionListener sessionListener,
92 final ManagedConnPool<HttpHost, IOSession> connPool,
93 final TlsStrategy tlsStrategy,
94 final Timeout handshakeTimeout) {
95 super(ioReactorConfig, eventHandlerFactory, ioSessionDecorator, exceptionCallback, sessionListener, connPool,
96 tlsStrategy, handshakeTimeout);
97 this.versionPolicy = versionPolicy != null ? versionPolicy : HttpVersionPolicy.NEGOTIATE;
98 }
99
100 @Override
101 protected Future<AsyncClientEndpoint> doConnect(
102 final HttpHost host,
103 final Timeout timeout,
104 final Object attachment,
105 final FutureCallback<AsyncClientEndpoint> callback) {
106 return super.doConnect(host, timeout, attachment != null ? attachment : versionPolicy, callback);
107 }
108
109 @Override
110 protected void doTlsUpgrade(final ProtocolIOSession ioSession,
111 final NamedEndpoint endpoint,
112 final FutureCallback<ProtocolIOSession> callback) {
113 super.doTlsUpgrade(ioSession, endpoint, new CallbackContribution<ProtocolIOSession>(callback) {
114
115 @Override
116 public void completed(final ProtocolIOSession protocolSession) {
117 final boolean switchProtocol;
118 switch (versionPolicy) {
119 case FORCE_HTTP_2:
120 switchProtocol = true;
121 break;
122 case NEGOTIATE:
123 final TlsDetails tlsDetails = protocolSession.getTlsDetails();
124 final String appProtocol = tlsDetails != null ? tlsDetails.getApplicationProtocol() : null;
125 switchProtocol = ApplicationProtocol.HTTP_2.id.equals(appProtocol);
126 break;
127 default:
128 switchProtocol = false;
129 }
130 if (switchProtocol) {
131 protocolSession.switchProtocol(ApplicationProtocol.HTTP_2.id, callback);
132 } else {
133 if (callback != null) {
134 callback.completed(protocolSession);
135 }
136 }
137 }
138
139 });
140 }
141
142 }