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 java.util.ArrayList;
30 import java.util.Arrays;
31 import java.util.Collection;
32 import java.util.List;
33 import java.util.concurrent.Future;
34
35 import org.apache.hc.client5.http.async.methods.SimpleHttpResponse;
36 import org.apache.hc.client5.http.async.methods.SimpleRequestBuilder;
37 import org.apache.hc.client5.http.config.RequestConfig;
38 import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
39 import org.apache.hc.client5.http.impl.async.HttpAsyncClientBuilder;
40 import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManager;
41 import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManagerBuilder;
42 import org.apache.hc.client5.http.protocol.HttpClientContext;
43 import org.apache.hc.client5.http.ssl.DefaultClientTlsStrategy;
44 import org.apache.hc.client5.testing.OldPathRedirectResolver;
45 import org.apache.hc.client5.testing.SSLTestContexts;
46 import org.apache.hc.client5.testing.redirect.Redirect;
47 import org.apache.hc.core5.function.Decorator;
48 import org.apache.hc.core5.http.Header;
49 import org.apache.hc.core5.http.HttpHeaders;
50 import org.apache.hc.core5.http.HttpHost;
51 import org.apache.hc.core5.http.HttpRequest;
52 import org.apache.hc.core5.http.HttpResponse;
53 import org.apache.hc.core5.http.HttpStatus;
54 import org.apache.hc.core5.http.HttpVersion;
55 import org.apache.hc.core5.http.URIScheme;
56 import org.apache.hc.core5.http.message.BasicHeader;
57 import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
58 import org.junit.Assert;
59 import org.junit.Rule;
60 import org.junit.Test;
61 import org.junit.rules.ExternalResource;
62 import org.junit.runner.RunWith;
63 import org.junit.runners.Parameterized;
64
65
66
67
68 @RunWith(Parameterized.class)
69 public class TestHttp1AsyncRedirects extends AbstractHttpAsyncRedirectsTest<CloseableHttpAsyncClient> {
70
71 @Parameterized.Parameters(name = "HTTP/1.1 {0}")
72 public static Collection<Object[]> protocols() {
73 return Arrays.asList(new Object[][]{
74 {URIScheme.HTTP},
75 {URIScheme.HTTPS},
76 });
77 }
78
79 protected HttpAsyncClientBuilder clientBuilder;
80 protected PoolingAsyncClientConnectionManager connManager;
81
82 public TestHttp1AsyncRedirects(final URIScheme scheme) {
83 super(HttpVersion.HTTP_1_1, scheme);
84 }
85
86 @Rule
87 public ExternalResource connManagerResource = new ExternalResource() {
88
89 @Override
90 protected void before() throws Throwable {
91 connManager = PoolingAsyncClientConnectionManagerBuilder.create()
92 .setTlsStrategy(new DefaultClientTlsStrategy(SSLTestContexts.createClientSSLContext()))
93 .build();
94 }
95
96 @Override
97 protected void after() {
98 if (connManager != null) {
99 connManager.close();
100 connManager = null;
101 }
102 }
103
104 };
105
106 @Rule
107 public ExternalResource clientBuilderResource = new ExternalResource() {
108
109 @Override
110 protected void before() throws Throwable {
111 clientBuilder = HttpAsyncClientBuilder.create()
112 .setDefaultRequestConfig(RequestConfig.custom()
113 .setConnectionRequestTimeout(TIMEOUT)
114 .setConnectTimeout(TIMEOUT)
115 .build())
116 .setConnectionManager(connManager);
117 }
118
119 };
120
121 @Override
122 protected CloseableHttpAsyncClient createClient() throws Exception {
123 return clientBuilder.build();
124 }
125
126 @Test
127 public void testBasicRedirect300NoKeepAlive() throws Exception {
128 final HttpHost target = start(new Decorator<AsyncServerExchangeHandler>() {
129
130 @Override
131 public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
132 return new RedirectingAsyncDecorator(
133 exchangeHandler,
134 new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MULTIPLE_CHOICES,
135 Redirect.ConnControl.CLOSE));
136 }
137
138 });
139 final HttpClientContext context = HttpClientContext.create();
140 final Future<SimpleHttpResponse> future = httpclient.execute(SimpleRequestBuilder.get()
141 .setHttpHost(target)
142 .setPath("/oldlocation/")
143 .build(), context, null);
144 final HttpResponse response = future.get();
145 Assert.assertNotNull(response);
146
147 final HttpRequest request = context.getRequest();
148
149 Assert.assertEquals(HttpStatus.SC_MULTIPLE_CHOICES, response.getCode());
150 Assert.assertEquals("/oldlocation/", request.getRequestUri());
151 }
152
153 @Test
154 public void testBasicRedirect301NoKeepAlive() throws Exception {
155 final HttpHost target = start(new Decorator<AsyncServerExchangeHandler>() {
156
157 @Override
158 public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
159 return new RedirectingAsyncDecorator(
160 exchangeHandler,
161 new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_PERMANENTLY,
162 Redirect.ConnControl.CLOSE));
163 }
164
165 });
166 final HttpClientContext context = HttpClientContext.create();
167 final Future<SimpleHttpResponse> future = httpclient.execute(SimpleRequestBuilder.get()
168 .setHttpHost(target)
169 .setPath("/oldlocation/100")
170 .build(), context, null);
171 final HttpResponse response = future.get();
172 Assert.assertNotNull(response);
173
174 final HttpRequest request = context.getRequest();
175
176 Assert.assertEquals(HttpStatus.SC_OK, response.getCode());
177 Assert.assertEquals("/random/100", request.getRequestUri());
178 Assert.assertEquals(target, new HttpHost(request.getScheme(), request.getAuthority()));
179 }
180
181 @Test
182 public void testDefaultHeadersRedirect() throws Exception {
183 final List<Header> defaultHeaders = new ArrayList<>(1);
184 defaultHeaders.add(new BasicHeader(HttpHeaders.USER_AGENT, "my-test-client"));
185 clientBuilder.setDefaultHeaders(defaultHeaders);
186
187 final HttpHost target = start(new Decorator<AsyncServerExchangeHandler>() {
188
189 @Override
190 public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
191 return new RedirectingAsyncDecorator(
192 exchangeHandler,
193 new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_PERMANENTLY,
194 Redirect.ConnControl.CLOSE));
195 }
196
197 });
198
199 final HttpClientContext context = HttpClientContext.create();
200
201 final Future<SimpleHttpResponse> future = httpclient.execute(SimpleRequestBuilder.get()
202 .setHttpHost(target)
203 .setPath("/oldlocation/123")
204 .build(), context, null);
205 final HttpResponse response = future.get();
206 Assert.assertNotNull(response);
207
208 final HttpRequest request = context.getRequest();
209
210 Assert.assertEquals(HttpStatus.SC_OK, response.getCode());
211 Assert.assertEquals("/random/123", request.getRequestUri());
212
213 final Header header = request.getFirstHeader(HttpHeaders.USER_AGENT);
214 Assert.assertEquals("my-test-client", header.getValue());
215 }
216
217 }