2
* $HeadURL: https://svn.apache.org/repos/asf/httpcomponents/httpcore/tags/4.0.1/httpcore/src/test/java/org/apache/http/impl/TestDefaultConnectionReuseStrategy.java $
4
* $Date: 2007-12-08 17:55:13 +0100 (Sat, 08 Dec 2007) $
5
* ====================================================================
6
* Licensed to the Apache Software Foundation (ASF) under one
7
* or more contributor license agreements. See the NOTICE file
8
* distributed with this work for additional information
9
* regarding copyright ownership. The ASF licenses this file
10
* to you under the Apache License, Version 2.0 (the
11
* "License"); you may not use this file except in compliance
12
* with the License. You may obtain a copy of the License at
14
* http://www.apache.org/licenses/LICENSE-2.0
16
* Unless required by applicable law or agreed to in writing,
17
* software distributed under the License is distributed on an
18
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
19
* KIND, either express or implied. See the License for the
20
* specific language governing permissions and limitations
22
* ====================================================================
24
* This software consists of voluntary contributions made by many
25
* individuals on behalf of the Apache Software Foundation. For more
26
* information on the Apache Software Foundation, please see
27
* <http://www.apache.org/>.
31
package org.apache.http.impl;
33
import org.apache.http.ConnectionReuseStrategy;
34
import org.apache.http.HttpConnection;
35
import org.apache.http.HttpConnectionMetrics;
36
import org.apache.http.HttpResponse;
37
import org.apache.http.HttpVersion;
38
import org.apache.http.StatusLine;
39
import org.apache.http.entity.BasicHttpEntity;
40
import org.apache.http.message.BasicHttpResponse;
41
import org.apache.http.message.BasicStatusLine;
42
import org.apache.http.protocol.HttpContext;
43
import org.apache.http.protocol.BasicHttpContext;
44
import org.apache.http.protocol.ExecutionContext;
46
import junit.framework.Test;
47
import junit.framework.TestCase;
48
import junit.framework.TestSuite;
50
public class TestDefaultConnectionReuseStrategy extends TestCase {
52
/** A mock connection that is open and not stale. */
53
private HttpConnection mockConnection;
56
private HttpContext context;
58
/** The reuse strategy to be tested. */
59
private ConnectionReuseStrategy reuseStrategy;
63
public TestDefaultConnectionReuseStrategy(String testName) {
67
// ------------------------------------------------------- TestCase Methods
69
public static Test suite() {
70
return new TestSuite(TestDefaultConnectionReuseStrategy.class);
74
// open and not stale is required for most of the tests here
75
mockConnection = new MockConnection(true, false);
76
reuseStrategy = new DefaultConnectionReuseStrategy();
77
context = new BasicHttpContext(null);
78
context.setAttribute(ExecutionContext.HTTP_CONNECTION, mockConnection);
81
public void tearDown() {
82
mockConnection = null;
86
// ------------------------------------------------------------------- Main
87
public static void main(String args[]) {
88
String[] testCaseName = { TestDefaultConnectionReuseStrategy.class.getName() };
89
junit.textui.TestRunner.main(testCaseName);
92
public void testIllegalResponseArg() throws Exception {
94
HttpContext context = new BasicHttpContext(null);
97
reuseStrategy.keepAlive(null, context);
98
fail("IllegalArgumentException should have been thrown");
99
} catch (IllegalArgumentException ex) {
104
public void testIllegalContextArg() throws Exception {
105
HttpResponse response =
106
createResponse(HttpVersion.HTTP_1_1, 200, "OK", false, -1);
108
reuseStrategy.keepAlive(response, null);
109
fail("IllegalArgumentException should have been thrown");
110
} catch (IllegalArgumentException ex) {
115
public void testNoContentLengthResponseHttp1_0() throws Exception {
116
HttpResponse response =
117
createResponse(HttpVersion.HTTP_1_0, 200, "OK", false, -1);
119
assertFalse(reuseStrategy.keepAlive(response, context));
122
public void testNoContentLengthResponseHttp1_1() throws Exception {
123
HttpResponse response =
124
createResponse(HttpVersion.HTTP_1_1, 200, "OK", false, -1);
126
assertFalse(reuseStrategy.keepAlive(response, context));
129
public void testChunkedContent() throws Exception {
130
HttpResponse response =
131
createResponse(HttpVersion.HTTP_1_1, 200, "OK", true, -1);
133
assertTrue(reuseStrategy.keepAlive(response, context));
136
public void testClosedConnection() throws Exception {
138
// based on testChunkedContent which is known to return true
139
// the difference is in the mock connection passed here
140
HttpResponse response =
141
createResponse(HttpVersion.HTTP_1_1, 200, "OK", true, -1);
143
HttpConnection mockonn = new MockConnection(false, false);
144
context.setAttribute(ExecutionContext.HTTP_CONNECTION, mockonn);
145
assertFalse("closed connection should not be kept alive",
146
reuseStrategy.keepAlive(response, context));
149
public void testStaleConnection() throws Exception {
151
// based on testChunkedContent which is known to return true
152
// the difference is in the mock connection passed here
153
HttpResponse response =
154
createResponse(HttpVersion.HTTP_1_1, 200, "OK", true, -1);
156
HttpConnection mockonn = new MockConnection(true, true);
157
context.setAttribute(ExecutionContext.HTTP_CONNECTION, mockonn);
158
assertTrue("stale connection should not be detected",
159
reuseStrategy.keepAlive(response, context));
162
public void testIgnoreInvalidKeepAlive() throws Exception {
163
HttpResponse response =
164
createResponse(HttpVersion.HTTP_1_0, 200, "OK", false, -1);
165
response.addHeader("Connection", "keep-alive");
167
assertFalse(reuseStrategy.keepAlive(response, context));
170
public void testExplicitClose() throws Exception {
172
HttpResponse response =
173
createResponse(HttpVersion.HTTP_1_1, 200, "OK", true, -1);
174
response.addHeader("Connection", "close");
176
assertFalse(reuseStrategy.keepAlive(response, context));
179
public void testExplicitKeepAlive() throws Exception {
181
HttpResponse response =
182
createResponse(HttpVersion.HTTP_1_0, 200, "OK", false, 10);
183
response.addHeader("Connection", "keep-alive");
185
assertTrue(reuseStrategy.keepAlive(response, context));
188
public void testHTTP10Default() throws Exception {
189
HttpResponse response =
190
createResponse(HttpVersion.HTTP_1_0, 200, "OK");
192
assertFalse(reuseStrategy.keepAlive(response, context));
195
public void testHTTP11Default() throws Exception {
196
HttpResponse response =
197
createResponse(HttpVersion.HTTP_1_1, 200, "OK");
198
assertTrue(reuseStrategy.keepAlive(response, context));
201
public void testFutureHTTP() throws Exception {
202
HttpResponse response =
203
createResponse(new HttpVersion(3, 45), 200, "OK");
205
assertTrue(reuseStrategy.keepAlive(response, context));
208
public void testBrokenConnectionDirective1() throws Exception {
210
HttpResponse response =
211
createResponse(HttpVersion.HTTP_1_0, 200, "OK");
212
response.addHeader("Connection", "keep--alive");
214
assertFalse(reuseStrategy.keepAlive(response, context));
217
public void testBrokenConnectionDirective2() throws Exception {
219
HttpResponse response =
220
createResponse(HttpVersion.HTTP_1_0, 200, "OK");
221
response.addHeader("Connection", null);
223
assertFalse(reuseStrategy.keepAlive(response, context));
226
public void testConnectionTokens1() throws Exception {
228
HttpResponse response =
229
createResponse(HttpVersion.HTTP_1_1, 200, "OK", true, -1);
230
response.addHeader("Connection", "yadda, cLOSe, dumdy");
232
assertFalse(reuseStrategy.keepAlive(response, context));
235
public void testConnectionTokens2() throws Exception {
237
HttpResponse response =
238
createResponse(HttpVersion.HTTP_1_1, 200, "OK", true, -1);
239
response.addHeader("Connection", "yadda, kEEP-alive, dumdy");
241
assertTrue(reuseStrategy.keepAlive(response, context));
244
public void testConnectionTokens3() throws Exception {
246
HttpResponse response =
247
createResponse(HttpVersion.HTTP_1_1, 200, "OK", true, -1);
248
response.addHeader("Connection", "yadda, keep-alive, close, dumdy");
250
assertFalse(reuseStrategy.keepAlive(response, context));
253
public void testConnectionTokens4() throws Exception {
255
HttpResponse response =
256
createResponse(HttpVersion.HTTP_1_1, 200, "OK", true, -1);
257
response.addHeader("Connection", "yadda, close, dumdy");
258
response.addHeader("Proxy-Connection", "keep-alive");
260
// Connection takes precedence over Proxy-Connection
261
assertFalse(reuseStrategy.keepAlive(response, context));
264
public void testConnectionTokens5() throws Exception {
266
HttpResponse response =
267
createResponse(HttpVersion.HTTP_1_1, 200, "OK", true, -1);
268
response.addHeader("Connection", "yadda, dumdy");
269
response.addHeader("Proxy-Connection", "close");
271
// Connection takes precedence over Proxy-Connection,
272
// even if it doesn't contain a recognized token.
273
// Default for HTTP/1.1 is to keep alive.
274
assertTrue(reuseStrategy.keepAlive(response, context));
277
public void testConnectionTokens6() throws Exception {
279
HttpResponse response =
280
createResponse(HttpVersion.HTTP_1_1, 200, "OK", true, -1);
281
response.addHeader("Connection", "");
282
response.addHeader("Proxy-Connection", "close");
284
// Connection takes precedence over Proxy-Connection,
285
// even if it is empty. Default for HTTP/1.1 is to keep alive.
286
assertTrue(reuseStrategy.keepAlive(response, context));
289
public void testConnectionTokensInvalid() throws Exception {
291
HttpResponse response =
292
createResponse(HttpVersion.HTTP_1_1, 200, "OK", true, -1);
293
response.addHeader("Connection", "keep-alive=true");
295
assertFalse(reuseStrategy.keepAlive(response, context));
300
* Creates a response without an entity.
302
* @param version the HTTP version
303
* @param status the status code
304
* @param message the status message
306
* @return a response with the argument attributes, but no headers
308
private final static HttpResponse createResponse(HttpVersion version,
312
StatusLine statusline = new BasicStatusLine(version, status, message);
313
HttpResponse response = new BasicHttpResponse(statusline);
317
} // createResponse/empty
321
* Creates a response with an entity.
323
* @param version the HTTP version
324
* @param status the status code
325
* @param message the status message
326
* @param chunked whether the entity should indicate chunked encoding
327
* @param length the content length to be indicated by the entity
329
* @return a response with the argument attributes, but no headers
331
private final static HttpResponse createResponse(HttpVersion version,
337
BasicHttpEntity entity = new BasicHttpEntity();
338
entity.setChunked(chunked);
339
entity.setContentLength(length);
340
HttpResponse response = createResponse(version, status, message);
341
response.setEntity(entity);
345
} // createResponse/entity
350
* This is neither client nor server connection, since the default
351
* strategy is agnostic. It does not allow modification of it's state,
352
* since the strategy is supposed to decide about keep-alive, but not
353
* to modify the connection's state.
355
private final static class MockConnection implements HttpConnection {
357
private boolean iAmOpen;
358
private boolean iAmStale;
360
public MockConnection(boolean open, boolean stale) {
365
public final boolean isOpen() {
369
public void setSocketTimeout(int timeout) {
372
public int getSocketTimeout() {
376
public final boolean isStale() {
380
public final void close() {
381
throw new UnsupportedOperationException
382
("connection state must not be modified");
385
public final void shutdown() {
386
throw new UnsupportedOperationException
387
("connection state must not be modified");
390
public HttpConnectionMetrics getMetrics() {
394
} // class MockConnection
396
} // class TestDefaultConnectionReuseStrategy