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