View Javadoc
1   /*
2    * ====================================================================
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *   http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing,
14   * software distributed under the License is distributed on an
15   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16   * KIND, either express or implied.  See the License for the
17   * specific language governing permissions and limitations
18   * under the License.
19   * ====================================================================
20   *
21   * This software consists of voluntary contributions made by many
22   * individuals on behalf of the Apache Software Foundation.  For more
23   * information on the Apache Software Foundation, please see
24   * <http://www.apache.org/>.
25   *
26   */
27  package org.apache.http.impl.conn;
28  
29  import java.io.IOException;
30  import java.net.InetAddress;
31  import java.net.Socket;
32  
33  import javax.net.ssl.SSLSession;
34  
35  import org.apache.http.HttpClientConnection;
36  import org.apache.http.HttpConnectionMetrics;
37  import org.apache.http.HttpEntityEnclosingRequest;
38  import org.apache.http.HttpException;
39  import org.apache.http.HttpRequest;
40  import org.apache.http.HttpResponse;
41  import org.apache.http.conn.ManagedHttpClientConnection;
42  import org.apache.http.protocol.HttpContext;
43  
44  /**
45   * @since 4.3
46   */
47  class CPoolProxy implements ManagedHttpClientConnection, HttpContext {
48  
49      private volatile CPoolEntry poolEntry;
50  
51      CPoolProxy(final CPoolEntry entry) {
52          super();
53          this.poolEntry = entry;
54      }
55  
56      CPoolEntry getPoolEntry() {
57          return this.poolEntry;
58      }
59  
60      CPoolEntry detach() {
61          final CPoolEntry local = this.poolEntry;
62          this.poolEntry = null;
63          return local;
64      }
65  
66      ManagedHttpClientConnection getConnection() {
67          final CPoolEntry local = this.poolEntry;
68          if (local == null) {
69              return null;
70          }
71          return local.getConnection();
72      }
73  
74      ManagedHttpClientConnection getValidConnection() {
75          final ManagedHttpClientConnection conn = getConnection();
76          if (conn == null) {
77              throw new ConnectionShutdownException();
78          }
79          return conn;
80      }
81  
82      @Override
83      public void close() throws IOException {
84          final CPoolEntry local = this.poolEntry;
85          if (local != null) {
86              local.closeConnection();
87          }
88      }
89  
90      @Override
91      public void shutdown() throws IOException {
92          final CPoolEntry local = this.poolEntry;
93          if (local != null) {
94              local.shutdownConnection();
95          }
96      }
97  
98      @Override
99      public boolean isOpen() {
100         final CPoolEntry local = this.poolEntry;
101         if (local != null) {
102             return !local.isClosed();
103         } else {
104             return false;
105         }
106     }
107 
108     @Override
109     public boolean isStale() {
110         final HttpClientConnection conn = getConnection();
111         if (conn != null) {
112             return conn.isStale();
113         } else {
114             return true;
115         }
116     }
117 
118     @Override
119     public void setSocketTimeout(final int timeout) {
120         getValidConnection().setSocketTimeout(timeout);
121     }
122 
123     @Override
124     public int getSocketTimeout() {
125         return getValidConnection().getSocketTimeout();
126     }
127 
128     @Override
129     public String getId() {
130         return getValidConnection().getId();
131     }
132 
133     @Override
134     public void bind(final Socket socket) throws IOException {
135         getValidConnection().bind(socket);
136     }
137 
138     @Override
139     public Socket getSocket() {
140         return getValidConnection().getSocket();
141     }
142 
143     @Override
144     public SSLSession getSSLSession() {
145         return getValidConnection().getSSLSession();
146     }
147 
148     @Override
149     public boolean isResponseAvailable(final int timeout) throws IOException {
150         return getValidConnection().isResponseAvailable(timeout);
151     }
152 
153     @Override
154     public void sendRequestHeader(final HttpRequest request) throws HttpException, IOException {
155         getValidConnection().sendRequestHeader(request);
156     }
157 
158     @Override
159     public void sendRequestEntity(final HttpEntityEnclosingRequest request) throws HttpException, IOException {
160         getValidConnection().sendRequestEntity(request);
161     }
162 
163     @Override
164     public HttpResponse receiveResponseHeader() throws HttpException, IOException {
165         return getValidConnection().receiveResponseHeader();
166     }
167 
168     @Override
169     public void receiveResponseEntity(final HttpResponse response) throws HttpException, IOException {
170         getValidConnection().receiveResponseEntity(response);
171     }
172 
173     @Override
174     public void flush() throws IOException {
175         getValidConnection().flush();
176     }
177 
178     @Override
179     public HttpConnectionMetrics getMetrics() {
180         return getValidConnection().getMetrics();
181     }
182 
183     @Override
184     public InetAddress getLocalAddress() {
185         return getValidConnection().getLocalAddress();
186     }
187 
188     @Override
189     public int getLocalPort() {
190         return getValidConnection().getLocalPort();
191     }
192 
193     @Override
194     public InetAddress getRemoteAddress() {
195         return getValidConnection().getRemoteAddress();
196     }
197 
198     @Override
199     public int getRemotePort() {
200         return getValidConnection().getRemotePort();
201     }
202 
203     @Override
204     public Object getAttribute(final String id) {
205         final ManagedHttpClientConnection conn = getValidConnection();
206         if (conn instanceof HttpContext) {
207             return ((HttpContext) conn).getAttribute(id);
208         } else {
209             return null;
210         }
211     }
212 
213     @Override
214     public void setAttribute(final String id, final Object obj) {
215         final ManagedHttpClientConnection conn = getValidConnection();
216         if (conn instanceof HttpContext) {
217             ((HttpContext) conn).setAttribute(id, obj);
218         }
219     }
220 
221     @Override
222     public Object removeAttribute(final String id) {
223         final ManagedHttpClientConnection conn = getValidConnection();
224         if (conn instanceof HttpContext) {
225             return ((HttpContext) conn).removeAttribute(id);
226         } else {
227             return null;
228         }
229     }
230 
231     @Override
232     public String toString() {
233         final StringBuilder sb = new StringBuilder("CPoolProxy{");
234         final ManagedHttpClientConnection conn = getConnection();
235         if (conn != null) {
236             sb.append(conn);
237         } else {
238             sb.append("detached");
239         }
240         sb.append('}');
241         return sb.toString();
242     }
243 
244     public static HttpClientConnection newProxy(final CPoolEntry poolEntry) {
245         return new CPoolProxy(poolEntry);
246     }
247 
248     private static CPoolProxy getProxy(final HttpClientConnection conn) {
249         if (!CPoolProxy.class.isInstance(conn)) {
250             throw new IllegalStateException("Unexpected connection proxy class: " + conn.getClass());
251         }
252         return CPoolProxy.class.cast(conn);
253     }
254 
255     public static CPoolEntry getPoolEntry(final HttpClientConnection proxy) {
256         final CPoolEntry entry = getProxy(proxy).getPoolEntry();
257         if (entry == null) {
258             throw new ConnectionShutdownException();
259         }
260         return entry;
261     }
262 
263     public static CPoolEntry detach(final HttpClientConnection conn) {
264         return getProxy(conn).detach();
265     }
266 
267 }