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.integration;
28  
29  import java.io.IOException;
30  import java.net.URI;
31  import java.util.Arrays;
32  import java.util.List;
33  
34  import org.apache.http.Header;
35  import org.apache.http.HttpException;
36  import org.apache.http.HttpHost;
37  import org.apache.http.HttpInetConnection;
38  import org.apache.http.HttpRequest;
39  import org.apache.http.HttpResponse;
40  import org.apache.http.HttpStatus;
41  import org.apache.http.ProtocolException;
42  import org.apache.http.client.CircularRedirectException;
43  import org.apache.http.client.ClientProtocolException;
44  import org.apache.http.client.CookieStore;
45  import org.apache.http.client.RedirectException;
46  import org.apache.http.client.config.RequestConfig;
47  import org.apache.http.client.methods.HttpGet;
48  import org.apache.http.client.methods.HttpPost;
49  import org.apache.http.client.protocol.HttpClientContext;
50  import org.apache.http.client.utils.URIUtils;
51  import org.apache.http.cookie.SM;
52  import org.apache.http.entity.StringEntity;
53  import org.apache.http.impl.client.BasicCookieStore;
54  import org.apache.http.impl.cookie.BasicClientCookie;
55  import org.apache.http.localserver.LocalServerTestBase;
56  import org.apache.http.message.BasicHeader;
57  import org.apache.http.protocol.HTTP;
58  import org.apache.http.protocol.HttpContext;
59  import org.apache.http.protocol.HttpCoreContext;
60  import org.apache.http.protocol.HttpRequestHandler;
61  import org.apache.http.protocol.UriHttpRequestHandlerMapper;
62  import org.apache.http.util.EntityUtils;
63  import org.junit.Assert;
64  import org.junit.Test;
65  
66  /**
67   * Redirection test cases.
68   */
69  public class TestRedirects extends LocalServerTestBase {
70  
71      private static class BasicRedirectService implements HttpRequestHandler {
72  
73          private final int statuscode;
74  
75          public BasicRedirectService(final int statuscode) {
76              super();
77              this.statuscode = statuscode > 0 ? statuscode : HttpStatus.SC_MOVED_TEMPORARILY;
78          }
79  
80          public BasicRedirectService() {
81              this(-1);
82          }
83  
84          @Override
85          public void handle(
86                  final HttpRequest request,
87                  final HttpResponse response,
88                  final HttpContext context) throws HttpException, IOException {
89              final HttpInetConnection conn = (HttpInetConnection) context.getAttribute(HttpCoreContext.HTTP_CONNECTION);
90              final int port = conn.getLocalPort();
91              final String uri = request.getRequestLine().getUri();
92              if (uri.equals("/oldlocation/")) {
93                  response.setStatusCode(this.statuscode);
94                  response.addHeader(new BasicHeader("Location",
95                          "http://localhost:" + port + "/newlocation/"));
96                  response.addHeader(new BasicHeader("Connection", "close"));
97              } else if (uri.equals("/newlocation/")) {
98                  response.setStatusCode(HttpStatus.SC_OK);
99                  final StringEntity entity = new StringEntity("Successful redirect");
100                 response.setEntity(entity);
101             } else {
102                 response.setStatusCode(HttpStatus.SC_NOT_FOUND);
103             }
104         }
105 
106     }
107 
108     private static class CircularRedirectService implements HttpRequestHandler {
109 
110         public CircularRedirectService() {
111             super();
112         }
113 
114         @Override
115         public void handle(
116                 final HttpRequest request,
117                 final HttpResponse response,
118                 final HttpContext context) throws HttpException, IOException {
119             final String uri = request.getRequestLine().getUri();
120             if (uri.startsWith("/circular-oldlocation")) {
121                 response.setStatusCode(HttpStatus.SC_MOVED_TEMPORARILY);
122                 response.addHeader(new BasicHeader("Location", "/circular-location2"));
123             } else if (uri.startsWith("/circular-location2")) {
124                 response.setStatusCode(HttpStatus.SC_MOVED_TEMPORARILY);
125                 response.addHeader(new BasicHeader("Location", "/circular-oldlocation"));
126             } else {
127                 response.setStatusCode(HttpStatus.SC_NOT_FOUND);
128             }
129         }
130     }
131 
132     private static class RelativeRedirectService implements HttpRequestHandler {
133 
134         public RelativeRedirectService() {
135             super();
136         }
137 
138         @Override
139         public void handle(
140                 final HttpRequest request,
141                 final HttpResponse response,
142                 final HttpContext context) throws HttpException, IOException {
143             final String uri = request.getRequestLine().getUri();
144             if (uri.equals("/oldlocation/")) {
145                 response.setStatusCode(HttpStatus.SC_MOVED_TEMPORARILY);
146                 response.addHeader(new BasicHeader("Location", "/relativelocation/"));
147             } else if (uri.equals("/relativelocation/")) {
148                 response.setStatusCode(HttpStatus.SC_OK);
149                 final StringEntity entity = new StringEntity("Successful redirect");
150                 response.setEntity(entity);
151             } else {
152                 response.setStatusCode(HttpStatus.SC_NOT_FOUND);
153             }
154         }
155     }
156 
157     private static class RelativeRedirectService2 implements HttpRequestHandler {
158 
159         public RelativeRedirectService2() {
160             super();
161         }
162 
163         @Override
164         public void handle(
165                 final HttpRequest request,
166                 final HttpResponse response,
167                 final HttpContext context) throws HttpException, IOException {
168             final String uri = request.getRequestLine().getUri();
169             if (uri.equals("/test/oldlocation")) {
170                 response.setStatusCode(HttpStatus.SC_MOVED_TEMPORARILY);
171                 response.addHeader(new BasicHeader("Location", "relativelocation"));
172             } else if (uri.equals("/test/relativelocation")) {
173                 response.setStatusCode(HttpStatus.SC_OK);
174                 final StringEntity entity = new StringEntity("Successful redirect");
175                 response.setEntity(entity);
176             } else {
177                 response.setStatusCode(HttpStatus.SC_NOT_FOUND);
178             }
179         }
180     }
181 
182     private static class RomeRedirectService implements HttpRequestHandler {
183 
184         public RomeRedirectService() {
185             super();
186         }
187 
188         @Override
189         public void handle(
190                 final HttpRequest request,
191                 final HttpResponse response,
192                 final HttpContext context) throws HttpException, IOException {
193             final String uri = request.getRequestLine().getUri();
194             if (uri.equals("/rome")) {
195                 response.setStatusCode(HttpStatus.SC_OK);
196                 final StringEntity entity = new StringEntity("Successful redirect");
197                 response.setEntity(entity);
198             } else {
199                 response.setStatusCode(HttpStatus.SC_MOVED_TEMPORARILY);
200                 response.addHeader(new BasicHeader("Location", "/rome"));
201             }
202         }
203     }
204 
205     private static class BogusRedirectService implements HttpRequestHandler {
206         private final String url;
207 
208         public BogusRedirectService(final String redirectUrl) {
209             super();
210             this.url = redirectUrl;
211         }
212 
213         @Override
214         public void handle(
215                 final HttpRequest request,
216                 final HttpResponse response,
217                 final HttpContext context) throws HttpException, IOException {
218             final String uri = request.getRequestLine().getUri();
219             if (uri.equals("/oldlocation/")) {
220                 response.setStatusCode(HttpStatus.SC_MOVED_TEMPORARILY);
221                 response.addHeader(new BasicHeader("Location", url));
222             } else if (uri.equals("/relativelocation/")) {
223                 response.setStatusCode(HttpStatus.SC_OK);
224                 final StringEntity entity = new StringEntity("Successful redirect");
225                 response.setEntity(entity);
226             } else {
227                 response.setStatusCode(HttpStatus.SC_NOT_FOUND);
228             }
229         }
230     }
231 
232     @Test
233     public void testBasicRedirect300() throws Exception {
234         this.serverBootstrap.registerHandler("*",
235                 new BasicRedirectService(HttpStatus.SC_MULTIPLE_CHOICES));
236 
237         final HttpHost target = start();
238 
239         final HttpClientContext context = HttpClientContext.create();
240 
241         final HttpGet httpget = new HttpGet("/oldlocation/");
242 
243         final HttpResponse response = this.httpclient.execute(target, httpget, context);
244         EntityUtils.consume(response.getEntity());
245 
246         final HttpRequest reqWrapper = context.getRequest();
247 
248         Assert.assertEquals(HttpStatus.SC_MULTIPLE_CHOICES, response.getStatusLine().getStatusCode());
249         Assert.assertEquals("/oldlocation/", reqWrapper.getRequestLine().getUri());
250 
251         final List<URI> redirects = context.getRedirectLocations();
252         Assert.assertNull(redirects);
253     }
254 
255     @Test
256     public void testBasicRedirect301() throws Exception {
257         this.serverBootstrap.registerHandler("*",
258                 new BasicRedirectService(HttpStatus.SC_MOVED_PERMANENTLY));
259 
260         final HttpHost target = start();
261 
262         final HttpClientContext context = HttpClientContext.create();
263 
264         final HttpGet httpget = new HttpGet("/oldlocation/");
265 
266         final HttpResponse response = this.httpclient.execute(target, httpget, context);
267         EntityUtils.consume(response.getEntity());
268 
269         final HttpRequest reqWrapper = context.getRequest();
270         final HttpHost host = context.getTargetHost();
271 
272         Assert.assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode());
273         Assert.assertEquals("/newlocation/", reqWrapper.getRequestLine().getUri());
274         Assert.assertEquals(target, host);
275 
276         final List<URI> redirects = context.getRedirectLocations();
277         Assert.assertNotNull(redirects);
278         Assert.assertEquals(1, redirects.size());
279 
280         final URI redirect = URIUtils.rewriteURI(new URI("/newlocation/"), target);
281         Assert.assertTrue(redirects.contains(redirect));
282     }
283 
284     @Test
285     public void testBasicRedirect302() throws Exception {
286         this.serverBootstrap.registerHandler("*",
287                 new BasicRedirectService(HttpStatus.SC_MOVED_TEMPORARILY));
288 
289         final HttpHost target = start();
290 
291         final HttpClientContext context = HttpClientContext.create();
292 
293         final HttpGet httpget = new HttpGet("/oldlocation/");
294 
295         final HttpResponse response = this.httpclient.execute(target, httpget, context);
296         EntityUtils.consume(response.getEntity());
297 
298         final HttpRequest reqWrapper = context.getRequest();
299         final HttpHost host = context.getTargetHost();
300 
301         Assert.assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode());
302         Assert.assertEquals("/newlocation/", reqWrapper.getRequestLine().getUri());
303         Assert.assertEquals(target, host);
304     }
305 
306     @Test
307     public void testBasicRedirect302NoLocation() throws Exception {
308         this.serverBootstrap.registerHandler("*", new HttpRequestHandler() {
309 
310             @Override
311             public void handle(
312                     final HttpRequest request,
313                     final HttpResponse response,
314                     final HttpContext context) throws HttpException, IOException {
315                 response.setStatusCode(HttpStatus.SC_MOVED_TEMPORARILY);
316             }
317 
318         });
319 
320         final HttpHost target = start();
321 
322         final HttpClientContext context = HttpClientContext.create();
323 
324         final HttpGet httpget = new HttpGet("/oldlocation/");
325 
326         final HttpResponse response = this.httpclient.execute(target, httpget, context);
327         EntityUtils.consume(response.getEntity());
328 
329         final HttpRequest reqWrapper = context.getRequest();
330         final HttpHost host = context.getTargetHost();
331 
332         Assert.assertEquals(HttpStatus.SC_MOVED_TEMPORARILY, response.getStatusLine().getStatusCode());
333         Assert.assertEquals("/oldlocation/", reqWrapper.getRequestLine().getUri());
334         Assert.assertEquals(target, host);
335     }
336 
337     @Test
338     public void testBasicRedirect303() throws Exception {
339         this.serverBootstrap.registerHandler("*",
340                 new BasicRedirectService(HttpStatus.SC_SEE_OTHER));
341 
342         final HttpHost target = start();
343 
344         final HttpClientContext context = HttpClientContext.create();
345 
346         final HttpGet httpget = new HttpGet("/oldlocation/");
347 
348         final HttpResponse response = this.httpclient.execute(target, httpget, context);
349         EntityUtils.consume(response.getEntity());
350 
351         final HttpRequest reqWrapper = context.getRequest();
352         final HttpHost host = context.getTargetHost();
353 
354         Assert.assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode());
355         Assert.assertEquals("/newlocation/", reqWrapper.getRequestLine().getUri());
356         Assert.assertEquals(target, host);
357     }
358 
359     @Test
360     public void testBasicRedirect304() throws Exception {
361         this.serverBootstrap.registerHandler("*",
362                 new BasicRedirectService(HttpStatus.SC_NOT_MODIFIED));
363 
364         final HttpHost target = start();
365 
366         final HttpClientContext context = HttpClientContext.create();
367 
368         final HttpGet httpget = new HttpGet("/oldlocation/");
369 
370         final HttpResponse response = this.httpclient.execute(target, httpget, context);
371         EntityUtils.consume(response.getEntity());
372 
373         final HttpRequest reqWrapper = context.getRequest();
374 
375         Assert.assertEquals(HttpStatus.SC_NOT_MODIFIED, response.getStatusLine().getStatusCode());
376         Assert.assertEquals("/oldlocation/", reqWrapper.getRequestLine().getUri());
377     }
378 
379     @Test
380     public void testBasicRedirect305() throws Exception {
381         this.serverBootstrap.registerHandler("*",
382                 new BasicRedirectService(HttpStatus.SC_USE_PROXY));
383         final HttpHost target = start();
384 
385         final HttpClientContext context = HttpClientContext.create();
386 
387         final HttpGet httpget = new HttpGet("/oldlocation/");
388 
389         final HttpResponse response = this.httpclient.execute(target, httpget, context);
390         EntityUtils.consume(response.getEntity());
391 
392         final HttpRequest reqWrapper = context.getRequest();
393 
394         Assert.assertEquals(HttpStatus.SC_USE_PROXY, response.getStatusLine().getStatusCode());
395         Assert.assertEquals("/oldlocation/", reqWrapper.getRequestLine().getUri());
396     }
397 
398     @Test
399     public void testBasicRedirect307() throws Exception {
400         this.serverBootstrap.registerHandler("*",
401                 new BasicRedirectService(HttpStatus.SC_TEMPORARY_REDIRECT));
402 
403         final HttpHost target = start();
404 
405         final HttpClientContext context = HttpClientContext.create();
406 
407         final HttpGet httpget = new HttpGet("/oldlocation/");
408 
409         final HttpResponse response = this.httpclient.execute(target, httpget, context);
410         EntityUtils.consume(response.getEntity());
411 
412         final HttpRequest reqWrapper = context.getRequest();
413         final HttpHost host = context.getTargetHost();
414 
415         Assert.assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode());
416         Assert.assertEquals("/newlocation/", reqWrapper.getRequestLine().getUri());
417         Assert.assertEquals(target, host);
418     }
419 
420     @Test(expected=ClientProtocolException.class)
421     public void testMaxRedirectCheck() throws Exception {
422         this.serverBootstrap.registerHandler("*", new CircularRedirectService());
423 
424         final HttpHost target = start();
425 
426         final RequestConfig config = RequestConfig.custom()
427             .setCircularRedirectsAllowed(true)
428             .setMaxRedirects(5)
429             .build();
430 
431         final HttpGet httpget = new HttpGet("/circular-oldlocation/");
432         httpget.setConfig(config);
433         try {
434             this.httpclient.execute(target, httpget);
435         } catch (final ClientProtocolException e) {
436             Assert.assertTrue(e.getCause() instanceof RedirectException);
437             throw e;
438         }
439     }
440 
441     @Test(expected=ClientProtocolException.class)
442     public void testCircularRedirect() throws Exception {
443         this.serverBootstrap.registerHandler("*", new CircularRedirectService());
444 
445         final HttpHost target = start();
446 
447         final RequestConfig config = RequestConfig.custom()
448             .setCircularRedirectsAllowed(false)
449             .build();
450 
451         final HttpGet httpget = new HttpGet("/circular-oldlocation/");
452         httpget.setConfig(config);
453         try {
454             this.httpclient.execute(target, httpget);
455         } catch (final ClientProtocolException e) {
456             Assert.assertTrue(e.getCause() instanceof CircularRedirectException);
457             throw e;
458         }
459     }
460 
461     @Test
462     public void testRepeatRequest() throws Exception {
463         this.serverBootstrap.registerHandler("*", new RomeRedirectService());
464 
465         final HttpHost target = start();
466 
467         final HttpClientContext context = HttpClientContext.create();
468 
469         final RequestConfig config = RequestConfig.custom().setRelativeRedirectsAllowed(true).build();
470         final HttpGet first = new HttpGet("/rome");
471         first.setConfig(config);
472 
473         EntityUtils.consume(this.httpclient.execute(target, first, context).getEntity());
474 
475         final HttpGet second = new HttpGet("/rome");
476         second.setConfig(config);
477 
478         final HttpResponse response = this.httpclient.execute(target, second, context);
479         EntityUtils.consume(response.getEntity());
480 
481         final HttpRequest reqWrapper = context.getRequest();
482         final HttpHost host = context.getTargetHost();
483 
484         Assert.assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode());
485         Assert.assertEquals("/rome", reqWrapper.getRequestLine().getUri());
486         Assert.assertEquals(host, target);
487     }
488 
489     @Test
490     public void testRepeatRequestRedirect() throws Exception {
491         this.serverBootstrap.registerHandler("*", new RomeRedirectService());
492 
493         final HttpHost target = start();
494 
495         final HttpClientContext context = HttpClientContext.create();
496 
497         final RequestConfig config = RequestConfig.custom().setRelativeRedirectsAllowed(true).build();
498         final HttpGet first = new HttpGet("/lille");
499         first.setConfig(config);
500 
501         final HttpResponse response1 = this.httpclient.execute(target, first, context);
502         EntityUtils.consume(response1.getEntity());
503 
504         final HttpGet second = new HttpGet("/lille");
505         second.setConfig(config);
506 
507         final HttpResponse response2 = this.httpclient.execute(target, second, context);
508         EntityUtils.consume(response2.getEntity());
509 
510         final HttpRequest reqWrapper = context.getRequest();
511         final HttpHost host = context.getTargetHost();
512 
513         Assert.assertEquals(HttpStatus.SC_OK, response2.getStatusLine().getStatusCode());
514         Assert.assertEquals("/rome", reqWrapper.getRequestLine().getUri());
515         Assert.assertEquals(host, target);
516     }
517 
518     @Test
519     public void testDifferentRequestSameRedirect() throws Exception {
520         this.serverBootstrap.registerHandler("*", new RomeRedirectService());
521 
522         final HttpHost target = start();
523 
524         final HttpClientContext context = HttpClientContext.create();
525 
526         final RequestConfig config = RequestConfig.custom().setRelativeRedirectsAllowed(true).build();
527         final HttpGet first = new HttpGet("/alian");
528         first.setConfig(config);
529 
530         final HttpResponse response1 = this.httpclient.execute(target, first, context);
531         EntityUtils.consume(response1.getEntity());
532 
533         final HttpGet second = new HttpGet("/lille");
534         second.setConfig(config);
535 
536         final HttpResponse response2 = this.httpclient.execute(target, second, context);
537         EntityUtils.consume(response2.getEntity());
538 
539         final HttpRequest reqWrapper = context.getRequest();
540         final HttpHost host = context.getTargetHost();
541 
542         Assert.assertEquals(HttpStatus.SC_OK, response2.getStatusLine().getStatusCode());
543         Assert.assertEquals("/rome", reqWrapper.getRequestLine().getUri());
544         Assert.assertEquals(host, target);
545     }
546 
547     @Test
548     public void testPostNoRedirect() throws Exception {
549         this.serverBootstrap.registerHandler("*", new BasicRedirectService());
550 
551         final HttpHost target = start();
552 
553         final HttpClientContext context = HttpClientContext.create();
554 
555         final HttpPost httppost = new HttpPost("/oldlocation/");
556         httppost.setEntity(new StringEntity("stuff"));
557 
558         final HttpResponse response = this.httpclient.execute(target, httppost, context);
559         EntityUtils.consume(response.getEntity());
560 
561         final HttpRequest reqWrapper = context.getRequest();
562 
563         Assert.assertEquals(HttpStatus.SC_MOVED_TEMPORARILY, response.getStatusLine().getStatusCode());
564         Assert.assertEquals("/oldlocation/", reqWrapper.getRequestLine().getUri());
565         Assert.assertEquals("POST", reqWrapper.getRequestLine().getMethod());
566     }
567 
568     @Test
569     public void testPostRedirectSeeOther() throws Exception {
570         this.serverBootstrap.registerHandler("*", new BasicRedirectService(HttpStatus.SC_SEE_OTHER));
571 
572         final HttpHost target = start();
573 
574         final HttpClientContext context = HttpClientContext.create();
575 
576         final HttpPost httppost = new HttpPost("/oldlocation/");
577         httppost.setEntity(new StringEntity("stuff"));
578 
579         final HttpResponse response = this.httpclient.execute(target, httppost, context);
580         EntityUtils.consume(response.getEntity());
581 
582         final HttpRequest reqWrapper = context.getRequest();
583 
584         Assert.assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode());
585         Assert.assertEquals("/newlocation/", reqWrapper.getRequestLine().getUri());
586         Assert.assertEquals("GET", reqWrapper.getRequestLine().getMethod());
587     }
588 
589     @Test
590     public void testRelativeRedirect() throws Exception {
591         this.serverBootstrap.registerHandler("*", new RelativeRedirectService());
592 
593         final HttpHost target = start();
594 
595         final HttpClientContext context = HttpClientContext.create();
596 
597         final RequestConfig config = RequestConfig.custom().setRelativeRedirectsAllowed(true).build();
598         final HttpGet httpget = new HttpGet("/oldlocation/");
599         httpget.setConfig(config);
600 
601         final HttpResponse response = this.httpclient.execute(target, httpget, context);
602         EntityUtils.consume(response.getEntity());
603 
604         final HttpRequest reqWrapper = context.getRequest();
605         final HttpHost host = context.getTargetHost();
606 
607         Assert.assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode());
608         Assert.assertEquals("/relativelocation/", reqWrapper.getRequestLine().getUri());
609         Assert.assertEquals(host, target);
610     }
611 
612     @Test
613     public void testRelativeRedirect2() throws Exception {
614         this.serverBootstrap.registerHandler("*", new RelativeRedirectService2());
615 
616         final HttpHost target = start();
617 
618         final HttpClientContext context = HttpClientContext.create();
619 
620         final RequestConfig config = RequestConfig.custom().setRelativeRedirectsAllowed(true).build();
621         final HttpGet httpget = new HttpGet("/test/oldlocation");
622         httpget.setConfig(config);
623 
624         final HttpResponse response = this.httpclient.execute(target, httpget, context);
625         EntityUtils.consume(response.getEntity());
626 
627         final HttpRequest reqWrapper = context.getRequest();
628         final HttpHost host = context.getTargetHost();
629 
630         Assert.assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode());
631         Assert.assertEquals("/test/relativelocation", reqWrapper.getRequestLine().getUri());
632         Assert.assertEquals(host, target);
633     }
634 
635     @Test(expected=ClientProtocolException.class)
636     public void testRejectRelativeRedirect() throws Exception {
637         this.serverBootstrap.registerHandler("*", new RelativeRedirectService());
638 
639         final HttpHost target = start();
640 
641         final RequestConfig config = RequestConfig.custom().setRelativeRedirectsAllowed(false).build();
642         final HttpGet httpget = new HttpGet("/oldlocation/");
643         httpget.setConfig(config);
644         try {
645             this.httpclient.execute(target, httpget);
646         } catch (final ClientProtocolException e) {
647             Assert.assertTrue(e.getCause() instanceof ProtocolException);
648             throw e;
649         }
650     }
651 
652     @Test(expected=ClientProtocolException.class)
653     public void testRejectBogusRedirectLocation() throws Exception {
654         this.serverBootstrap.registerHandler("*", new BogusRedirectService("xxx://bogus"));
655 
656         final HttpHost target = start();
657 
658         final HttpGet httpget = new HttpGet("/oldlocation/");
659 
660         try {
661             this.httpclient.execute(target, httpget);
662         } catch (final ClientProtocolException ex) {
663             final Throwable cause = ex.getCause();
664             Assert.assertTrue(cause instanceof HttpException);
665             throw ex;
666         }
667     }
668 
669     @Test(expected=ClientProtocolException.class)
670     public void testRejectInvalidRedirectLocation() throws Exception {
671         final UriHttpRequestHandlerMapper reqistry = new UriHttpRequestHandlerMapper();
672         this.serverBootstrap.setHandlerMapper(reqistry);
673 
674         final HttpHost target = start();
675 
676         reqistry.register("*",
677                 new BogusRedirectService("http://" + target.toHostString() +
678                         "/newlocation/?p=I have spaces"));
679 
680         final HttpGet httpget = new HttpGet("/oldlocation/");
681 
682         try {
683             this.httpclient.execute(target, httpget);
684         } catch (final ClientProtocolException e) {
685             Assert.assertTrue(e.getCause() instanceof ProtocolException);
686             throw e;
687         }
688     }
689 
690     @Test
691     public void testRedirectWithCookie() throws Exception {
692         this.serverBootstrap.registerHandler("*", new BasicRedirectService());
693 
694         final HttpHost target = start();
695 
696         final CookieStore cookieStore = new BasicCookieStore();
697 
698         final BasicClientCookie cookie = new BasicClientCookie("name", "value");
699         cookie.setDomain(target.getHostName());
700         cookie.setPath("/");
701 
702         cookieStore.addCookie(cookie);
703 
704         final HttpClientContext context = HttpClientContext.create();
705         context.setCookieStore(cookieStore);
706         final HttpGet httpget = new HttpGet("/oldlocation/");
707 
708         final HttpResponse response = this.httpclient.execute(target, httpget, context);
709         EntityUtils.consume(response.getEntity());
710 
711         final HttpRequest reqWrapper = context.getRequest();
712 
713         Assert.assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode());
714         Assert.assertEquals("/newlocation/", reqWrapper.getRequestLine().getUri());
715 
716         final Header[] headers = reqWrapper.getHeaders(SM.COOKIE);
717         Assert.assertEquals("There can only be one (cookie)", 1, headers.length);
718     }
719 
720     @Test
721     public void testDefaultHeadersRedirect() throws Exception {
722         this.clientBuilder.setDefaultHeaders(Arrays.asList(new BasicHeader(HTTP.USER_AGENT, "my-test-client")));
723 
724         this.serverBootstrap.registerHandler("*", new BasicRedirectService());
725 
726         final HttpHost target = start();
727 
728         final HttpClientContext context = HttpClientContext.create();
729 
730         final HttpGet httpget = new HttpGet("/oldlocation/");
731 
732 
733         final HttpResponse response = this.httpclient.execute(target, httpget, context);
734         EntityUtils.consume(response.getEntity());
735 
736         final HttpRequest reqWrapper = context.getRequest();
737 
738         Assert.assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode());
739         Assert.assertEquals("/newlocation/", reqWrapper.getRequestLine().getUri());
740 
741         final Header header = reqWrapper.getFirstHeader(HTTP.USER_AGENT);
742         Assert.assertEquals("my-test-client", header.getValue());
743     }
744 
745 }