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