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.io.IOException;
31 import java.net.SocketAddress;
32 import java.util.concurrent.atomic.AtomicBoolean;
33
34 import javax.net.ssl.SSLContext;
35 import javax.net.ssl.SSLSession;
36
37 import org.apache.hc.client5.http.nio.ManagedAsyncClientConnection;
38 import org.apache.hc.core5.concurrent.FutureCallback;
39 import org.apache.hc.core5.http.EndpointDetails;
40 import org.apache.hc.core5.http.HttpConnection;
41 import org.apache.hc.core5.http.HttpVersion;
42 import org.apache.hc.core5.http.ProtocolVersion;
43 import org.apache.hc.core5.http.nio.command.ShutdownCommand;
44 import org.apache.hc.core5.io.CloseMode;
45 import org.apache.hc.core5.net.NamedEndpoint;
46 import org.apache.hc.core5.reactor.Command;
47 import org.apache.hc.core5.reactor.IOEventHandler;
48 import org.apache.hc.core5.reactor.IOSession;
49 import org.apache.hc.core5.reactor.ProtocolIOSession;
50 import org.apache.hc.core5.reactor.ssl.SSLBufferMode;
51 import org.apache.hc.core5.reactor.ssl.SSLSessionInitializer;
52 import org.apache.hc.core5.reactor.ssl.SSLSessionVerifier;
53 import org.apache.hc.core5.reactor.ssl.TlsDetails;
54 import org.apache.hc.core5.reactor.ssl.TransportSecurityLayer;
55 import org.apache.hc.core5.util.Identifiable;
56 import org.apache.hc.core5.util.Timeout;
57 import org.slf4j.Logger;
58 import org.slf4j.LoggerFactory;
59
60 final class DefaultManagedAsyncClientConnection implements ManagedAsyncClientConnection, Identifiable {
61
62 private static final Logger LOG = LoggerFactory.getLogger(DefaultManagedAsyncClientConnection.class);
63
64 private final IOSession ioSession;
65 private final Timeout socketTimeout;
66 private final AtomicBoolean closed;
67
68 public DefaultManagedAsyncClientConnection(final IOSession ioSession) {
69 this.ioSession = ioSession;
70 this.socketTimeout = ioSession.getSocketTimeout();
71 this.closed = new AtomicBoolean();
72 }
73
74 @Override
75 public String getId() {
76 return ioSession.getId();
77 }
78
79 @Override
80 public void close(final CloseMode closeMode) {
81 if (this.closed.compareAndSet(false, true)) {
82 if (LOG.isDebugEnabled()) {
83 LOG.debug("{} Shutdown connection {}", getId(), closeMode);
84 }
85 ioSession.close(closeMode);
86 }
87 }
88
89 @Override
90 public void close() throws IOException {
91 if (this.closed.compareAndSet(false, true)) {
92 if (LOG.isDebugEnabled()) {
93 LOG.debug("{} Close connection", getId());
94 }
95 ioSession.enqueue(new ShutdownCommand(CloseMode.GRACEFUL), Command.Priority.IMMEDIATE);
96 }
97 }
98
99 @Override
100 public boolean isOpen() {
101 return ioSession.isOpen();
102 }
103
104 @Override
105 public void setSocketTimeout(final Timeout timeout) {
106 ioSession.setSocketTimeout(timeout);
107 }
108
109 @Override
110 public Timeout getSocketTimeout() {
111 return ioSession.getSocketTimeout();
112 }
113
114 @Override
115 public SocketAddress getRemoteAddress() {
116 return ioSession.getRemoteAddress();
117 }
118
119 @Override
120 public SocketAddress getLocalAddress() {
121 return ioSession.getLocalAddress();
122 }
123
124 @Override
125 public EndpointDetails getEndpointDetails() {
126 final IOEventHandler handler = ioSession.getHandler();
127 if (handler instanceof HttpConnection) {
128 return ((HttpConnection) handler).getEndpointDetails();
129 }
130 return null;
131 }
132
133 @Override
134 public ProtocolVersion getProtocolVersion() {
135 final IOEventHandler handler = ioSession.getHandler();
136 if (handler instanceof HttpConnection) {
137 final ProtocolVersion version = ((HttpConnection) handler).getProtocolVersion();
138 if (version != null) {
139 return version;
140 }
141 }
142 return HttpVersion.DEFAULT;
143 }
144
145 @Override
146 public void startTls(
147 final SSLContext sslContext,
148 final NamedEndpoint endpoint,
149 final SSLBufferMode sslBufferMode,
150 final SSLSessionInitializer initializer,
151 final SSLSessionVerifier verifier,
152 final Timeout handshakeTimeout,
153 final FutureCallback<TransportSecurityLayer> callback) throws UnsupportedOperationException {
154 if (LOG.isDebugEnabled()) {
155 LOG.debug("{} start TLS", getId());
156 }
157 if (ioSession instanceof TransportSecurityLayer) {
158 ((TransportSecurityLayer) ioSession).startTls(sslContext, endpoint, sslBufferMode, initializer, verifier,
159 handshakeTimeout, callback);
160 } else {
161 throw new UnsupportedOperationException("TLS upgrade not supported");
162 }
163 }
164
165 @Override
166 public void startTls(
167 final SSLContext sslContext,
168 final NamedEndpoint endpoint,
169 final SSLBufferMode sslBufferMode,
170 final SSLSessionInitializer initializer,
171 final SSLSessionVerifier verifier,
172 final Timeout handshakeTimeout) throws UnsupportedOperationException {
173 startTls(sslContext, endpoint, sslBufferMode, initializer, verifier, handshakeTimeout, null);
174 }
175
176 @Override
177 public TlsDetails getTlsDetails() {
178 return ioSession instanceof TransportSecurityLayer ? ((TransportSecurityLayer) ioSession).getTlsDetails() : null;
179 }
180
181 @Override
182 public SSLSession getSSLSession() {
183 final TlsDetails tlsDetails = getTlsDetails();
184 return tlsDetails != null ? tlsDetails.getSSLSession() : null;
185 }
186
187 @Override
188 public void submitCommand(final Command command, final Command.Priority priority) {
189 if (LOG.isDebugEnabled()) {
190 LOG.debug("{} {} with {} priority", getId(), command.getClass().getSimpleName(), priority);
191 }
192 ioSession.enqueue(command, Command.Priority.IMMEDIATE);
193 }
194
195 @Override
196 public void passivate() {
197 ioSession.setSocketTimeout(Timeout.ZERO_MILLISECONDS);
198 }
199
200 @Override
201 public void activate() {
202 ioSession.setSocketTimeout(socketTimeout);
203 }
204
205 @Override
206 public void switchProtocol(final String protocolId,
207 final FutureCallback<ProtocolIOSession> callback) throws UnsupportedOperationException {
208 if (ioSession instanceof ProtocolIOSession) {
209 ((ProtocolIOSession) ioSession).switchProtocol(protocolId, callback);
210 } else {
211 throw new UnsupportedOperationException("Protocol switch not supported");
212 }
213 }
214
215 }