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.hc.client5.testing.async;
28
29 import static org.hamcrest.MatcherAssert.assertThat;
30
31 import java.net.InetSocketAddress;
32 import java.net.URI;
33 import java.util.concurrent.ExecutionException;
34 import java.util.concurrent.Future;
35
36 import org.apache.hc.client5.http.CircularRedirectException;
37 import org.apache.hc.client5.http.RedirectException;
38 import org.apache.hc.client5.http.async.methods.SimpleHttpRequest;
39 import org.apache.hc.client5.http.async.methods.SimpleHttpResponse;
40 import org.apache.hc.client5.http.async.methods.SimpleRequestBuilder;
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.testing.OldPathRedirectResolver;
47 import org.apache.hc.client5.testing.extension.async.ClientProtocolLevel;
48 import org.apache.hc.client5.testing.extension.async.ServerProtocolLevel;
49 import org.apache.hc.client5.testing.extension.async.TestAsyncClient;
50 import org.apache.hc.client5.testing.extension.async.TestAsyncServer;
51 import org.apache.hc.client5.testing.extension.async.TestAsyncServerBootstrap;
52 import org.apache.hc.client5.testing.redirect.Redirect;
53 import org.apache.hc.core5.http.ContentType;
54 import org.apache.hc.core5.http.Header;
55 import org.apache.hc.core5.http.HttpException;
56 import org.apache.hc.core5.http.HttpHost;
57 import org.apache.hc.core5.http.HttpRequest;
58 import org.apache.hc.core5.http.HttpResponse;
59 import org.apache.hc.core5.http.HttpStatus;
60 import org.apache.hc.core5.http.ProtocolException;
61 import org.apache.hc.core5.http.URIScheme;
62 import org.apache.hc.core5.http.protocol.HttpCoreContext;
63 import org.apache.hc.core5.net.URIBuilder;
64 import org.apache.hc.core5.util.TimeValue;
65 import org.hamcrest.CoreMatchers;
66 import org.junit.jupiter.api.Assertions;
67 import org.junit.jupiter.api.Test;
68
69 public abstract class AbstractHttpAsyncRedirectsTest extends AbstractIntegrationTestBase {
70
71 public AbstractHttpAsyncRedirectsTest(final URIScheme scheme, final ClientProtocolLevel clientProtocolLevel, final ServerProtocolLevel serverProtocolLevel) {
72 super(scheme, clientProtocolLevel, serverProtocolLevel);
73 }
74
75 @Test
76 public void testBasicRedirect300() throws Exception {
77 configureServer(bootstrap -> bootstrap
78 .register("/random/*", AsyncRandomHandler::new)
79 .setExchangeHandlerDecorator(exchangeHandler -> new RedirectingAsyncDecorator(
80 exchangeHandler,
81 new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MULTIPLE_CHOICES))));
82 final HttpHost target = startServer();
83
84 final TestAsyncClient client = startClient();
85
86 final HttpClientContext context = HttpClientContext.create();
87 final Future<SimpleHttpResponse> future = client.execute(
88 SimpleRequestBuilder.get()
89 .setHttpHost(target)
90 .setPath("/oldlocation/")
91 .build(), context, null);
92 final HttpResponse response = future.get();
93 Assertions.assertNotNull(response);
94
95 final HttpRequest request = context.getRequest();
96
97 Assertions.assertEquals(HttpStatus.SC_MULTIPLE_CHOICES, response.getCode());
98 Assertions.assertEquals("/oldlocation/", request.getRequestUri());
99 }
100
101 @Test
102 public void testBasicRedirect301() throws Exception {
103 configureServer(bootstrap -> bootstrap
104 .register("/random/*", AsyncRandomHandler::new)
105 .setExchangeHandlerDecorator(exchangeHandler -> new RedirectingAsyncDecorator(
106 exchangeHandler,
107 new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_PERMANENTLY))));
108 final HttpHost target = startServer();
109
110 final TestAsyncClient client = startClient();
111
112 final HttpClientContext context = HttpClientContext.create();
113 final Future<SimpleHttpResponse> future = client.execute(
114 SimpleRequestBuilder.get()
115 .setHttpHost(target)
116 .setPath("/oldlocation/100")
117 .build(), context, null);
118 final HttpResponse response = future.get();
119 Assertions.assertNotNull(response);
120
121 final HttpRequest request = context.getRequest();
122
123 Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
124 Assertions.assertEquals("/random/100", request.getRequestUri());
125 Assertions.assertEquals(target, new HttpHost(request.getScheme(), request.getAuthority()));
126 }
127
128 @Test
129 public void testBasicRedirect302() throws Exception {
130 configureServer(bootstrap -> bootstrap
131 .register("/random/*", AsyncRandomHandler::new)
132 .setExchangeHandlerDecorator(exchangeHandler -> new RedirectingAsyncDecorator(
133 exchangeHandler,
134 new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_TEMPORARILY))));
135 final HttpHost target = startServer();
136
137 final TestAsyncClient client = startClient();
138
139 final HttpClientContext context = HttpClientContext.create();
140 final Future<SimpleHttpResponse> future = client.execute(
141 SimpleRequestBuilder.get()
142 .setHttpHost(target)
143 .setPath("/oldlocation/123")
144 .build(), context, null);
145 final HttpResponse response = future.get();
146 Assertions.assertNotNull(response);
147
148 final HttpRequest request = context.getRequest();
149
150 Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
151 Assertions.assertEquals("/random/123", request.getRequestUri());
152 Assertions.assertEquals(target, new HttpHost(request.getScheme(), request.getAuthority()));
153 }
154
155 @Test
156 public void testBasicRedirect302NoLocation() throws Exception {
157 configureServer(bootstrap -> bootstrap
158 .register("/random/*", AsyncRandomHandler::new)
159 .setExchangeHandlerDecorator(exchangeHandler -> new RedirectingAsyncDecorator(
160 exchangeHandler,
161 requestUri -> {
162 final String path = requestUri.getPath();
163 if (path.startsWith("/oldlocation")) {
164 return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, null);
165 }
166 return null;
167 })));
168 final HttpHost target = startServer();
169
170 final TestAsyncClient client = startClient();
171
172 final HttpClientContext context = HttpClientContext.create();
173 final Future<SimpleHttpResponse> future = client.execute(
174 SimpleRequestBuilder.get()
175 .setHttpHost(target)
176 .setPath("/oldlocation/100")
177 .build(), context, null);
178 final HttpResponse response = future.get();
179 Assertions.assertNotNull(response);
180
181 final HttpRequest request = context.getRequest();
182 Assertions.assertEquals(HttpStatus.SC_MOVED_TEMPORARILY, response.getCode());
183 Assertions.assertEquals("/oldlocation/100", request.getRequestUri());
184 Assertions.assertEquals(target, new HttpHost(request.getScheme(), request.getAuthority()));
185 }
186
187 @Test
188 public void testBasicRedirect303() throws Exception {
189 configureServer(bootstrap -> bootstrap
190 .register("/random/*", AsyncRandomHandler::new)
191 .setExchangeHandlerDecorator(exchangeHandler -> new RedirectingAsyncDecorator(
192 exchangeHandler,
193 new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_SEE_OTHER))));
194
195 final HttpHost target = startServer();
196
197 final TestAsyncClient client = startClient();
198
199 final HttpClientContext context = HttpClientContext.create();
200 final Future<SimpleHttpResponse> future = client.execute(
201 SimpleRequestBuilder.get()
202 .setHttpHost(target)
203 .setPath("/oldlocation/123")
204 .build(), context, null);
205 final HttpResponse response = future.get();
206 Assertions.assertNotNull(response);
207
208 final HttpRequest request = context.getRequest();
209
210 Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
211 Assertions.assertEquals("/random/123", request.getRequestUri());
212 Assertions.assertEquals(target, new HttpHost(request.getScheme(), request.getAuthority()));
213 }
214
215 @Test
216 public void testBasicRedirect304() throws Exception {
217 configureServer(bootstrap -> bootstrap
218 .register("/random/*", AsyncRandomHandler::new)
219 .register("/oldlocation/*", () -> new AbstractSimpleServerExchangeHandler() {
220
221 @Override
222 protected SimpleHttpResponse handle(final SimpleHttpRequest request,
223 final HttpCoreContext context) throws HttpException {
224 return SimpleHttpResponse.create(HttpStatus.SC_NOT_MODIFIED, (String) null);
225 }
226 }));
227 final HttpHost target = startServer();
228
229 final TestAsyncClient client = startClient();
230
231 final HttpClientContext context = HttpClientContext.create();
232 final Future<SimpleHttpResponse> future = client.execute(
233 SimpleRequestBuilder.get()
234 .setHttpHost(target)
235 .setPath("/oldlocation/")
236 .build(), context, null);
237 final HttpResponse response = future.get();
238 Assertions.assertNotNull(response);
239
240 final HttpRequest request = context.getRequest();
241
242 Assertions.assertEquals(HttpStatus.SC_NOT_MODIFIED, response.getCode());
243 Assertions.assertEquals("/oldlocation/", request.getRequestUri());
244 }
245
246 @Test
247 public void testBasicRedirect305() throws Exception {
248 configureServer(bootstrap -> bootstrap
249 .register("/random/*", AsyncRandomHandler::new)
250 .register("/oldlocation/*", () -> new AbstractSimpleServerExchangeHandler() {
251
252 @Override
253 protected SimpleHttpResponse handle(final SimpleHttpRequest request,
254 final HttpCoreContext context) throws HttpException {
255 return SimpleHttpResponse.create(HttpStatus.SC_USE_PROXY, (String) null);
256 }
257 }));
258 final HttpHost target = startServer();
259
260 final TestAsyncClient client = startClient();
261
262 final HttpClientContext context = HttpClientContext.create();
263 final Future<SimpleHttpResponse> future = client.execute(
264 SimpleRequestBuilder.get()
265 .setHttpHost(target)
266 .setPath("/oldlocation/")
267 .build(), context, null);
268 final HttpResponse response = future.get();
269 Assertions.assertNotNull(response);
270
271 final HttpRequest request = context.getRequest();
272
273 Assertions.assertEquals(HttpStatus.SC_USE_PROXY, response.getCode());
274 Assertions.assertEquals("/oldlocation/", request.getRequestUri());
275 }
276
277 @Test
278 public void testBasicRedirect307() throws Exception {
279 configureServer(bootstrap -> bootstrap
280 .register("/random/*", AsyncRandomHandler::new)
281 .setExchangeHandlerDecorator(exchangeHandler -> new RedirectingAsyncDecorator(
282 exchangeHandler,
283 new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_TEMPORARY_REDIRECT))));
284 final HttpHost target = startServer();
285
286 final TestAsyncClient client = startClient();
287
288 final HttpClientContext context = HttpClientContext.create();
289 final Future<SimpleHttpResponse> future = client.execute(
290 SimpleRequestBuilder.get()
291 .setHttpHost(target)
292 .setPath("/oldlocation/123")
293 .build(), context, null);
294 final HttpResponse response = future.get();
295 Assertions.assertNotNull(response);
296
297 final HttpRequest request = context.getRequest();
298
299 Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
300 Assertions.assertEquals("/random/123", request.getRequestUri());
301 Assertions.assertEquals(target, new HttpHost(request.getScheme(), request.getAuthority()));
302 }
303
304 @Test
305 public void testMaxRedirectCheck() throws Exception {
306 configureServer(bootstrap -> bootstrap
307 .register("/random/*", AsyncRandomHandler::new)
308 .setExchangeHandlerDecorator(exchangeHandler -> new RedirectingAsyncDecorator(
309 exchangeHandler,
310 new OldPathRedirectResolver("/circular-oldlocation/", "/circular-oldlocation/",
311 HttpStatus.SC_MOVED_TEMPORARILY))));
312 final HttpHost target = startServer();
313
314 final TestAsyncClient client = startClient();
315
316 final RequestConfig config = RequestConfig.custom()
317 .setCircularRedirectsAllowed(true)
318 .setMaxRedirects(5).build();
319 final ExecutionException exception = Assertions.assertThrows(ExecutionException.class, () -> {
320 final Future<SimpleHttpResponse> future = client.execute(SimpleRequestBuilder.get()
321 .setHttpHost(target)
322 .setPath("/circular-oldlocation/")
323 .setRequestConfig(config)
324 .build(), null);
325 future.get();
326 });
327 assertThat(exception.getCause(), CoreMatchers.instanceOf(RedirectException.class));
328 }
329
330 @Test
331 public void testCircularRedirect() throws Exception {
332 configureServer(bootstrap -> bootstrap
333 .register("/random/*", AsyncRandomHandler::new)
334 .setExchangeHandlerDecorator(exchangeHandler -> new RedirectingAsyncDecorator(
335 exchangeHandler,
336 new OldPathRedirectResolver("/circular-oldlocation/", "/circular-oldlocation/",
337 HttpStatus.SC_MOVED_TEMPORARILY))));
338 final HttpHost target = startServer();
339
340 final TestAsyncClient client = startClient();
341
342 final RequestConfig config = RequestConfig.custom()
343 .setCircularRedirectsAllowed(false)
344 .build();
345 final ExecutionException exception = Assertions.assertThrows(ExecutionException.class, () -> {
346 final Future<SimpleHttpResponse> future = client.execute(
347 SimpleRequestBuilder.get()
348 .setHttpHost(target)
349 .setPath("/circular-oldlocation/")
350 .setRequestConfig(config)
351 .build(), null);
352 future.get();
353 });
354 assertThat(exception.getCause(), CoreMatchers.instanceOf(CircularRedirectException.class));
355 }
356
357 @Test
358 public void testPostRedirect() throws Exception {
359 configureServer(bootstrap -> bootstrap
360 .register("/echo/*", AsyncEchoHandler::new)
361 .setExchangeHandlerDecorator(exchangeHandler -> new RedirectingAsyncDecorator(
362 exchangeHandler,
363 new OldPathRedirectResolver("/oldlocation", "/echo", HttpStatus.SC_TEMPORARY_REDIRECT))));
364 final HttpHost target = startServer();
365
366 final TestAsyncClient client = startClient();
367
368 final HttpClientContext context = HttpClientContext.create();
369 final Future<SimpleHttpResponse> future = client.execute(
370 SimpleRequestBuilder.post()
371 .setHttpHost(target)
372 .setPath("/oldlocation/stuff")
373 .setBody("stuff", ContentType.TEXT_PLAIN)
374 .build(), context, null);
375 final HttpResponse response = future.get();
376 Assertions.assertNotNull(response);
377
378 final HttpRequest request = context.getRequest();
379
380 Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
381 Assertions.assertEquals("/echo/stuff", request.getRequestUri());
382 Assertions.assertEquals("POST", request.getMethod());
383 }
384
385 @Test
386 public void testPostRedirectSeeOther() throws Exception {
387 configureServer(bootstrap -> bootstrap
388 .register("/echo/*", AsyncEchoHandler::new)
389 .setExchangeHandlerDecorator(exchangeHandler -> new RedirectingAsyncDecorator(
390 exchangeHandler,
391 new OldPathRedirectResolver("/oldlocation", "/echo", HttpStatus.SC_SEE_OTHER))));
392 final HttpHost target = startServer();
393
394 final TestAsyncClient client = startClient();
395
396 final HttpClientContext context = HttpClientContext.create();
397 final Future<SimpleHttpResponse> future = client.execute(
398 SimpleRequestBuilder.post()
399 .setHttpHost(target)
400 .setPath("/oldlocation/stuff")
401 .setBody("stuff", ContentType.TEXT_PLAIN)
402 .build(), context, null);
403 final HttpResponse response = future.get();
404 Assertions.assertNotNull(response);
405
406 final HttpRequest request = context.getRequest();
407
408 Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
409 Assertions.assertEquals("/echo/stuff", request.getRequestUri());
410 Assertions.assertEquals("GET", request.getMethod());
411 }
412
413 @Test
414 public void testRelativeRedirect() throws Exception {
415 configureServer(bootstrap -> bootstrap
416 .register("/random/*", AsyncRandomHandler::new)
417 .setExchangeHandlerDecorator(exchangeHandler -> new RedirectingAsyncDecorator(
418 exchangeHandler,
419 requestUri -> {
420 final String path = requestUri.getPath();
421 if (path.startsWith("/oldlocation")) {
422 return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, "/random/100");
423
424 }
425 return null;
426 })));
427 final HttpHost target = startServer();
428
429 final TestAsyncClient client = startClient();
430
431 final HttpClientContext context = HttpClientContext.create();
432
433 final Future<SimpleHttpResponse> future = client.execute(
434 SimpleRequestBuilder.get()
435 .setHttpHost(target)
436 .setPath("/oldlocation/stuff")
437 .build(), context, null);
438 final HttpResponse response = future.get();
439 Assertions.assertNotNull(response);
440
441 final HttpRequest request = context.getRequest();
442
443 Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
444 Assertions.assertEquals("/random/100", request.getRequestUri());
445 Assertions.assertEquals(target, new HttpHost(request.getScheme(), request.getAuthority()));
446 }
447
448 @Test
449 public void testRelativeRedirect2() throws Exception {
450 configureServer(bootstrap -> bootstrap
451 .register("/random/*", AsyncRandomHandler::new)
452 .setExchangeHandlerDecorator(exchangeHandler -> new RedirectingAsyncDecorator(
453 exchangeHandler,
454 requestUri -> {
455 final String path = requestUri.getPath();
456 if (path.equals("/random/oldlocation")) {
457 return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, "100");
458
459 }
460 return null;
461 })));
462 final HttpHost target = startServer();
463
464 final TestAsyncClient client = startClient();
465
466 final HttpClientContext context = HttpClientContext.create();
467
468 final Future<SimpleHttpResponse> future = client.execute(
469 SimpleRequestBuilder.get()
470 .setHttpHost(target)
471 .setPath("/random/oldlocation")
472 .build(), context, null);
473 final HttpResponse response = future.get();
474 Assertions.assertNotNull(response);
475
476 final HttpRequest request = context.getRequest();
477
478 Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
479 Assertions.assertEquals("/random/100", request.getRequestUri());
480 Assertions.assertEquals(target, new HttpHost(request.getScheme(), request.getAuthority()));
481 }
482
483 @Test
484 public void testRejectBogusRedirectLocation() throws Exception {
485 configureServer(bootstrap -> bootstrap
486 .register("/random/*", AsyncRandomHandler::new)
487 .setExchangeHandlerDecorator(exchangeHandler -> new RedirectingAsyncDecorator(
488 exchangeHandler,
489 requestUri -> {
490 final String path = requestUri.getPath();
491 if (path.equals("/oldlocation/")) {
492 return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, "xxx://bogus");
493
494 }
495 return null;
496 })));
497 final HttpHost target = startServer();
498
499 final TestAsyncClient client = startClient();
500
501 final ExecutionException exception = Assertions.assertThrows(ExecutionException.class, () -> {
502 final Future<SimpleHttpResponse> future = client.execute(
503 SimpleRequestBuilder.get()
504 .setHttpHost(target)
505 .setPath("/oldlocation/")
506 .build(), null);
507 future.get();
508 });
509 assertThat(exception.getCause(), CoreMatchers.instanceOf(HttpException.class));
510 }
511
512 @Test
513 public void testRejectInvalidRedirectLocation() throws Exception {
514 configureServer(bootstrap -> bootstrap
515 .register("/random/*", AsyncRandomHandler::new)
516 .setExchangeHandlerDecorator(exchangeHandler -> new RedirectingAsyncDecorator(
517 exchangeHandler,
518 requestUri -> {
519 final String path = requestUri.getPath();
520 if (path.equals("/oldlocation/")) {
521 return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, "/newlocation/?p=I have spaces");
522 }
523 return null;
524 })));
525 final HttpHost target = startServer();
526
527 final TestAsyncClient client = startClient();
528
529 final ExecutionException exception = Assertions.assertThrows(ExecutionException.class, () -> {
530 final Future<SimpleHttpResponse> future = client.execute(
531 SimpleRequestBuilder.get()
532 .setHttpHost(target)
533 .setPath("/oldlocation/")
534 .build(), null);
535 future.get();
536 });
537 assertThat(exception.getCause(), CoreMatchers.instanceOf(ProtocolException.class));
538 }
539
540 @Test
541 public void testRedirectWithCookie() throws Exception {
542 configureServer(bootstrap -> bootstrap
543 .register("/random/*", AsyncRandomHandler::new)
544 .setExchangeHandlerDecorator(exchangeHandler -> new RedirectingAsyncDecorator(
545 exchangeHandler,
546 new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_TEMPORARILY))));
547 final HttpHost target = startServer();
548
549 final TestAsyncClient client = startClient();
550
551 final CookieStore cookieStore = new BasicCookieStore();
552 final HttpClientContext context = HttpClientContext.create();
553 context.setCookieStore(cookieStore);
554
555 final BasicClientCookie cookie = new BasicClientCookie("name", "value");
556 cookie.setDomain(target.getHostName());
557 cookie.setPath("/");
558
559 cookieStore.addCookie(cookie);
560
561 final Future<SimpleHttpResponse> future = client.execute(
562 SimpleRequestBuilder.get()
563 .setHttpHost(target)
564 .setPath("/oldlocation/100")
565 .build(), context, null);
566 final HttpResponse response = future.get();
567 Assertions.assertNotNull(response);
568
569 final HttpRequest request = context.getRequest();
570
571 Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
572 Assertions.assertEquals("/random/100", request.getRequestUri());
573
574 final Header[] headers = request.getHeaders("Cookie");
575 Assertions.assertEquals(1, headers.length, "There can only be one (cookie)");
576 }
577
578 @Test
579 public void testCrossSiteRedirect() throws Exception {
580 final URIScheme scheme = scheme();
581 final TestAsyncServer secondServer = new TestAsyncServerBootstrap(scheme(), getServerProtocolLevel())
582 .register("/random/*", AsyncRandomHandler::new)
583 .build();
584 try {
585 final InetSocketAddress address2 = secondServer.start();
586
587 final HttpHost redirectTarget = new HttpHost(scheme.name(), "localhost", address2.getPort());
588
589 configureServer(bootstrap -> bootstrap
590 .register("/random/*", AsyncRandomHandler::new)
591 .setExchangeHandlerDecorator(exchangeHandler -> new RedirectingAsyncDecorator(
592 exchangeHandler,
593 requestUri -> {
594 final String path = requestUri.getPath();
595 if (path.equals("/oldlocation")) {
596 final URI location = new URIBuilder(requestUri)
597 .setHttpHost(redirectTarget)
598 .setPath("/random/100")
599 .build();
600 return new Redirect(HttpStatus.SC_MOVED_PERMANENTLY, location.toString());
601 }
602 return null;
603 })));
604 final HttpHost target = startServer();
605
606 final TestAsyncClient client = startClient();
607
608 final HttpClientContext context = HttpClientContext.create();
609 final Future<SimpleHttpResponse> future = client.execute(
610 SimpleRequestBuilder.get()
611 .setHttpHost(target)
612 .setPath("/oldlocation")
613 .build(), context, null);
614 final HttpResponse response = future.get();
615 Assertions.assertNotNull(response);
616
617 final HttpRequest request = context.getRequest();
618
619 Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
620 Assertions.assertEquals("/random/100", request.getRequestUri());
621 Assertions.assertEquals(redirectTarget, new HttpHost(request.getScheme(), request.getAuthority()));
622 } finally {
623 secondServer.shutdown(TimeValue.ofSeconds(5));
624 }
625 }
626
627 }