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;
29
30 import org.apache.hc.core5.annotation.Contract;
31 import org.apache.hc.core5.annotation.Internal;
32 import org.apache.hc.core5.annotation.ThreadingBehavior;
33 import org.apache.hc.core5.function.Callback;
34 import org.apache.hc.core5.http.URIScheme;
35 import org.apache.hc.core5.http.impl.nio.ClientHttp1IOEventHandler;
36 import org.apache.hc.core5.http.impl.nio.ClientHttp1StreamDuplexerFactory;
37 import org.apache.hc.core5.http.impl.nio.HttpConnectionEventHandler;
38 import org.apache.hc.core5.http.nio.ssl.TlsStrategy;
39 import org.apache.hc.core5.http2.HttpVersionPolicy;
40 import org.apache.hc.core5.http2.ssl.ApplicationProtocol;
41 import org.apache.hc.core5.reactor.EndpointParameters;
42 import org.apache.hc.core5.reactor.IOEventHandlerFactory;
43 import org.apache.hc.core5.reactor.ProtocolIOSession;
44 import org.apache.hc.core5.util.Args;
45 import org.apache.hc.core5.util.Timeout;
46
47
48
49
50
51
52
53
54 @Contract(threading = ThreadingBehavior.IMMUTABLE_CONDITIONAL)
55 @Internal
56 public class ClientHttpProtocolNegotiationStarter implements IOEventHandlerFactory {
57
58 private final ClientHttp1StreamDuplexerFactory http1StreamHandlerFactory;
59 private final ClientH2StreamMultiplexerFactory http2StreamHandlerFactory;
60 private final HttpVersionPolicy versionPolicy;
61 private final TlsStrategy tlsStrategy;
62 private final Timeout handshakeTimeout;
63 private final Callback<Exception> exceptionCallback;
64
65 public ClientHttpProtocolNegotiationStarter(
66 final ClientHttp1StreamDuplexerFactory http1StreamHandlerFactory,
67 final ClientH2StreamMultiplexerFactory http2StreamHandlerFactory,
68 final HttpVersionPolicy versionPolicy,
69 final TlsStrategy tlsStrategy,
70 final Timeout handshakeTimeout,
71 final Callback<Exception> exceptionCallback) {
72 this.http1StreamHandlerFactory = Args.notNull(http1StreamHandlerFactory, "HTTP/1.1 stream handler factory");
73 this.http2StreamHandlerFactory = Args.notNull(http2StreamHandlerFactory, "HTTP/2 stream handler factory");
74 this.versionPolicy = versionPolicy != null ? versionPolicy : HttpVersionPolicy.NEGOTIATE;
75 this.tlsStrategy = tlsStrategy;
76 this.handshakeTimeout = handshakeTimeout;
77 this.exceptionCallback = exceptionCallback;
78 }
79
80 @Override
81 public HttpConnectionEventHandler createHandler(final ProtocolIOSession ioSession, final Object attachment) {
82 HttpVersionPolicy endpointPolicy = versionPolicy;
83 if (attachment instanceof EndpointParameters) {
84 final EndpointParameters params = (EndpointParameters) attachment;
85 if (tlsStrategy != null && URIScheme.HTTPS.same(params.getScheme())) {
86 tlsStrategy.upgrade(ioSession, params, params.getAttachment(), handshakeTimeout, null);
87 }
88 if (params.getAttachment() instanceof HttpVersionPolicy) {
89 endpointPolicy = (HttpVersionPolicy) params.getAttachment();
90 }
91 }
92
93 ioSession.registerProtocol(ApplicationProtocol.HTTP_1_1.id, new ClientHttp1UpgradeHandler(http1StreamHandlerFactory));
94 ioSession.registerProtocol(ApplicationProtocol.HTTP_2.id, new ClientH2UpgradeHandler(http2StreamHandlerFactory, exceptionCallback));
95
96 switch (endpointPolicy) {
97 case FORCE_HTTP_2:
98 return new ClientH2PrefaceHandler(ioSession, http2StreamHandlerFactory, false, exceptionCallback);
99 case FORCE_HTTP_1:
100 return new ClientHttp1IOEventHandler(http1StreamHandlerFactory.create(ioSession));
101 default:
102 return new HttpProtocolNegotiator(ioSession, null);
103 }
104 }
105
106 }