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
28
29
30 package org.apache.commons.httpclient;
31
32 import java.io.IOException;
33 import java.io.InputStream;
34
35 import org.apache.commons.httpclient.params.HttpConnectionManagerParams;
36 import org.apache.commons.logging.Log;
37 import org.apache.commons.logging.LogFactory;
38
39 /***
40 * A connection manager that provides access to a single HttpConnection. This
41 * manager makes no attempt to provide exclusive access to the contained
42 * HttpConnection.
43 *
44 * @author <a href="mailto:becke@u.washington.edu">Michael Becke</a>
45 * @author Eric Johnson
46 * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
47 * @author <a href="mailto:oleg@ural.ru">Oleg Kalnichevski</a>
48 * @author Laura Werner
49 *
50 * @since 2.0
51 */
52 public class SimpleHttpConnectionManager implements HttpConnectionManager {
53
54 private static final Log LOG = LogFactory.getLog(SimpleHttpConnectionManager.class);
55
56 private static final String MISUSE_MESSAGE =
57 "SimpleHttpConnectionManager being used incorrectly. Be sure that"
58 + " HttpMethod.releaseConnection() is always called and that only one thread"
59 + " and/or method is using this connection manager at a time.";
60
61 /***
62 * Since the same connection is about to be reused, make sure the
63 * previous request was completely processed, and if not
64 * consume it now.
65 * @param conn The connection
66 */
67 static void finishLastResponse(HttpConnection conn) {
68 InputStream lastResponse = conn.getLastResponseInputStream();
69 if (lastResponse != null) {
70 conn.setLastResponseInputStream(null);
71 try {
72 lastResponse.close();
73 } catch (IOException ioe) {
74
75 conn.close();
76 }
77 }
78 }
79
80 /*** The http connection */
81 protected HttpConnection httpConnection;
82
83 /***
84 * Collection of parameters associated with this connection manager.
85 */
86 private HttpConnectionManagerParams params = new HttpConnectionManagerParams();
87
88 /***
89 * The time the connection was made idle.
90 */
91 private long idleStartTime = Long.MAX_VALUE;
92
93 /***
94 * Used to test if {@link #httpConnection} is currently in use
95 * (i.e. checked out). This is only used as a sanity check to help
96 * debug cases where this connection manager is being used incorrectly.
97 * It will not be used to enforce thread safety.
98 */
99 private volatile boolean inUse = false;
100
101 public SimpleHttpConnectionManager() {
102 }
103
104 /***
105 * @see HttpConnectionManager#getConnection(HostConfiguration)
106 */
107 public HttpConnection getConnection(HostConfiguration hostConfiguration) {
108 return getConnection(hostConfiguration, 0);
109 }
110
111 /***
112 * Gets the staleCheckingEnabled value to be set on HttpConnections that are created.
113 *
114 * @return <code>true</code> if stale checking will be enabled on HttpConections
115 *
116 * @see HttpConnection#isStaleCheckingEnabled()
117 *
118 * @deprecated Use {@link HttpConnectionManagerParams#isStaleCheckingEnabled()},
119 * {@link HttpConnectionManager#getParams()}.
120 */
121 public boolean isConnectionStaleCheckingEnabled() {
122 return this.params.isStaleCheckingEnabled();
123 }
124
125 /***
126 * Sets the staleCheckingEnabled value to be set on HttpConnections that are created.
127 *
128 * @param connectionStaleCheckingEnabled <code>true</code> if stale checking will be enabled
129 * on HttpConections
130 *
131 * @see HttpConnection#setStaleCheckingEnabled(boolean)
132 *
133 * @deprecated Use {@link HttpConnectionManagerParams#setStaleCheckingEnabled(boolean)},
134 * {@link HttpConnectionManager#getParams()}.
135 */
136 public void setConnectionStaleCheckingEnabled(boolean connectionStaleCheckingEnabled) {
137 this.params.setStaleCheckingEnabled(connectionStaleCheckingEnabled);
138 }
139
140 /***
141 * @see HttpConnectionManager#getConnectionWithTimeout(HostConfiguration, long)
142 *
143 * @since 3.0
144 */
145 public HttpConnection getConnectionWithTimeout(
146 HostConfiguration hostConfiguration, long timeout) {
147
148 if (httpConnection == null) {
149 httpConnection = new HttpConnection(hostConfiguration);
150 httpConnection.setHttpConnectionManager(this);
151 httpConnection.getParams().setDefaults(this.params);
152 } else {
153
154
155
156 if (!hostConfiguration.hostEquals(httpConnection)
157 || !hostConfiguration.proxyEquals(httpConnection)) {
158
159 if (httpConnection.isOpen()) {
160 httpConnection.close();
161 }
162
163 httpConnection.setHost(hostConfiguration.getHost());
164 httpConnection.setPort(hostConfiguration.getPort());
165 httpConnection.setProtocol(hostConfiguration.getProtocol());
166 httpConnection.setLocalAddress(hostConfiguration.getLocalAddress());
167
168 httpConnection.setProxyHost(hostConfiguration.getProxyHost());
169 httpConnection.setProxyPort(hostConfiguration.getProxyPort());
170 } else {
171 finishLastResponse(httpConnection);
172 }
173 }
174
175
176 idleStartTime = Long.MAX_VALUE;
177
178 if (inUse) LOG.warn(MISUSE_MESSAGE);
179 inUse = true;
180
181 return httpConnection;
182 }
183
184 /***
185 * @see HttpConnectionManager#getConnection(HostConfiguration, long)
186 *
187 * @deprecated Use #getConnectionWithTimeout(HostConfiguration, long)
188 */
189 public HttpConnection getConnection(
190 HostConfiguration hostConfiguration, long timeout) {
191 return getConnectionWithTimeout(hostConfiguration, timeout);
192 }
193
194 /***
195 * @see HttpConnectionManager#releaseConnection(org.apache.commons.httpclient.HttpConnection)
196 */
197 public void releaseConnection(HttpConnection conn) {
198 if (conn != httpConnection) {
199 throw new IllegalStateException("Unexpected release of an unknown connection.");
200 }
201
202 finishLastResponse(httpConnection);
203
204 inUse = false;
205
206
207 idleStartTime = System.currentTimeMillis();
208 }
209
210 /***
211 * Returns {@link HttpConnectionManagerParams parameters} associated
212 * with this connection manager.
213 *
214 * @since 2.1
215 *
216 * @see HttpConnectionManagerParams
217 */
218 public HttpConnectionManagerParams getParams() {
219 return this.params;
220 }
221
222 /***
223 * Assigns {@link HttpConnectionManagerParams parameters} for this
224 * connection manager.
225 *
226 * @since 2.1
227 *
228 * @see HttpConnectionManagerParams
229 */
230 public void setParams(final HttpConnectionManagerParams params) {
231 if (params == null) {
232 throw new IllegalArgumentException("Parameters may not be null");
233 }
234 this.params = params;
235 }
236
237 /***
238 * @since 3.0
239 */
240 public void closeIdleConnections(long idleTimeout) {
241 long maxIdleTime = System.currentTimeMillis() - idleTimeout;
242 if (idleStartTime <= maxIdleTime) {
243 httpConnection.close();
244 }
245 }
246 }