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  
28  package org.apache.hc.core5.http.impl;
29  
30  import org.apache.hc.core5.http.ConnectionReuseStrategy;
31  import org.apache.hc.core5.http.HttpRequest;
32  import org.apache.hc.core5.http.HttpResponse;
33  import org.apache.hc.core5.http.HttpStatus;
34  import org.apache.hc.core5.http.HttpVersion;
35  import org.apache.hc.core5.http.message.BasicHttpRequest;
36  import org.apache.hc.core5.http.message.BasicHttpResponse;
37  import org.apache.hc.core5.http.protocol.BasicHttpContext;
38  import org.apache.hc.core5.http.protocol.HttpContext;
39  import org.junit.Assert;
40  import org.junit.Before;
41  import org.junit.Test;
42  
43  public class TestDefaultConnectionReuseStrategy {
44  
45      /** HTTP context. */
46      private HttpContext context;
47  
48      /** The reuse strategy to be tested. */
49      private ConnectionReuseStrategy reuseStrategy;
50  
51      @Before
52      public void setUp() {
53          reuseStrategy = DefaultConnectionReuseStrategy.INSTANCE;
54          context = new BasicHttpContext(null);
55      }
56  
57      @Test(expected=IllegalArgumentException.class)
58      public void testIllegalResponseArg() throws Exception {
59          reuseStrategy.keepAlive(null, null, this.context);
60      }
61  
62      @Test
63      public void testNoContentLengthResponseHttp1_0() throws Exception {
64          context.setProtocolVersion(HttpVersion.HTTP_1_0);
65          final HttpResponse response = new BasicHttpResponse(200, "OK");
66          Assert.assertFalse(reuseStrategy.keepAlive(null, response, context));
67      }
68  
69      @Test
70      public void testNoContentLengthResponseHttp1_1() throws Exception {
71          final HttpResponse response = new BasicHttpResponse(200, "OK");
72          Assert.assertFalse(reuseStrategy.keepAlive(null, response, context));
73      }
74  
75      @Test
76      public void testChunkedContent() throws Exception {
77          final HttpResponse response = new BasicHttpResponse(200, "OK");
78          response.addHeader("Transfer-Encoding", "chunked");
79          Assert.assertTrue(reuseStrategy.keepAlive(null, response, context));
80      }
81  
82      @Test
83      public void testIgnoreInvalidKeepAlive() throws Exception {
84          context.setProtocolVersion(HttpVersion.HTTP_1_0);
85          final HttpResponse response = new BasicHttpResponse(200, "OK");
86          response.addHeader("Connection", "keep-alive");
87          Assert.assertFalse(reuseStrategy.keepAlive(null, response, context));
88      }
89  
90      @Test
91      public void testExplicitClose() throws Exception {
92          // Use HTTP 1.1
93          final HttpResponse response = new BasicHttpResponse(200, "OK");
94          response.addHeader("Transfer-Encoding", "chunked");
95          response.addHeader("Connection", "close");
96          Assert.assertFalse(reuseStrategy.keepAlive(null, response, context));
97      }
98  
99      @Test
100     public void testExplicitKeepAlive() throws Exception {
101         // Use HTTP 1.0
102         context.setProtocolVersion(HttpVersion.HTTP_1_0);
103         final HttpResponse response = new BasicHttpResponse(200, "OK");
104         response.addHeader("Content-Length", "10");
105         response.addHeader("Connection", "keep-alive");
106 
107         Assert.assertTrue(reuseStrategy.keepAlive(null, response, context));
108     }
109 
110     @Test
111     public void testHTTP10Default() throws Exception {
112         context.setProtocolVersion(HttpVersion.HTTP_1_0);
113         final HttpResponse response = new BasicHttpResponse(200, "OK");
114         response.addHeader("Content-Length", "10");
115         Assert.assertFalse(reuseStrategy.keepAlive(null, response, context));
116     }
117 
118     @Test
119     public void testHTTP11Default() throws Exception {
120         final HttpResponse response = new BasicHttpResponse(200, "OK");
121         response.addHeader("Content-Length", "10");
122         Assert.assertTrue(reuseStrategy.keepAlive(null, response, context));
123     }
124 
125     @Test
126     public void testBrokenConnectionDirective1() throws Exception {
127         // Use HTTP 1.0
128         context.setProtocolVersion(HttpVersion.HTTP_1_0);
129         final HttpResponse response = new BasicHttpResponse(200, "OK");
130         response.addHeader("Content-Length", "10");
131         response.addHeader("Connection", "keep--alive");
132         Assert.assertFalse(reuseStrategy.keepAlive(null, response, context));
133     }
134 
135     @Test
136     public void testBrokenConnectionDirective2() throws Exception {
137         // Use HTTP 1.0
138         context.setProtocolVersion(HttpVersion.HTTP_1_0);
139         final HttpResponse response = new BasicHttpResponse(200, "OK");
140         response.addHeader("Content-Length", "10");
141         response.addHeader("Connection", null);
142         Assert.assertFalse(reuseStrategy.keepAlive(null, response, context));
143     }
144 
145     @Test
146     public void testConnectionTokens1() throws Exception {
147         // Use HTTP 1.1
148         final HttpResponse response = new BasicHttpResponse(200, "OK");
149         response.addHeader("Transfer-Encoding", "chunked");
150         response.addHeader("Connection", "yadda, cLOSe, dumdy");
151         Assert.assertFalse(reuseStrategy.keepAlive(null, response, context));
152     }
153 
154     @Test
155     public void testConnectionTokens2() throws Exception {
156         // Use HTTP 1.1
157         final HttpResponse response = new BasicHttpResponse(200, "OK");
158         response.addHeader("Transfer-Encoding", "chunked");
159         response.addHeader("Connection", "yadda, kEEP-alive, dumdy");
160         Assert.assertTrue(reuseStrategy.keepAlive(null, response, context));
161     }
162 
163     @Test
164     public void testConnectionTokens3() throws Exception {
165         // Use HTTP 1.1
166         final HttpResponse response = new BasicHttpResponse(200, "OK");
167         response.addHeader("Transfer-Encoding", "chunked");
168         response.addHeader("Connection", "yadda, keep-alive, close, dumdy");
169         Assert.assertFalse(reuseStrategy.keepAlive(null, response, context));
170     }
171 
172     @Test
173     public void testConnectionTokens4() throws Exception {
174         // Use HTTP 1.1
175         final HttpResponse response = new BasicHttpResponse(200, "OK");
176         response.addHeader("Transfer-Encoding", "chunked");
177         response.addHeader("Connection", "yadda, close, dumdy");
178         response.addHeader("Proxy-Connection", "keep-alive");
179         // Connection takes precedence over Proxy-Connection
180         Assert.assertFalse(reuseStrategy.keepAlive(null, response, context));
181     }
182 
183     @Test
184     public void testConnectionTokens5() throws Exception {
185         // Use HTTP 1.1
186         final HttpResponse response = new BasicHttpResponse(200, "OK");
187         response.addHeader("Transfer-Encoding", "chunked");
188         response.addHeader("Connection", "yadda, dumdy");
189         response.addHeader("Proxy-Connection", "close");
190         // Connection takes precedence over Proxy-Connection,
191         // even if it doesn't contain a recognized token.
192         // Default for HTTP/1.1 is to keep alive.
193         Assert.assertTrue(reuseStrategy.keepAlive(null, response, context));
194     }
195 
196     @Test
197     public void testConnectionTokens6() throws Exception {
198         // Use HTTP 1.1
199         final HttpResponse response = new BasicHttpResponse(200, "OK");
200         response.addHeader("Transfer-Encoding", "chunked");
201         response.addHeader("Connection", "");
202         response.addHeader("Proxy-Connection", "close");
203         // Connection takes precedence over Proxy-Connection,
204         // even if it is empty. Default for HTTP/1.1 is to keep alive.
205         Assert.assertTrue(reuseStrategy.keepAlive(null, response, context));
206     }
207 
208     @Test
209     public void testMultipleContentLength() throws Exception {
210         // Use HTTP 1.1
211         final HttpResponse response = new BasicHttpResponse(200, "OK");
212         response.addHeader("Content-Length", "10");
213         response.addHeader("Content-Length", "11");
214         Assert.assertFalse(reuseStrategy.keepAlive(null, response, context));
215     }
216 
217     @Test
218     public void testNoContentResponse() throws Exception {
219         // Use HTTP 1.1
220         final HttpResponse response = new BasicHttpResponse(HttpStatus.SC_NO_CONTENT, "No Content");
221         Assert.assertTrue(reuseStrategy.keepAlive(null, response, context));
222     }
223 
224     @Test
225     public void testNoContentResponseHttp10() throws Exception {
226         // Use HTTP 1.0
227         context.setProtocolVersion(HttpVersion.HTTP_1_0);
228         final HttpResponse response = new BasicHttpResponse(HttpStatus.SC_NO_CONTENT, "No Content");
229         Assert.assertFalse(reuseStrategy.keepAlive(null, response, context));
230     }
231 
232     @Test
233     public void testRequestExplicitClose() throws Exception {
234         final HttpRequest request = new BasicHttpRequest("GET", "/");
235         request.addHeader("Connection", "close");
236 
237         final HttpResponse response = new BasicHttpResponse(200, "OK");
238         response.addHeader("Transfer-Encoding", "chunked");
239         response.addHeader("Connection", "keep-alive");
240         Assert.assertFalse(reuseStrategy.keepAlive(request, response, context));
241     }
242 
243     @Test
244     public void testRequestNoExplicitClose() throws Exception {
245         final HttpRequest request = new BasicHttpRequest("GET", "/");
246         request.addHeader("Connection", "blah, blah, blah");
247 
248         final HttpResponse response = new BasicHttpResponse(200, "OK");
249         response.addHeader("Transfer-Encoding", "chunked");
250         response.addHeader("Connection", "keep-alive");
251         Assert.assertTrue(reuseStrategy.keepAlive(request, response, context));
252     }
253 
254     @Test
255     public void testRequestExplicitCloseMultipleTokens() throws Exception {
256         final HttpRequest request = new BasicHttpRequest("GET", "/");
257         request.addHeader("Connection", "blah, blah, blah");
258         request.addHeader("Connection", "keep-alive");
259         request.addHeader("Connection", "close");
260 
261         final HttpResponse response = new BasicHttpResponse(200, "OK");
262         response.addHeader("Transfer-Encoding", "chunked");
263         response.addHeader("Connection", "keep-alive");
264         Assert.assertFalse(reuseStrategy.keepAlive(request, response, context));
265     }
266 
267     @Test
268     public void testRequestClose() throws Exception {
269         final HttpRequest request = new BasicHttpRequest("GET", "/");
270         request.addHeader("Connection", "close");
271 
272         final HttpResponse response = new BasicHttpResponse(200, "OK");
273         response.addHeader("Content-Length", "10");
274         response.addHeader("Connection", "keep-alive");
275 
276         Assert.assertFalse(reuseStrategy.keepAlive(request, response, context));
277     }
278 
279     @Test
280     public void testHeadRequestWithout() throws Exception {
281         final HttpRequest request = new BasicHttpRequest("HEAD", "/");
282         final HttpResponse response = new BasicHttpResponse(200, "OK");
283 
284         Assert.assertTrue(reuseStrategy.keepAlive(request, response, context));
285     }
286 
287 }
288