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.client;
28  
29  import java.net.URI;
30  import java.util.List;
31  
32  import org.apache.http.HttpEntity;
33  import org.apache.http.HttpEntityEnclosingRequest;
34  import org.apache.http.HttpHost;
35  import org.apache.http.HttpResponse;
36  import org.apache.http.HttpStatus;
37  import org.apache.http.HttpVersion;
38  import org.apache.http.ProtocolException;
39  import org.apache.http.client.config.RequestConfig;
40  import org.apache.http.client.methods.HttpDelete;
41  import org.apache.http.client.methods.HttpGet;
42  import org.apache.http.client.methods.HttpHead;
43  import org.apache.http.client.methods.HttpPost;
44  import org.apache.http.client.methods.HttpPut;
45  import org.apache.http.client.methods.HttpTrace;
46  import org.apache.http.client.methods.HttpUriRequest;
47  import org.apache.http.client.protocol.HttpClientContext;
48  import org.apache.http.entity.BasicHttpEntity;
49  import org.apache.http.message.BasicHttpResponse;
50  import org.apache.http.protocol.BasicHttpContext;
51  import org.apache.http.protocol.HttpContext;
52  import org.apache.http.protocol.HttpCoreContext;
53  import org.junit.Assert;
54  import org.junit.Test;
55  
56  public class TestDefaultRedirectStrategy {
57  
58      @Test
59      public void testIsRedirectable() {
60          final DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
61          Assert.assertTrue(redirectStrategy.isRedirectable(HttpGet.METHOD_NAME));
62          Assert.assertTrue(redirectStrategy.isRedirectable(HttpHead.METHOD_NAME));
63          Assert.assertFalse(redirectStrategy.isRedirectable(HttpPut.METHOD_NAME));
64          Assert.assertFalse(redirectStrategy.isRedirectable(HttpPost.METHOD_NAME));
65          Assert.assertFalse(redirectStrategy.isRedirectable(HttpDelete.METHOD_NAME));
66      }
67  
68      @Test
69      public void testIsRedirectedMovedTemporary() throws Exception {
70          final DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
71          final HttpClientContext context = HttpClientContext.create();
72          final HttpGet httpget = new HttpGet("http://localhost/");
73          final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1,
74                  HttpStatus.SC_MOVED_TEMPORARILY, "Redirect");
75          response.addHeader("Location", "http://localhost/stuff");
76          Assert.assertTrue(redirectStrategy.isRedirected(httpget, response, context));
77          final HttpPost httppost = new HttpPost("http://localhost/");
78          Assert.assertFalse(redirectStrategy.isRedirected(httppost, response, context));
79      }
80  
81      @Test
82      public void testIsRedirectedMovedTemporaryNoLocation() throws Exception {
83          final DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
84          final HttpClientContext context = HttpClientContext.create();
85          final HttpGet httpget = new HttpGet("http://localhost/");
86          final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1,
87                  HttpStatus.SC_MOVED_TEMPORARILY, "Redirect");
88          Assert.assertFalse(redirectStrategy.isRedirected(httpget, response, context));
89      }
90  
91      @Test
92      public void testIsRedirectedMovedPermanently() throws Exception {
93          final DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
94          final HttpClientContext context = HttpClientContext.create();
95          final HttpGet httpget = new HttpGet("http://localhost/");
96          final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1,
97                  HttpStatus.SC_MOVED_PERMANENTLY, "Redirect");
98          Assert.assertTrue(redirectStrategy.isRedirected(httpget, response, context));
99          final HttpPost httppost = new HttpPost("http://localhost/");
100         Assert.assertFalse(redirectStrategy.isRedirected(httppost, response, context));
101     }
102 
103     @Test
104     public void testIsRedirectedTemporaryRedirect() throws Exception {
105         final DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
106         final HttpClientContext context = HttpClientContext.create();
107         final HttpGet httpget = new HttpGet("http://localhost/");
108         final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1,
109                 HttpStatus.SC_TEMPORARY_REDIRECT, "Redirect");
110         Assert.assertTrue(redirectStrategy.isRedirected(httpget, response, context));
111         final HttpPost httppost = new HttpPost("http://localhost/");
112         Assert.assertFalse(redirectStrategy.isRedirected(httppost, response, context));
113     }
114 
115     @Test
116     public void testIsRedirectedSeeOther() throws Exception {
117         final DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
118         final HttpClientContext context = HttpClientContext.create();
119         final HttpGet httpget = new HttpGet("http://localhost/");
120         final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1,
121                 HttpStatus.SC_SEE_OTHER, "Redirect");
122         Assert.assertTrue(redirectStrategy.isRedirected(httpget, response, context));
123         final HttpPost httppost = new HttpPost("http://localhost/");
124         Assert.assertTrue(redirectStrategy.isRedirected(httppost, response, context));
125     }
126 
127     @Test
128     public void testIsRedirectedUnknownStatus() throws Exception {
129         final DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
130         final HttpClientContext context = HttpClientContext.create();
131         final HttpGet httpget = new HttpGet("http://localhost/");
132         final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 333, "Redirect");
133         Assert.assertFalse(redirectStrategy.isRedirected(httpget, response, context));
134         final HttpPost httppost = new HttpPost("http://localhost/");
135         Assert.assertFalse(redirectStrategy.isRedirected(httppost, response, context));
136     }
137 
138     @Test
139     public void testIsRedirectedInvalidInput() throws Exception {
140         final DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
141         final HttpClientContext context = HttpClientContext.create();
142         final HttpGet httpget = new HttpGet("http://localhost/");
143         final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1,
144                 HttpStatus.SC_SEE_OTHER, "Redirect");
145         try {
146             redirectStrategy.isRedirected(null, response, context);
147             Assert.fail("IllegalArgumentException expected");
148         } catch (final IllegalArgumentException expected) {
149         }
150         try {
151             redirectStrategy.isRedirected(httpget, null, context);
152             Assert.fail("IllegalArgumentException expected");
153         } catch (final IllegalArgumentException expected) {
154         }
155     }
156 
157     @Test
158     public void testGetLocationUri() throws Exception {
159         final DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
160         final HttpClientContext context = HttpClientContext.create();
161         final HttpGet httpget = new HttpGet("http://localhost/");
162         final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1,
163                 HttpStatus.SC_MOVED_TEMPORARILY, "Redirect");
164         response.addHeader("Location", "http://localhost/stuff");
165         final URI uri = redirectStrategy.getLocationURI(httpget, response, context);
166         Assert.assertEquals(URI.create("http://localhost/stuff"), uri);
167     }
168 
169     @Test(expected=ProtocolException.class)
170     public void testGetLocationUriMissingHeader() throws Exception {
171         final DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
172         final HttpClientContext context = HttpClientContext.create();
173         final HttpGet httpget = new HttpGet("http://localhost/");
174         final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1,
175                 HttpStatus.SC_MOVED_TEMPORARILY, "Redirect");
176         redirectStrategy.getLocationURI(httpget, response, context);
177     }
178 
179     @Test(expected=ProtocolException.class)
180     public void testGetLocationUriInvalidLocation() throws Exception {
181         final DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
182         final HttpClientContext context = HttpClientContext.create();
183         final HttpGet httpget = new HttpGet("http://localhost/");
184         final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1,
185                 HttpStatus.SC_MOVED_TEMPORARILY, "Redirect");
186         response.addHeader("Location", "http://localhost/not valid");
187         redirectStrategy.getLocationURI(httpget, response, context);
188     }
189 
190     @Test
191     public void testGetLocationUriRelative() throws Exception {
192         final DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
193         final HttpClientContext context = HttpClientContext.create();
194         context.setAttribute(HttpCoreContext.HTTP_TARGET_HOST, new HttpHost("localhost"));
195         final HttpGet httpget = new HttpGet("http://localhost/");
196         final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1,
197                 HttpStatus.SC_MOVED_TEMPORARILY, "Redirect");
198         response.addHeader("Location", "/stuff");
199         final URI uri = redirectStrategy.getLocationURI(httpget, response, context);
200         Assert.assertEquals(URI.create("http://localhost/stuff"), uri);
201     }
202 
203     @Test(expected=IllegalStateException.class)
204     public void testGetLocationUriRelativeMissingTargetHost() throws Exception {
205         final DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
206         final HttpClientContext context = HttpClientContext.create();
207         final HttpGet httpget = new HttpGet("http://localhost/");
208         final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1,
209                 HttpStatus.SC_MOVED_TEMPORARILY, "Redirect");
210         response.addHeader("Location", "/stuff");
211         final URI uri = redirectStrategy.getLocationURI(httpget, response, context);
212         Assert.assertEquals(URI.create("http://localhost/stuff"), uri);
213     }
214 
215     @Test
216     public void testGetLocationUriRelativeWithFragment() throws Exception {
217         final DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
218         final HttpClientContext context = HttpClientContext.create();
219         context.setAttribute(HttpCoreContext.HTTP_TARGET_HOST, new HttpHost("localhost"));
220         final HttpGet httpget = new HttpGet("http://localhost/");
221         final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1,
222                 HttpStatus.SC_MOVED_TEMPORARILY, "Redirect");
223         response.addHeader("Location", "/stuff#fragment");
224         final URI uri = redirectStrategy.getLocationURI(httpget, response, context);
225         Assert.assertEquals(URI.create("http://localhost/stuff#fragment"), uri);
226     }
227 
228     @Test
229     public void testGetLocationUriAbsoluteWithFragment() throws Exception {
230         final DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
231         final HttpClientContext context = HttpClientContext.create();
232         context.setAttribute(HttpCoreContext.HTTP_TARGET_HOST, new HttpHost("localhost"));
233         final HttpGet httpget = new HttpGet("http://localhost/");
234         final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1,
235                 HttpStatus.SC_MOVED_TEMPORARILY, "Redirect");
236         response.addHeader("Location", "http://localhost/stuff#fragment");
237         final URI uri = redirectStrategy.getLocationURI(httpget, response, context);
238         Assert.assertEquals(URI.create("http://localhost/stuff#fragment"), uri);
239     }
240 
241     @Test
242     public void testGetLocationUriNormalized() throws Exception {
243         final DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
244         final HttpClientContext context = HttpClientContext.create();
245         context.setAttribute(HttpCoreContext.HTTP_TARGET_HOST, new HttpHost("localhost"));
246         final HttpGet httpget = new HttpGet("http://localhost/");
247         final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1,
248                 HttpStatus.SC_MOVED_TEMPORARILY, "Redirect");
249         response.addHeader("Location", "http://localhost/././stuff/../morestuff");
250         final URI uri = redirectStrategy.getLocationURI(httpget, response, context);
251         Assert.assertEquals(URI.create("http://localhost/morestuff"), uri);
252     }
253 
254     @Test(expected=ProtocolException.class)
255     public void testGetLocationUriRelativeLocationNotAllowed() throws Exception {
256         final DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
257         final HttpClientContext context = HttpClientContext.create();
258         context.setAttribute(HttpCoreContext.HTTP_TARGET_HOST, new HttpHost("localhost"));
259         final RequestConfig config = RequestConfig.custom().setRelativeRedirectsAllowed(false).build();
260         context.setRequestConfig(config);
261 
262         final HttpGet httpget = new HttpGet("http://localhost/");
263         final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1,
264                 HttpStatus.SC_MOVED_TEMPORARILY, "Redirect");
265         response.addHeader("Location", "/stuff");
266         redirectStrategy.getLocationURI(httpget, response, context);
267     }
268 
269     @Test
270     public void testGetLocationUriAllowCircularRedirects() throws Exception {
271         final DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
272         final HttpClientContext context = HttpClientContext.create();
273         context.setAttribute(HttpCoreContext.HTTP_TARGET_HOST, new HttpHost("localhost"));
274         final RequestConfig config = RequestConfig.custom().setCircularRedirectsAllowed(true).build();
275         context.setRequestConfig(config);
276         final URI uri1 = URI.create("http://localhost/stuff1");
277         final URI uri2 = URI.create("http://localhost/stuff2");
278         final URI uri3 = URI.create("http://localhost/stuff3");
279         final HttpGet httpget1 = new HttpGet("http://localhost/");
280         final HttpResponse response1 = new BasicHttpResponse(HttpVersion.HTTP_1_1,
281                 HttpStatus.SC_MOVED_TEMPORARILY, "Redirect");
282         response1.addHeader("Location", uri1.toASCIIString());
283         final HttpGet httpget2 = new HttpGet(uri1.toASCIIString());
284         final HttpResponse response2 = new BasicHttpResponse(HttpVersion.HTTP_1_1,
285                 HttpStatus.SC_MOVED_TEMPORARILY, "Redirect");
286         response2.addHeader("Location", uri2.toASCIIString());
287         final HttpGet httpget3 = new HttpGet(uri2.toASCIIString());
288         final HttpResponse response3 = new BasicHttpResponse(HttpVersion.HTTP_1_1,
289                 HttpStatus.SC_MOVED_TEMPORARILY, "Redirect");
290         response3.addHeader("Location", uri3.toASCIIString());
291         Assert.assertEquals(uri1, redirectStrategy.getLocationURI(httpget1, response1, context));
292         Assert.assertEquals(uri2, redirectStrategy.getLocationURI(httpget2, response2, context));
293         Assert.assertEquals(uri3, redirectStrategy.getLocationURI(httpget3, response3, context));
294 
295         final List<URI> uris = context.getRedirectLocations();
296         Assert.assertNotNull(uris);
297         Assert.assertTrue(uris.contains(uri1));
298         Assert.assertTrue(uris.contains(uri2));
299         Assert.assertTrue(uris.contains(uri3));
300         Assert.assertEquals(3, uris.size());
301         Assert.assertEquals(uri1, uris.get(0));
302         Assert.assertEquals(uri2, uris.get(1));
303         Assert.assertEquals(uri3, uris.get(2));
304     }
305 
306     @Test(expected=ProtocolException.class)
307     public void testGetLocationUriDisallowCircularRedirects() throws Exception {
308         final DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
309         final HttpClientContext context = HttpClientContext.create();
310         context.setAttribute(HttpCoreContext.HTTP_TARGET_HOST, new HttpHost("localhost"));
311         final HttpGet httpget = new HttpGet("http://localhost/stuff");
312         final RequestConfig config = RequestConfig.custom().setCircularRedirectsAllowed(false).build();
313         context.setRequestConfig(config);
314         final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1,
315                 HttpStatus.SC_MOVED_TEMPORARILY, "Redirect");
316         response.addHeader("Location", "http://localhost/stuff");
317         final URI uri = URI.create("http://localhost/stuff");
318         Assert.assertEquals(uri, redirectStrategy.getLocationURI(httpget, response, context));
319         redirectStrategy.getLocationURI(httpget, response, context);
320     }
321 
322     @Test
323     public void testGetLocationUriInvalidInput() throws Exception {
324         final DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
325         final HttpClientContext context = HttpClientContext.create();
326         final HttpGet httpget = new HttpGet("http://localhost/");
327         final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1,
328                 HttpStatus.SC_MOVED_TEMPORARILY, "Redirect");
329         response.addHeader("Location", "http://localhost/stuff");
330         try {
331             redirectStrategy.getLocationURI(null, response, context);
332             Assert.fail("IllegalArgumentException expected");
333         } catch (final IllegalArgumentException expected) {
334         }
335         try {
336             redirectStrategy.getLocationURI(httpget, null, context);
337             Assert.fail("IllegalArgumentException expected");
338         } catch (final IllegalArgumentException expected) {
339         }
340         try {
341             redirectStrategy.getLocationURI(httpget, response, null);
342             Assert.fail("IllegalArgumentException expected");
343         } catch (final IllegalArgumentException expected) {
344         }
345     }
346 
347     @Test
348     public void testGetRedirectRequest() throws Exception {
349         final DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
350         final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1,
351                 HttpStatus.SC_SEE_OTHER, "Redirect");
352         response.addHeader("Location", "http://localhost/stuff");
353         final HttpContext context1 = new BasicHttpContext();
354         final HttpUriRequest redirect1 = redirectStrategy.getRedirect(
355                 new HttpGet("http://localhost/"), response, context1);
356         Assert.assertEquals("GET", redirect1.getMethod());
357         final HttpContext context2 = new BasicHttpContext();
358         final HttpUriRequest redirect2 = redirectStrategy.getRedirect(
359                 new HttpPost("http://localhost/"), response, context2);
360         Assert.assertEquals("GET", redirect2.getMethod());
361         final HttpContext context3 = new BasicHttpContext();
362         final HttpUriRequest redirect3 = redirectStrategy.getRedirect(
363                 new HttpHead("http://localhost/"), response, context3);
364         Assert.assertEquals("HEAD", redirect3.getMethod());
365     }
366 
367     @Test
368     public void testGetRedirectRequestForTemporaryRedirect() throws Exception {
369         final DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
370         final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1,
371                 HttpStatus.SC_TEMPORARY_REDIRECT, "Temporary Redirect");
372         response.addHeader("Location", "http://localhost/stuff");
373         final HttpContext context1 = new BasicHttpContext();
374         final HttpUriRequest redirect1 = redirectStrategy.getRedirect(
375                 new HttpTrace("http://localhost/"), response, context1);
376         Assert.assertEquals("TRACE", redirect1.getMethod());
377         final HttpContext context2 = new BasicHttpContext();
378         final HttpPost httppost = new HttpPost("http://localhost/");
379         final HttpEntity entity = new BasicHttpEntity();
380         httppost.setEntity(entity);
381         final HttpUriRequest redirect2 = redirectStrategy.getRedirect(
382                 httppost, response, context2);
383         Assert.assertEquals("POST", redirect2.getMethod());
384         Assert.assertTrue(redirect2 instanceof HttpEntityEnclosingRequest);
385         Assert.assertSame(entity, ((HttpEntityEnclosingRequest) redirect2).getEntity());
386     }
387 
388     @Test
389     public void testCreateLocationURI() throws Exception {
390         final DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
391         Assert.assertEquals("http://blahblah/",
392                 redirectStrategy.createLocationURI("http://BlahBlah").toASCIIString());
393     }
394 
395     @Test(expected=ProtocolException.class)
396     public void testCreateLocationURIInvalid() throws Exception {
397         final DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
398         redirectStrategy.createLocationURI(":::::::");
399     }
400 
401 }