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.annotation.NotThreadSafe;
42  import org.apache.http.conn.ManagedHttpClientConnection;
43  import org.apache.http.protocol.HttpContext;
44  
45  /**
46   * @since 4.3
47   */
48  @NotThreadSafe
49  class CPoolProxy implements ManagedHttpClientConnection, HttpContext {
50  
51      private volatile CPoolEntry poolEntry;
52  
53      CPoolProxy(final CPoolEntry entry) {
54          super();
55          this.poolEntry = entry;
56      }
57  
58      CPoolEntry getPoolEntry() {
59          return this.poolEntry;
60      }
61  
62      CPoolEntry detach() {
63          final CPoolEntry local = this.poolEntry;
64          this.poolEntry = null;
65          return local;
66      }
67  
68      ManagedHttpClientConnection getConnection() {
69          final CPoolEntry local = this.poolEntry;
70          if (local == null) {
71              return null;
72          }
73          return local.getConnection();
74      }
75  
76      ManagedHttpClientConnection getValidConnection() {
77          final ManagedHttpClientConnection conn = getConnection();
78          if (conn == null) {
79              throw new ConnectionShutdownException();
80          }
81          return conn;
82      }
83  
84      @Override
85      public void close() throws IOException {
86          final CPoolEntry local = this.poolEntry;
87          if (local != null) {
88              local.closeConnection();
89          }
90      }
91  
92      @Override
93      public void shutdown() throws IOException {
94          final CPoolEntry local = this.poolEntry;
95          if (local != null) {
96              local.shutdownConnection();
97          }
98      }
99  
100     @Override
101     public boolean isOpen() {
102         final CPoolEntry local = this.poolEntry;
103         if (local != null) {
104             return !local.isClosed();
105         } else {
106             return false;
107         }
108     }
109 
110     @Override
111     public boolean isStale() {
112         final HttpClientConnection conn = getConnection();
113         if (conn != null) {
114             return conn.isStale();
115         } else {
116             return true;
117         }
118     }
119 
120     @Override
121     public void setSocketTimeout(final int timeout) {
122         getValidConnection().setSocketTimeout(timeout);
123     }
124 
125     @Override
126     public int getSocketTimeout() {
127         return getValidConnection().getSocketTimeout();
128     }
129 
130     @Override
131     public String getId() {
132         return getValidConnection().getId();
133     }
134 
135     @Override
136     public void bind(final Socket socket) throws IOException {
137         getValidConnection().bind(socket);
138     }
139 
140     @Override
141     public Socket getSocket() {
142         return getValidConnection().getSocket();
143     }
144 
145     @Override
146     public SSLSession getSSLSession() {
147         return getValidConnection().getSSLSession();
148     }
149 
150     @Override
151     public boolean isResponseAvailable(final int timeout) throws IOException {
152         return getValidConnection().isResponseAvailable(timeout);
153     }
154 
155     @Override
156     public void sendRequestHeader(final HttpRequest request) throws HttpException, IOException {
157         getValidConnection().sendRequestHeader(request);
158     }
159 
160     @Override
161     public void sendRequestEntity(final HttpEntityEnclosingRequest request) throws HttpException, IOException {
162         getValidConnection().sendRequestEntity(request);
163     }
164 
165     @Override
166     public HttpResponse receiveResponseHeader() throws HttpException, IOException {
167         return getValidConnection().receiveResponseHeader();
168     }
169 
170     @Override
171     public void receiveResponseEntity(final HttpResponse response) throws HttpException, IOException {
172         getValidConnection().receiveResponseEntity(response);
173     }
174 
175     @Override
176     public void flush() throws IOException {
177         getValidConnection().flush();
178     }
179 
180     @Override
181     public HttpConnectionMetrics getMetrics() {
182         return getValidConnection().getMetrics();
183     }
184 
185     @Override
186     public InetAddress getLocalAddress() {
187         return getValidConnection().getLocalAddress();
188     }
189 
190     @Override
191     public int getLocalPort() {
192         return getValidConnection().getLocalPort();
193     }
194 
195     @Override
196     public InetAddress getRemoteAddress() {
197         return getValidConnection().getRemoteAddress();
198     }
199 
200     @Override
201     public int getRemotePort() {
202         return getValidConnection().getRemotePort();
203     }
204 
205     @Override
206     public Object getAttribute(final String id) {
207         final ManagedHttpClientConnection conn = getValidConnection();
208         if (conn instanceof HttpContext) {
209             return ((HttpContext) conn).getAttribute(id);
210         } else {
211             return null;
212         }
213     }
214 
215     @Override
216     public void setAttribute(final String id, final Object obj) {
217         final ManagedHttpClientConnection conn = getValidConnection();
218         if (conn instanceof HttpContext) {
219             ((HttpContext) conn).setAttribute(id, obj);
220         }
221     }
222 
223     @Override
224     public Object removeAttribute(final String id) {
225         final ManagedHttpClientConnection conn = getValidConnection();
226         if (conn instanceof HttpContext) {
227             return ((HttpContext) conn).removeAttribute(id);
228         } else {
229             return null;
230         }
231     }
232 
233     @Override
234     public String toString() {
235         final StringBuilder sb = new StringBuilder("CPoolProxy{");
236         final ManagedHttpClientConnection conn = getConnection();
237         if (conn != null) {
238             sb.append(conn);
239         } else {
240             sb.append("detached");
241         }
242         sb.append('}');
243         return sb.toString();
244     }
245 
246     public static HttpClientConnection newProxy(final CPoolEntry poolEntry) {
247         return new CPoolProxy(poolEntry);
248     }
249 
250     private static CPoolProxy getProxy(final HttpClientConnection conn) {
251         if (!CPoolProxy.class.isInstance(conn)) {
252             throw new IllegalStateException("Unexpected connection proxy class: " + conn.getClass());
253         }
254         return CPoolProxy.class.cast(conn);
255     }
256 
257     public static CPoolEntry getPoolEntry(final HttpClientConnection proxy) {
258         final CPoolEntry entry = getProxy(proxy).getPoolEntry();
259         if (entry == null) {
260             throw new ConnectionShutdownException();
261         }
262         return entry;
263     }
264 
265     public static CPoolEntry detach(final HttpClientConnection conn) {
266         return getProxy(conn).detach();
267     }
268 
269 }