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