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      public void close() throws IOException {
85          final CPoolEntry local = this.poolEntry;
86          if (local != null) {
87              local.closeConnection();
88          }
89      }
90  
91      public void shutdown() throws IOException {
92          final CPoolEntry local = this.poolEntry;
93          if (local != null) {
94              local.shutdownConnection();
95          }
96      }
97  
98      public boolean isOpen() {
99          final CPoolEntry local = this.poolEntry;
100         if (local != null) {
101             return !local.isClosed();
102         } else {
103             return false;
104         }
105     }
106 
107     public boolean isStale() {
108         final HttpClientConnection conn = getConnection();
109         if (conn != null) {
110             return conn.isStale();
111         } else {
112             return true;
113         }
114     }
115 
116     public void setSocketTimeout(final int timeout) {
117         getValidConnection().setSocketTimeout(timeout);
118     }
119 
120     public int getSocketTimeout() {
121         return getValidConnection().getSocketTimeout();
122     }
123 
124     public String getId() {
125         return getValidConnection().getId();
126     }
127 
128     public void bind(final Socket socket) throws IOException {
129         getValidConnection().bind(socket);
130     }
131 
132     public Socket getSocket() {
133         return getValidConnection().getSocket();
134     }
135 
136     public SSLSession getSSLSession() {
137         return getValidConnection().getSSLSession();
138     }
139 
140     public boolean isResponseAvailable(final int timeout) throws IOException {
141         return getValidConnection().isResponseAvailable(timeout);
142     }
143 
144     public void sendRequestHeader(final HttpRequest request) throws HttpException, IOException {
145         getValidConnection().sendRequestHeader(request);
146     }
147 
148     public void sendRequestEntity(final HttpEntityEnclosingRequest request) throws HttpException, IOException {
149         getValidConnection().sendRequestEntity(request);
150     }
151 
152     public HttpResponse receiveResponseHeader() throws HttpException, IOException {
153         return getValidConnection().receiveResponseHeader();
154     }
155 
156     public void receiveResponseEntity(final HttpResponse response) throws HttpException, IOException {
157         getValidConnection().receiveResponseEntity(response);
158     }
159 
160     public void flush() throws IOException {
161         getValidConnection().flush();
162     }
163 
164     public HttpConnectionMetrics getMetrics() {
165         return getValidConnection().getMetrics();
166     }
167 
168     public InetAddress getLocalAddress() {
169         return getValidConnection().getLocalAddress();
170     }
171 
172     public int getLocalPort() {
173         return getValidConnection().getLocalPort();
174     }
175 
176     public InetAddress getRemoteAddress() {
177         return getValidConnection().getRemoteAddress();
178     }
179 
180     public int getRemotePort() {
181         return getValidConnection().getRemotePort();
182     }
183 
184     public Object getAttribute(final String id) {
185         final ManagedHttpClientConnection conn = getValidConnection();
186         if (conn instanceof HttpContext) {
187             return ((HttpContext) conn).getAttribute(id);
188         } else {
189             return null;
190         }
191     }
192 
193     public void setAttribute(final String id, final Object obj) {
194         final ManagedHttpClientConnection conn = getValidConnection();
195         if (conn instanceof HttpContext) {
196             ((HttpContext) conn).setAttribute(id, obj);
197         }
198     }
199 
200     public Object removeAttribute(final String id) {
201         final ManagedHttpClientConnection conn = getValidConnection();
202         if (conn instanceof HttpContext) {
203             return ((HttpContext) conn).removeAttribute(id);
204         } else {
205             return null;
206         }
207     }
208 
209     @Override
210     public String toString() {
211         final StringBuilder sb = new StringBuilder("CPoolProxy{");
212         final ManagedHttpClientConnection conn = getConnection();
213         if (conn != null) {
214             sb.append(conn);
215         } else {
216             sb.append("detached");
217         }
218         sb.append('}');
219         return sb.toString();
220     }
221 
222     public static HttpClientConnection newProxy(final CPoolEntry poolEntry) {
223         return new CPoolProxy(poolEntry);
224     }
225 
226     private static CPoolProxy getProxy(final HttpClientConnection conn) {
227         if (!CPoolProxy.class.isInstance(conn)) {
228             throw new IllegalStateException("Unexpected connection proxy class: " + conn.getClass());
229         }
230         return CPoolProxy.class.cast(conn);
231     }
232 
233     public static CPoolEntry getPoolEntry(final HttpClientConnection proxy) {
234         final CPoolEntry entry = getProxy(proxy).getPoolEntry();
235         if (entry == null) {
236             throw new ConnectionShutdownException();
237         }
238         return entry;
239     }
240 
241     public static CPoolEntry detach(final HttpClientConnection conn) {
242         return getProxy(conn).detach();
243     }
244 
245 }