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 package org.apache.http.impl.nio.conn;
28
29 import java.io.IOException;
30 import java.net.InetAddress;
31 import java.util.concurrent.TimeUnit;
32
33 import javax.net.ssl.SSLSession;
34
35 import org.apache.http.HttpConnectionMetrics;
36 import org.apache.http.HttpException;
37 import org.apache.http.HttpHost;
38 import org.apache.http.HttpRequest;
39 import org.apache.http.HttpResponse;
40 import org.apache.http.client.protocol.ClientContext;
41 import org.apache.http.conn.routing.HttpRoute;
42 import org.apache.http.conn.routing.RouteTracker;
43 import org.apache.http.impl.conn.ConnectionShutdownException;
44 import org.apache.http.nio.conn.ClientAsyncConnection;
45 import org.apache.http.nio.conn.ClientAsyncConnectionFactory;
46 import org.apache.http.nio.conn.ClientAsyncConnectionManager;
47 import org.apache.http.nio.conn.ManagedClientAsyncConnection;
48 import org.apache.http.nio.conn.scheme.AsyncScheme;
49 import org.apache.http.nio.conn.scheme.AsyncSchemeRegistry;
50 import org.apache.http.nio.conn.scheme.LayeringStrategy;
51 import org.apache.http.nio.reactor.IOEventDispatch;
52 import org.apache.http.nio.reactor.IOSession;
53 import org.apache.http.nio.reactor.ssl.SSLIOSession;
54 import org.apache.http.params.HttpParams;
55 import org.apache.http.protocol.HttpContext;
56
57 @Deprecated
58 class ManagedClientAsyncConnectionImpl implements ManagedClientAsyncConnection {
59
60 private final ClientAsyncConnectionManager manager;
61 private final ClientAsyncConnectionFactory connFactory;
62 private volatile HttpPoolEntry poolEntry;
63 private volatile boolean reusable;
64 private volatile long duration;
65
66 ManagedClientAsyncConnectionImpl(
67 final ClientAsyncConnectionManager manager,
68 final ClientAsyncConnectionFactory connFactory,
69 final HttpPoolEntry poolEntry) {
70 super();
71 this.manager = manager;
72 this.connFactory = connFactory;
73 this.poolEntry = poolEntry;
74 this.reusable = true;
75 this.duration = Long.MAX_VALUE;
76 }
77
78 HttpPoolEntry getPoolEntry() {
79 return this.poolEntry;
80 }
81
82 HttpPoolEntry detach() {
83 final HttpPoolEntry local = this.poolEntry;
84 this.poolEntry = null;
85 return local;
86 }
87
88 public ClientAsyncConnectionManager getManager() {
89 return this.manager;
90 }
91
92 private ClientAsyncConnection getConnection() {
93 final HttpPoolEntry local = this.poolEntry;
94 if (local == null) {
95 return null;
96 }
97 final IOSession session = local.getConnection();
98 return (ClientAsyncConnection) session.getAttribute(IOEventDispatch.CONNECTION_KEY);
99 }
100
101 private ClientAsyncConnection ensureConnection() {
102 final HttpPoolEntry local = this.poolEntry;
103 if (local == null) {
104 throw new ConnectionShutdownException();
105 }
106 final IOSession session = local.getConnection();
107 return (ClientAsyncConnection) session.getAttribute(IOEventDispatch.CONNECTION_KEY);
108 }
109
110 private HttpPoolEntry ensurePoolEntry() {
111 final HttpPoolEntry local = this.poolEntry;
112 if (local == null) {
113 throw new ConnectionShutdownException();
114 }
115 return local;
116 }
117
118 @Override
119 public void close() throws IOException {
120 final ClientAsyncConnection conn = getConnection();
121 if (conn != null) {
122 conn.close();
123 }
124 }
125
126 @Override
127 public void shutdown() throws IOException {
128 final ClientAsyncConnection conn = getConnection();
129 if (conn != null) {
130 conn.shutdown();
131 }
132 }
133
134 @Override
135 public boolean isOpen() {
136 final ClientAsyncConnection conn = getConnection();
137 return conn != null ? conn.isOpen() : false;
138 }
139
140 @Override
141 public boolean isStale() {
142 return isOpen();
143 }
144
145 @Override
146 public void setSocketTimeout(final int timeout) {
147 final ClientAsyncConnection conn = ensureConnection();
148 conn.setSocketTimeout(timeout);
149 }
150
151 @Override
152 public int getSocketTimeout() {
153 final ClientAsyncConnection conn = ensureConnection();
154 return conn.getSocketTimeout();
155 }
156
157 @Override
158 public HttpConnectionMetrics getMetrics() {
159 final ClientAsyncConnection conn = ensureConnection();
160 return conn.getMetrics();
161 }
162
163 @Override
164 public InetAddress getLocalAddress() {
165 final ClientAsyncConnection conn = ensureConnection();
166 return conn.getLocalAddress();
167 }
168
169 @Override
170 public int getLocalPort() {
171 final ClientAsyncConnection conn = ensureConnection();
172 return conn.getLocalPort();
173 }
174
175 @Override
176 public InetAddress getRemoteAddress() {
177 final ClientAsyncConnection conn = ensureConnection();
178 return conn.getRemoteAddress();
179 }
180
181 @Override
182 public int getRemotePort() {
183 final ClientAsyncConnection conn = ensureConnection();
184 return conn.getRemotePort();
185 }
186
187 @Override
188 public int getStatus() {
189 final ClientAsyncConnection conn = ensureConnection();
190 return conn.getStatus();
191 }
192
193 @Override
194 public HttpRequest getHttpRequest() {
195 final ClientAsyncConnection conn = ensureConnection();
196 return conn.getHttpRequest();
197 }
198
199 @Override
200 public HttpResponse getHttpResponse() {
201 final ClientAsyncConnection conn = ensureConnection();
202 return conn.getHttpResponse();
203 }
204
205 @Override
206 public HttpContext getContext() {
207 final ClientAsyncConnection conn = ensureConnection();
208 return conn.getContext();
209 }
210
211 @Override
212 public void requestInput() {
213 final ClientAsyncConnection conn = ensureConnection();
214 conn.requestInput();
215 }
216
217 @Override
218 public void suspendInput() {
219 final ClientAsyncConnection conn = ensureConnection();
220 conn.suspendInput();
221 }
222
223 @Override
224 public void requestOutput() {
225 final ClientAsyncConnection conn = ensureConnection();
226 conn.requestOutput();
227 }
228
229 @Override
230 public void suspendOutput() {
231 final ClientAsyncConnection conn = ensureConnection();
232 conn.suspendOutput();
233 }
234
235 @Override
236 public void submitRequest(final HttpRequest request) throws IOException, HttpException {
237 final ClientAsyncConnection conn = ensureConnection();
238 conn.submitRequest(request);
239 }
240
241 @Override
242 public boolean isRequestSubmitted() {
243 final ClientAsyncConnection conn = ensureConnection();
244 return conn.isRequestSubmitted();
245 }
246
247 @Override
248 public void resetOutput() {
249 final ClientAsyncConnection conn = ensureConnection();
250 conn.resetOutput();
251 }
252
253 @Override
254 public void resetInput() {
255 final ClientAsyncConnection conn = ensureConnection();
256 conn.resetInput();
257 }
258
259 @Override
260 public boolean isSecure() {
261 final ClientAsyncConnection conn = ensureConnection();
262 return conn.getIOSession() instanceof SSLIOSession;
263 }
264
265 @Override
266 public HttpRoute getRoute() {
267 final HttpPoolEntry entry = ensurePoolEntry();
268 return entry.getEffectiveRoute();
269 }
270
271 @Override
272 public SSLSession getSSLSession() {
273 final ClientAsyncConnection conn = ensureConnection();
274 final IOSession ioSession = conn.getIOSession();
275 return ioSession instanceof SSLIOSession
276 ? ((SSLIOSession) ioSession).getSSLSession()
277 : null;
278 }
279
280 @Override
281 public Object getState() {
282 final HttpPoolEntry entry = ensurePoolEntry();
283 return entry.getState();
284 }
285
286 @Override
287 public void setState(final Object state) {
288 final HttpPoolEntry entry = ensurePoolEntry();
289 entry.setState(state);
290 }
291
292 @Override
293 public void markReusable() {
294 this.reusable = true;
295 }
296
297 @Override
298 public void unmarkReusable() {
299 this.reusable = false;
300 }
301
302 @Override
303 public boolean isMarkedReusable() {
304 return this.reusable;
305 }
306
307 @Override
308 public void setIdleDuration(final long duration, final TimeUnit unit) {
309 if(duration > 0) {
310 this.duration = unit.toMillis(duration);
311 } else {
312 this.duration = -1;
313 }
314 }
315
316 private AsyncSchemeRegistry getSchemeRegistry(final HttpContext context) {
317 AsyncSchemeRegistry./../../org/apache/http/nio/conn/scheme/AsyncSchemeRegistry.html#AsyncSchemeRegistry">AsyncSchemeRegistry reg = (AsyncSchemeRegistry) context.getAttribute(
318 ClientContext.SCHEME_REGISTRY);
319 if (reg == null) {
320 reg = this.manager.getSchemeRegistry();
321 }
322 return reg;
323 }
324
325 @Override
326 public synchronized void open(
327 final HttpRoute route,
328 final HttpContext context,
329 final HttpParams params) throws IOException {
330 final HttpPoolEntry entry = ensurePoolEntry();
331 final RouteTracker tracker = entry.getTracker();
332 if (tracker.isConnected()) {
333 throw new IllegalStateException("Connection already open");
334 }
335
336 final HttpHost target = route.getTargetHost();
337 final HttpHost proxy = route.getProxyHost();
338 IOSession ioSession = entry.getConnection();
339
340 if (proxy == null) {
341 final AsyncScheme scheme = getSchemeRegistry(context).getScheme(target);
342 final LayeringStrategy layeringStrategy = scheme.getLayeringStrategy();
343 if (layeringStrategy != null) {
344 ioSession = layeringStrategy.layer(ioSession);
345 }
346 }
347
348 final ClientAsyncConnection conn = this.connFactory.create(
349 "http-outgoing-" + entry.getId(),
350 ioSession,
351 params);
352 ioSession.setAttribute(IOEventDispatch.CONNECTION_KEY, conn);
353
354 if (proxy == null) {
355 tracker.connectTarget(conn.getIOSession() instanceof SSLIOSession);
356 } else {
357 tracker.connectProxy(proxy, false);
358 }
359 }
360
361 @Override
362 public synchronized void tunnelProxy(
363 final HttpHost next, final HttpParams params) throws IOException {
364 final HttpPoolEntry entry = ensurePoolEntry();
365 final RouteTracker tracker = entry.getTracker();
366 if (!tracker.isConnected()) {
367 throw new IllegalStateException("Connection not open");
368 }
369 tracker.tunnelProxy(next, false);
370 }
371
372 @Override
373 public synchronized void tunnelTarget(
374 final HttpParams params) throws IOException {
375 final HttpPoolEntry entry = ensurePoolEntry();
376 final RouteTracker tracker = entry.getTracker();
377 if (!tracker.isConnected()) {
378 throw new IllegalStateException("Connection not open");
379 }
380 if (tracker.isTunnelled()) {
381 throw new IllegalStateException("Connection is already tunnelled");
382 }
383 tracker.tunnelTarget(false);
384 }
385
386 @Override
387 public synchronized void layerProtocol(
388 final HttpContext context, final HttpParams params) throws IOException {
389 final HttpPoolEntry entry = ensurePoolEntry();
390 final RouteTracker tracker = entry.getTracker();
391 if (!tracker.isConnected()) {
392 throw new IllegalStateException("Connection not open");
393 }
394 if (!tracker.isTunnelled()) {
395 throw new IllegalStateException("Protocol layering without a tunnel not supported");
396 }
397 if (tracker.isLayered()) {
398 throw new IllegalStateException("Multiple protocol layering not supported");
399 }
400 final HttpHost target = tracker.getTargetHost();
401 final AsyncScheme scheme = getSchemeRegistry(context).getScheme(target);
402 final LayeringStrategy layeringStrategy = scheme.getLayeringStrategy();
403 if (layeringStrategy == null) {
404 throw new IllegalStateException(scheme.getName() +
405 " scheme does not provider support for protocol layering");
406 }
407 final IOSession ioSession = entry.getConnection();
408 final ClientAsyncConnection./../org/apache/http/nio/conn/ClientAsyncConnection.html#ClientAsyncConnection">ClientAsyncConnection conn = (ClientAsyncConnection) ioSession.getAttribute(
409 IOEventDispatch.CONNECTION_KEY);
410 conn.upgrade(layeringStrategy.layer(ioSession));
411 tracker.layerProtocol(layeringStrategy.isSecure());
412 }
413
414 @Override
415 public synchronized void releaseConnection() {
416 if (this.poolEntry == null) {
417 return;
418 }
419 this.manager.releaseConnection(this, this.duration, TimeUnit.MILLISECONDS);
420 this.poolEntry = null;
421 }
422
423 @Override
424 public synchronized void abortConnection() {
425 if (this.poolEntry == null) {
426 return;
427 }
428 this.reusable = false;
429 final IOSession ioSession = this.poolEntry.getConnection();
430 final ClientAsyncConnection./../org/apache/http/nio/conn/ClientAsyncConnection.html#ClientAsyncConnection">ClientAsyncConnection conn = (ClientAsyncConnection) ioSession.getAttribute(
431 IOEventDispatch.CONNECTION_KEY);
432 try {
433 conn.shutdown();
434 } catch (final IOException ignore) {
435 }
436 this.manager.releaseConnection(this, this.duration, TimeUnit.MILLISECONDS);
437 this.poolEntry = null;
438 }
439
440 @Override
441 public synchronized String toString() {
442 return this.poolEntry != null ? this.poolEntry.toString() : "released";
443 }
444
445 }