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.async;
28  
29  import java.util.ArrayList;
30  import java.util.List;
31  import java.util.concurrent.Future;
32  
33  import org.apache.hc.client5.http.async.methods.SimpleHttpResponse;
34  import org.apache.hc.client5.http.async.methods.SimpleRequestBuilder;
35  import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
36  import org.apache.hc.client5.http.protocol.HttpClientContext;
37  import org.apache.hc.client5.testing.OldPathRedirectResolver;
38  import org.apache.hc.client5.testing.redirect.Redirect;
39  import org.apache.hc.core5.function.Decorator;
40  import org.apache.hc.core5.http.Header;
41  import org.apache.hc.core5.http.HttpHeaders;
42  import org.apache.hc.core5.http.HttpHost;
43  import org.apache.hc.core5.http.HttpRequest;
44  import org.apache.hc.core5.http.HttpResponse;
45  import org.apache.hc.core5.http.HttpStatus;
46  import org.apache.hc.core5.http.HttpVersion;
47  import org.apache.hc.core5.http.URIScheme;
48  import org.apache.hc.core5.http.config.Http1Config;
49  import org.apache.hc.core5.http.message.BasicHeader;
50  import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
51  import org.apache.hc.core5.testing.nio.H2TestServer;
52  import org.junit.jupiter.api.Assertions;
53  import org.junit.jupiter.api.Test;
54  
55  /**
56   * Redirection test cases.
57   */
58  public abstract class TestHttp1AsyncRedirects extends AbstractHttpAsyncRedirectsTest<CloseableHttpAsyncClient> {
59  
60      public TestHttp1AsyncRedirects(final URIScheme scheme) {
61          super(scheme, HttpVersion.HTTP_1_1);
62      }
63  
64      @Override
65      protected H2TestServer startServer(final Decorator<AsyncServerExchangeHandler> exchangeHandlerDecorator) throws Exception {
66          return startServer(Http1Config.DEFAULT, null, exchangeHandlerDecorator);
67      }
68  
69      @Override
70      protected CloseableHttpAsyncClient startClient() throws Exception {
71          return startClient(b -> {});
72      }
73  
74      @Test
75      public void testBasicRedirect300NoKeepAlive() throws Exception {
76          final H2TestServer server = startServer(exchangeHandler -> new RedirectingAsyncDecorator(
77                  exchangeHandler,
78                  new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MULTIPLE_CHOICES,
79                          Redirect.ConnControl.CLOSE)));
80          server.register("/random/*", AsyncRandomHandler::new);
81          final HttpHost target = targetHost();
82  
83          final CloseableHttpAsyncClient client = startClient();
84  
85          final HttpClientContext context = HttpClientContext.create();
86          final Future<SimpleHttpResponse> future = client.execute(SimpleRequestBuilder.get()
87                          .setHttpHost(target)
88                          .setPath("/oldlocation/")
89                          .build(), context, null);
90          final HttpResponse response = future.get();
91          Assertions.assertNotNull(response);
92  
93          final HttpRequest request = context.getRequest();
94  
95          Assertions.assertEquals(HttpStatus.SC_MULTIPLE_CHOICES, response.getCode());
96          Assertions.assertEquals("/oldlocation/", request.getRequestUri());
97      }
98  
99      @Test
100     public void testBasicRedirect301NoKeepAlive() throws Exception {
101         final H2TestServer server = startServer(exchangeHandler -> new RedirectingAsyncDecorator(
102                 exchangeHandler,
103                 new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_PERMANENTLY,
104                         Redirect.ConnControl.CLOSE)));
105         server.register("/random/*", AsyncRandomHandler::new);
106         final HttpHost target = targetHost();
107 
108         final CloseableHttpAsyncClient client = startClient();
109 
110         final HttpClientContext context = HttpClientContext.create();
111         final Future<SimpleHttpResponse> future = client.execute(SimpleRequestBuilder.get()
112                         .setHttpHost(target)
113                         .setPath("/oldlocation/100")
114                         .build(), context, null);
115         final HttpResponse response = future.get();
116         Assertions.assertNotNull(response);
117 
118         final HttpRequest request = context.getRequest();
119 
120         Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
121         Assertions.assertEquals("/random/100", request.getRequestUri());
122         Assertions.assertEquals(target, new HttpHost(request.getScheme(), request.getAuthority()));
123     }
124 
125     @Test
126     public void testDefaultHeadersRedirect() throws Exception {
127         final H2TestServer server = startServer(exchangeHandler -> new RedirectingAsyncDecorator(
128                 exchangeHandler,
129                 new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_PERMANENTLY,
130                         Redirect.ConnControl.CLOSE)));
131         server.register("/random/*", AsyncRandomHandler::new);
132         final HttpHost target = targetHost();
133 
134         final List<Header> defaultHeaders = new ArrayList<>(1);
135         defaultHeaders.add(new BasicHeader(HttpHeaders.USER_AGENT, "my-test-client"));
136         final CloseableHttpAsyncClient client = startClient(builder -> builder
137                 .setDefaultHeaders(defaultHeaders)
138         );
139 
140         final HttpClientContext context = HttpClientContext.create();
141         final Future<SimpleHttpResponse> future = client.execute(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 
153         final Header header = request.getFirstHeader(HttpHeaders.USER_AGENT);
154         Assertions.assertEquals("my-test-client", header.getValue());
155     }
156 
157 }