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 package org.apache.http.impl.client.integration;
29
30 import java.io.ByteArrayOutputStream;
31 import java.io.IOException;
32 import java.io.OutputStream;
33 import java.util.concurrent.TimeUnit;
34
35 import org.apache.http.HttpClientConnection;
36 import org.apache.http.HttpEntity;
37 import org.apache.http.HttpException;
38 import org.apache.http.HttpHost;
39 import org.apache.http.HttpRequest;
40 import org.apache.http.HttpResponse;
41 import org.apache.http.MalformedChunkCodingException;
42 import org.apache.http.client.methods.HttpGet;
43 import org.apache.http.conn.ConnectionPoolTimeoutException;
44 import org.apache.http.conn.ConnectionRequest;
45 import org.apache.http.conn.routing.HttpRoute;
46 import org.apache.http.entity.BasicHttpEntity;
47 import org.apache.http.impl.DefaultBHttpServerConnection;
48 import org.apache.http.localserver.LocalServerTestBase;
49 import org.apache.http.pool.PoolStats;
50 import org.apache.http.protocol.HttpContext;
51 import org.apache.http.protocol.HttpCoreContext;
52 import org.apache.http.protocol.HttpRequestHandler;
53 import org.apache.http.util.EntityUtils;
54 import org.junit.Assert;
55 import org.junit.Test;
56
57 public class TestConnectionAutoRelease extends LocalServerTestBase {
58
59 @Test
60 public void testReleaseOnEntityConsumeContent() throws Exception {
61 this.connManager.setDefaultMaxPerRoute(1);
62 this.connManager.setMaxTotal(1);
63
64
65 PoolStats stats = this.connManager.getTotalStats();
66 Assert.assertEquals(0, stats.getAvailable());
67
68 final HttpHost target = start();
69
70 final HttpGet httpget = new HttpGet("/random/20000");
71 final HttpResponse response = this.httpclient.execute(target, httpget);
72
73 ConnectionRequest connreq = this.connManager.requestConnection(new HttpRoute(target), null);
74 try {
75 connreq.get(250, TimeUnit.MILLISECONDS);
76 Assert.fail("ConnectionPoolTimeoutException should have been thrown");
77 } catch (final ConnectionPoolTimeoutException expected) {
78 }
79
80 final HttpEntity e = response.getEntity();
81 Assert.assertNotNull(e);
82 EntityUtils.consume(e);
83
84
85 stats = this.connManager.getTotalStats();
86 Assert.assertEquals(1, stats.getAvailable());
87
88
89 connreq = this.connManager.requestConnection(new HttpRoute(target), null);
90 final HttpClientConnection conn = connreq.get(250, TimeUnit.MILLISECONDS);
91
92 this.connManager.releaseConnection(conn, null, -1, null);
93 }
94
95 @Test
96 public void testReleaseOnEntityWriteTo() throws Exception {
97 this.connManager.setDefaultMaxPerRoute(1);
98 this.connManager.setMaxTotal(1);
99
100
101 PoolStats stats = this.connManager.getTotalStats();
102 Assert.assertEquals(0, stats.getAvailable());
103
104 final HttpHost target = start();
105
106 final HttpGet httpget = new HttpGet("/random/20000");
107 final HttpResponse response = this.httpclient.execute(target, httpget);
108
109 ConnectionRequest connreq = this.connManager.requestConnection(new HttpRoute(target), null);
110 try {
111 connreq.get(250, TimeUnit.MILLISECONDS);
112 Assert.fail("ConnectionPoolTimeoutException should have been thrown");
113 } catch (final ConnectionPoolTimeoutException expected) {
114 }
115
116 final HttpEntity e = response.getEntity();
117 Assert.assertNotNull(e);
118 final ByteArrayOutputStream outstream = new ByteArrayOutputStream();
119 e.writeTo(outstream);
120
121
122 stats = this.connManager.getTotalStats();
123 Assert.assertEquals(1, stats.getAvailable());
124
125
126 connreq = this.connManager.requestConnection(new HttpRoute(target), null);
127 final HttpClientConnection conn = connreq.get(250, TimeUnit.MILLISECONDS);
128
129 this.connManager.releaseConnection(conn, null, -1, null);
130 }
131
132 @Test
133 public void testReleaseOnAbort() throws Exception {
134 this.connManager.setDefaultMaxPerRoute(1);
135 this.connManager.setMaxTotal(1);
136
137
138 final PoolStats stats = this.connManager.getTotalStats();
139 Assert.assertEquals(0, stats.getAvailable());
140
141 final HttpHost target = start();
142
143
144 final HttpGet httpget = new HttpGet("/random/20000");
145 final HttpResponse response = this.httpclient.execute(target, httpget);
146
147 ConnectionRequest connreq = this.connManager.requestConnection(new HttpRoute(target), null);
148 try {
149 connreq.get(250, TimeUnit.MILLISECONDS);
150 Assert.fail("ConnectionPoolTimeoutException should have been thrown");
151 } catch (final ConnectionPoolTimeoutException expected) {
152 }
153
154 final HttpEntity e = response.getEntity();
155 Assert.assertNotNull(e);
156 httpget.abort();
157
158
159 Assert.assertEquals(0, this.connManager.getTotalStats().getAvailable());
160
161
162 connreq = this.connManager.requestConnection(new HttpRoute(target), null);
163 final HttpClientConnection conn = connreq.get(250, TimeUnit.MILLISECONDS);
164
165 this.connManager.releaseConnection(conn, null, -1, null);
166 }
167
168 @Test
169 public void testReleaseOnIOException() throws Exception {
170 this.serverBootstrap.registerHandler("/dropdead", new HttpRequestHandler() {
171
172 @Override
173 public void handle(
174 final HttpRequest request,
175 final HttpResponse response,
176 final HttpContext context) throws HttpException, IOException {
177 final BasicHttpEntity entity = new BasicHttpEntity() {
178
179 @Override
180 public void writeTo(
181 final OutputStream outStream) throws IOException {
182 final byte[] tmp = new byte[5];
183 outStream.write(tmp);
184 outStream.flush();
185
186
187
188 final DefaultBHttpServerConnection conn = (DefaultBHttpServerConnection)
189 context.getAttribute(HttpCoreContext.HTTP_CONNECTION);
190 try {
191 conn.sendResponseHeader(response);
192 } catch (final HttpException ignore) {
193 }
194 }
195
196 };
197 entity.setChunked(true);
198 response.setEntity(entity);
199 }
200
201 });
202
203 this.connManager.setDefaultMaxPerRoute(1);
204 this.connManager.setMaxTotal(1);
205
206
207 Assert.assertEquals(0, this.connManager.getTotalStats().getAvailable());
208
209 final HttpHost target = start();
210
211
212 final HttpGet httpget = new HttpGet("/dropdead");
213 final HttpResponse response = this.httpclient.execute(target, httpget);
214
215 ConnectionRequest connreq = this.connManager.requestConnection(new HttpRoute(target), null);
216 try {
217 connreq.get(250, TimeUnit.MILLISECONDS);
218 Assert.fail("ConnectionPoolTimeoutException should have been thrown");
219 } catch (final ConnectionPoolTimeoutException expected) {
220 }
221
222 final HttpEntity e = response.getEntity();
223 Assert.assertNotNull(e);
224
225 try {
226 EntityUtils.toByteArray(e);
227 Assert.fail("MalformedChunkCodingException should have been thrown");
228 } catch (final MalformedChunkCodingException expected) {
229
230 }
231
232
233 Assert.assertEquals(0, this.connManager.getTotalStats().getAvailable());
234
235
236 connreq = this.connManager.requestConnection(new HttpRoute(target), null);
237 final HttpClientConnection conn = connreq.get(250, TimeUnit.MILLISECONDS);
238
239 this.connManager.releaseConnection(conn, null, -1, null);
240 }
241
242 }