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