diff --git a/httpclient5-testing/src/main/java/org/apache/hc/client5/testing/async/RedirectingAsyncDecorator.java b/httpclient5-testing/src/main/java/org/apache/hc/client5/testing/async/RedirectingAsyncDecorator.java
new file mode 100644
index 000000000..9fe15b506
--- /dev/null
+++ b/httpclient5-testing/src/main/java/org/apache/hc/client5/testing/async/RedirectingAsyncDecorator.java
@@ -0,0 +1,158 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ *
+ */
+
+package org.apache.hc.client5.testing.async;
+
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.nio.ByteBuffer;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.apache.hc.client5.testing.redirect.Redirect;
+import org.apache.hc.client5.testing.redirect.RedirectResolver;
+import org.apache.hc.core5.http.EntityDetails;
+import org.apache.hc.core5.http.Header;
+import org.apache.hc.core5.http.HeaderElements;
+import org.apache.hc.core5.http.HttpException;
+import org.apache.hc.core5.http.HttpHeaders;
+import org.apache.hc.core5.http.HttpRequest;
+import org.apache.hc.core5.http.HttpResponse;
+import org.apache.hc.core5.http.ProtocolException;
+import org.apache.hc.core5.http.message.BasicHeader;
+import org.apache.hc.core5.http.message.BasicHttpResponse;
+import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
+import org.apache.hc.core5.http.nio.CapacityChannel;
+import org.apache.hc.core5.http.nio.DataStreamChannel;
+import org.apache.hc.core5.http.nio.ResponseChannel;
+import org.apache.hc.core5.http.protocol.HttpContext;
+import org.apache.hc.core5.util.Args;
+
+public class RedirectingAsyncDecorator implements AsyncServerExchangeHandler {
+
+ private final AsyncServerExchangeHandler exchangeHandler;
+ private final RedirectResolver redirectResolver;
+ private final AtomicBoolean redirecting;
+
+ public RedirectingAsyncDecorator(final AsyncServerExchangeHandler exchangeHandler,
+ final RedirectResolver redirectResolver) {
+ this.exchangeHandler = Args.notNull(exchangeHandler, "Exchange handler");
+ this.redirectResolver = redirectResolver;
+ this.redirecting = new AtomicBoolean();
+ }
+
+ private Redirect resolveRedirect(final HttpRequest request) throws HttpException {
+ try {
+ final URI requestURI = request.getUri();
+ return redirectResolver != null ? redirectResolver.resolve(requestURI) : null;
+ } catch (final URISyntaxException ex) {
+ throw new ProtocolException(ex.getMessage(), ex);
+ }
+ }
+
+ private HttpResponse createRedirectResponse(final Redirect redirect) {
+ final HttpResponse response = new BasicHttpResponse(redirect.status);
+ if (redirect.location != null) {
+ response.addHeader(new BasicHeader(HttpHeaders.LOCATION, redirect.location));
+ }
+ switch (redirect.connControl) {
+ case KEEP_ALIVE:
+ response.addHeader(new BasicHeader(HttpHeaders.CONNECTION, HeaderElements.KEEP_ALIVE));
+ break;
+ case CLOSE:
+ response.addHeader(new BasicHeader(HttpHeaders.CONNECTION, HeaderElements.CLOSE));
+ }
+ return response;
+ }
+
+ @Override
+ public void handleRequest(final HttpRequest request,
+ final EntityDetails entityDetails,
+ final ResponseChannel responseChannel,
+ final HttpContext context) throws HttpException, IOException {
+ final Redirect redirect = resolveRedirect(request);
+ if (redirect != null) {
+ responseChannel.sendResponse(createRedirectResponse(redirect), null, context);
+ redirecting.set(true);
+ } else {
+ exchangeHandler.handleRequest(request, entityDetails, responseChannel, context);
+ }
+ }
+
+ @Override
+ public final void updateCapacity(final CapacityChannel capacityChannel) throws IOException {
+ if (!redirecting.get()) {
+ exchangeHandler.updateCapacity(capacityChannel);
+ } else {
+ capacityChannel.update(Integer.MAX_VALUE);
+ }
+ }
+
+ @Override
+ public final void consume(final ByteBuffer src) throws IOException {
+ if (!redirecting.get()) {
+ exchangeHandler.consume(src);
+ }
+ }
+
+ @Override
+ public final void streamEnd(final List extends Header> trailers) throws HttpException, IOException {
+ if (!redirecting.get()) {
+ exchangeHandler.streamEnd(trailers);
+ }
+ }
+
+ @Override
+ public int available() {
+ if (!redirecting.get()) {
+ return exchangeHandler.available();
+ } else {
+ return 0;
+ }
+ }
+
+ @Override
+ public void produce(final DataStreamChannel channel) throws IOException {
+ if (!redirecting.get()) {
+ exchangeHandler.produce(channel);
+ }
+ }
+
+ @Override
+ public void failed(final Exception cause) {
+ if (!redirecting.get()) {
+ exchangeHandler.failed(cause);
+ }
+ }
+
+ @Override
+ public void releaseResources() {
+ exchangeHandler.releaseResources();
+ }
+
+}
diff --git a/httpclient5-testing/src/main/java/org/apache/hc/client5/testing/classic/RedirectingDecorator.java b/httpclient5-testing/src/main/java/org/apache/hc/client5/testing/classic/RedirectingDecorator.java
new file mode 100644
index 000000000..37160a752
--- /dev/null
+++ b/httpclient5-testing/src/main/java/org/apache/hc/client5/testing/classic/RedirectingDecorator.java
@@ -0,0 +1,86 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ *
+ */
+
+package org.apache.hc.client5.testing.classic;
+
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+
+import org.apache.hc.client5.testing.redirect.Redirect;
+import org.apache.hc.client5.testing.redirect.RedirectResolver;
+import org.apache.hc.core5.http.ClassicHttpRequest;
+import org.apache.hc.core5.http.ClassicHttpResponse;
+import org.apache.hc.core5.http.HeaderElements;
+import org.apache.hc.core5.http.HttpException;
+import org.apache.hc.core5.http.HttpHeaders;
+import org.apache.hc.core5.http.ProtocolException;
+import org.apache.hc.core5.http.io.HttpServerRequestHandler;
+import org.apache.hc.core5.http.message.BasicClassicHttpResponse;
+import org.apache.hc.core5.http.message.BasicHeader;
+import org.apache.hc.core5.http.protocol.HttpContext;
+import org.apache.hc.core5.util.Args;
+
+public class RedirectingDecorator implements HttpServerRequestHandler {
+
+ private final HttpServerRequestHandler requestHandler;
+ private final RedirectResolver redirectResolver;
+
+ public RedirectingDecorator(final HttpServerRequestHandler requestHandler,
+ final RedirectResolver redirectResolver) {
+ this.requestHandler = Args.notNull(requestHandler, "Request handler");
+ this.redirectResolver = redirectResolver;
+ }
+
+ @Override
+ public void handle(final ClassicHttpRequest request,
+ final ResponseTrigger responseTrigger,
+ final HttpContext context) throws HttpException, IOException {
+ try {
+ final URI requestURI = request.getUri();
+ final Redirect redirect = redirectResolver != null ? redirectResolver.resolve(requestURI) : null;
+ if (redirect != null) {
+ final ClassicHttpResponse response = new BasicClassicHttpResponse(redirect.status);
+ if (redirect.location != null) {
+ response.addHeader(new BasicHeader(HttpHeaders.LOCATION, redirect.location));
+ }
+ switch (redirect.connControl) {
+ case KEEP_ALIVE:
+ response.addHeader(new BasicHeader(HttpHeaders.CONNECTION, HeaderElements.KEEP_ALIVE));
+ break;
+ case CLOSE:
+ response.addHeader(new BasicHeader(HttpHeaders.CONNECTION, HeaderElements.CLOSE));
+ }
+ responseTrigger.submitResponse(response);
+ } else {
+ requestHandler.handle(request, responseTrigger, context);
+ }
+ } catch (final URISyntaxException ex) {
+ throw new ProtocolException(ex.getMessage(), ex);
+ }
+ }
+}
diff --git a/httpclient5-testing/src/main/java/org/apache/hc/client5/testing/redirect/Redirect.java b/httpclient5-testing/src/main/java/org/apache/hc/client5/testing/redirect/Redirect.java
new file mode 100644
index 000000000..b52fb35a9
--- /dev/null
+++ b/httpclient5-testing/src/main/java/org/apache/hc/client5/testing/redirect/Redirect.java
@@ -0,0 +1,48 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ *
+ */
+
+package org.apache.hc.client5.testing.redirect;
+
+public class Redirect {
+
+ public enum ConnControl { PROTOCOL_DEFAULT, KEEP_ALIVE, CLOSE }
+
+ public final int status;
+ public final String location;
+ public final ConnControl connControl;
+
+ public Redirect(final int status, final String location, final ConnControl connControl) {
+ this.status = status;
+ this.location = location;
+ this.connControl = connControl;
+ }
+
+ public Redirect(final int status, final String location) {
+ this(status , location, ConnControl.PROTOCOL_DEFAULT);
+ }
+
+}
diff --git a/httpclient5-testing/src/main/java/org/apache/hc/client5/testing/redirect/RedirectResolver.java b/httpclient5-testing/src/main/java/org/apache/hc/client5/testing/redirect/RedirectResolver.java
new file mode 100644
index 000000000..2ffa2dbdf
--- /dev/null
+++ b/httpclient5-testing/src/main/java/org/apache/hc/client5/testing/redirect/RedirectResolver.java
@@ -0,0 +1,37 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ *
+ */
+
+package org.apache.hc.client5.testing.redirect;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+
+public interface RedirectResolver {
+
+ Redirect resolve(URI requestUri) throws URISyntaxException;
+
+}
diff --git a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/OldPathRedirectResolver.java b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/OldPathRedirectResolver.java
new file mode 100644
index 000000000..84aaf0979
--- /dev/null
+++ b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/OldPathRedirectResolver.java
@@ -0,0 +1,68 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ *
+ */
+
+package org.apache.hc.client5.testing;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+
+import org.apache.hc.client5.testing.redirect.Redirect;
+import org.apache.hc.client5.testing.redirect.RedirectResolver;
+import org.apache.hc.core5.net.URIBuilder;
+
+public class OldPathRedirectResolver implements RedirectResolver {
+
+ private final String oldPath;
+ private final String newPath;
+ private final int status;
+ private final Redirect.ConnControl connControl;
+
+ public OldPathRedirectResolver(
+ final String oldPath, final String newPath, final int status, final Redirect.ConnControl connControl) {
+ this.oldPath = oldPath;
+ this.newPath = newPath;
+ this.status = status;
+ this.connControl = connControl;
+ }
+
+ public OldPathRedirectResolver(final String oldPath, final String newPath, final int status) {
+ this(oldPath, newPath, status, Redirect.ConnControl.PROTOCOL_DEFAULT);
+ }
+
+ @Override
+ public Redirect resolve(final URI requestUri) throws URISyntaxException {
+ final String path = requestUri.getPath();
+ if (path.startsWith(oldPath)) {
+ final URI location = new URIBuilder(requestUri)
+ .setPath(newPath + path.substring(oldPath.length()))
+ .build();
+ return new Redirect(status, location.toString(), connControl);
+
+ }
+ return null;
+ }
+}
diff --git a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/AbstractHttpAsyncRedirectsTest.java b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/AbstractHttpAsyncRedirectsTest.java
index e92af3a1a..185722973 100644
--- a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/AbstractHttpAsyncRedirectsTest.java
+++ b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/AbstractHttpAsyncRedirectsTest.java
@@ -29,8 +29,6 @@ package org.apache.hc.client5.testing.async;
import java.net.InetSocketAddress;
import java.net.URI;
import java.net.URISyntaxException;
-import java.util.Queue;
-import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
@@ -45,7 +43,11 @@ import org.apache.hc.client5.http.cookie.CookieStore;
import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
import org.apache.hc.client5.http.impl.cookie.BasicClientCookie;
import org.apache.hc.client5.http.protocol.HttpClientContext;
+import org.apache.hc.client5.testing.OldPathRedirectResolver;
import org.apache.hc.client5.testing.SSLTestContexts;
+import org.apache.hc.client5.testing.redirect.Redirect;
+import org.apache.hc.client5.testing.redirect.RedirectResolver;
+import org.apache.hc.core5.function.Decorator;
import org.apache.hc.core5.function.Supplier;
import org.apache.hc.core5.http.ContentType;
import org.apache.hc.core5.http.Header;
@@ -58,14 +60,14 @@ import org.apache.hc.core5.http.HttpVersion;
import org.apache.hc.core5.http.ProtocolException;
import org.apache.hc.core5.http.URIScheme;
import org.apache.hc.core5.http.config.Http1Config;
-import org.apache.hc.core5.http.message.BasicHeader;
import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
import org.apache.hc.core5.http.protocol.HttpCoreContext;
import org.apache.hc.core5.http2.config.H2Config;
import org.apache.hc.core5.net.URIBuilder;
+import org.apache.hc.core5.reactive.ReactiveServerExchangeHandler;
import org.apache.hc.core5.reactor.IOReactorConfig;
-import org.apache.hc.core5.reactor.ListenerEndpoint;
import org.apache.hc.core5.testing.nio.H2TestServer;
+import org.apache.hc.core5.testing.reactive.ReactiveRandomProcessor;
import org.apache.hc.core5.util.TimeValue;
import org.junit.Assert;
import org.junit.Test;
@@ -88,132 +90,26 @@ public abstract class AbstractHttpAsyncRedirectsTest exchangeHandlerDecorator) throws Exception {
+ if (version.greaterEquals(HttpVersion.HTTP_2)) {
+ return super.start(null, exchangeHandlerDecorator, H2Config.DEFAULT);
+ } else {
+ return super.start(null, exchangeHandlerDecorator, Http1Config.DEFAULT);
}
-
- @Override
- protected SimpleHttpResponse handle(
- final SimpleHttpRequest request, final HttpCoreContext context) throws HttpException {
- try {
- final URI requestURI = request.getUri();
- final String path = requestURI.getPath();
- if (path.equals("/oldlocation/")) {
- final SimpleHttpResponse response = new SimpleHttpResponse(statuscode);
- response.addHeader(new BasicHeader("Location",
- new URIBuilder(requestURI).setPath("/newlocation/").build()));
- return response;
- } else if (path.equals("/newlocation/")) {
- final SimpleHttpResponse response = new SimpleHttpResponse(HttpStatus.SC_OK);
- response.setBody("Successful redirect", ContentType.TEXT_PLAIN);
- return response;
- } else {
- return new SimpleHttpResponse(HttpStatus.SC_NOT_FOUND);
- }
- } catch (final URISyntaxException ex) {
- throw new ProtocolException(ex.getMessage(), ex);
- }
- }
-
- }
-
- static class CircularRedirectService extends AbstractSimpleServerExchangeHandler {
-
- public CircularRedirectService() {
- super();
- }
-
- @Override
- protected SimpleHttpResponse handle(
- final SimpleHttpRequest request, final HttpCoreContext context) throws HttpException {
- try {
- final URI requestURI = request.getUri();
- final String path = requestURI.getPath();
- if (path.startsWith("/circular-oldlocation")) {
- final SimpleHttpResponse response = new SimpleHttpResponse(HttpStatus.SC_MOVED_TEMPORARILY);
- response.addHeader(new BasicHeader("Location", "/circular-location2"));
- return response;
- } else if (path.startsWith("/circular-location2")) {
- final SimpleHttpResponse response = new SimpleHttpResponse(HttpStatus.SC_MOVED_TEMPORARILY);
- response.addHeader(new BasicHeader("Location", "/circular-oldlocation"));
- return response;
- } else {
- return new SimpleHttpResponse(HttpStatus.SC_NOT_FOUND);
- }
- } catch (final URISyntaxException ex) {
- throw new ProtocolException(ex.getMessage(), ex);
- }
- }
-
- }
-
- static class RelativeRedirectService extends AbstractSimpleServerExchangeHandler {
-
- @Override
- protected SimpleHttpResponse handle(
- final SimpleHttpRequest request, final HttpCoreContext context) throws HttpException {
- try {
- final URI requestURI = request.getUri();
- final String path = requestURI.getPath();
- if (path.equals("/oldlocation/")) {
- final SimpleHttpResponse response = new SimpleHttpResponse(HttpStatus.SC_MOVED_TEMPORARILY);
- response.addHeader(new BasicHeader("Location", "/relativelocation/"));
- return response;
- } else if (path.equals("/relativelocation/")) {
- final SimpleHttpResponse response = new SimpleHttpResponse(HttpStatus.SC_OK);
- response.setBody("Successful redirect", ContentType.TEXT_PLAIN);
- return response;
- } else {
- return new SimpleHttpResponse(HttpStatus.SC_NOT_FOUND);
- }
- } catch (final URISyntaxException ex) {
- throw new ProtocolException(ex.getMessage(), ex);
- }
- }
- }
-
- static class RelativeRedirectService2 extends AbstractSimpleServerExchangeHandler {
-
- @Override
- protected SimpleHttpResponse handle(
- final SimpleHttpRequest request, final HttpCoreContext context) throws HttpException {
- try {
- final URI requestURI = request.getUri();
- final String path = requestURI.getPath();
- if (path.equals("/test/oldlocation")) {
- final SimpleHttpResponse response = new SimpleHttpResponse(HttpStatus.SC_MOVED_TEMPORARILY);
- response.addHeader(new BasicHeader("Location", "relativelocation"));
- return response;
- } else if (path.equals("/test/relativelocation")) {
- final SimpleHttpResponse response = new SimpleHttpResponse(HttpStatus.SC_OK);
- response.setBody("Successful redirect", ContentType.TEXT_PLAIN);
- return response;
- } else {
- return new SimpleHttpResponse(HttpStatus.SC_NOT_FOUND);
- }
- } catch (final URISyntaxException ex) {
- throw new ProtocolException(ex.getMessage(), ex);
- }
- }
-
}
@Test
public void testBasicRedirect300() throws Exception {
- server.register("*", new Supplier() {
+ final HttpHost target = start(new Decorator() {
@Override
- public AsyncServerExchangeHandler get() {
- return new BasicRedirectService(HttpStatus.SC_MULTIPLE_CHOICES);
+ public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
+ return new RedirectingAsyncDecorator(
+ exchangeHandler,
+ new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MULTIPLE_CHOICES));
}
});
- final HttpHost target = start();
final HttpClientContext context = HttpClientContext.create();
final Future future = httpclient.execute(
@@ -229,117 +125,131 @@ public abstract class AbstractHttpAsyncRedirectsTest () {
+ final HttpHost target = start(new Decorator() {
@Override
- public AsyncServerExchangeHandler get() {
- return new BasicRedirectService(HttpStatus.SC_MOVED_PERMANENTLY);
+ public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
+ return new RedirectingAsyncDecorator(
+ exchangeHandler,
+ new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_PERMANENTLY));
}
});
-
- final HttpHost target = start();
final HttpClientContext context = HttpClientContext.create();
final Future future = httpclient.execute(
- SimpleHttpRequests.get(target, "/oldlocation/"), context, null);
+ SimpleHttpRequests.get(target, "/oldlocation/100"), context, null);
final HttpResponse response = future.get();
Assert.assertNotNull(response);
final HttpRequest request = context.getRequest();
Assert.assertEquals(HttpStatus.SC_OK, response.getCode());
- Assert.assertEquals("/newlocation/", request.getRequestUri());
+ Assert.assertEquals("/random/100", request.getRequestUri());
Assert.assertEquals(target, new HttpHost(request.getScheme(), request.getAuthority()));
}
@Test
public void testBasicRedirect302() throws Exception {
- server.register("*", new Supplier() {
+ final HttpHost target = start(new Decorator() {
@Override
- public AsyncServerExchangeHandler get() {
- return new BasicRedirectService(HttpStatus.SC_MOVED_TEMPORARILY);
+ public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
+ return new RedirectingAsyncDecorator(
+ exchangeHandler,
+ new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_TEMPORARILY));
}
});
- final HttpHost target = start();
final HttpClientContext context = HttpClientContext.create();
final Future future = httpclient.execute(
- SimpleHttpRequests.get(target, "/oldlocation/"), context, null);
+ SimpleHttpRequests.get(target, "/oldlocation/123"), context, null);
final HttpResponse response = future.get();
Assert.assertNotNull(response);
final HttpRequest request = context.getRequest();
Assert.assertEquals(HttpStatus.SC_OK, response.getCode());
- Assert.assertEquals("/newlocation/", request.getRequestUri());
+ Assert.assertEquals("/random/123", request.getRequestUri());
Assert.assertEquals(target, new HttpHost(request.getScheme(), request.getAuthority()));
}
@Test
public void testBasicRedirect302NoLocation() throws Exception {
- server.register("*", new Supplier() {
+ final HttpHost target = start(new Decorator() {
@Override
- public AsyncServerExchangeHandler get() {
- return new AbstractSimpleServerExchangeHandler() {
+ public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
+ return new RedirectingAsyncDecorator(
+ exchangeHandler,
+ new RedirectResolver() {
- @Override
- protected SimpleHttpResponse handle(
- final SimpleHttpRequest request, final HttpCoreContext context) throws HttpException {
- return new SimpleHttpResponse(HttpStatus.SC_MOVED_TEMPORARILY);
- }
+ @Override
+ public Redirect resolve(final URI requestUri) throws URISyntaxException {
+ final String path = requestUri.getPath();
+ if (path.startsWith("/oldlocation")) {
+ return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, null);
+ }
+ return null;
+ }
- };
+ });
}
});
- final HttpHost target = start();
final HttpClientContext context = HttpClientContext.create();
final Future future = httpclient.execute(
- SimpleHttpRequests.get(target, "/oldlocation/"), context, null);
+ SimpleHttpRequests.get(target, "/oldlocation/100"), context, null);
final HttpResponse response = future.get();
Assert.assertNotNull(response);
final HttpRequest request = context.getRequest();
Assert.assertEquals(HttpStatus.SC_MOVED_TEMPORARILY, response.getCode());
- Assert.assertEquals("/oldlocation/", request.getRequestUri());
+ Assert.assertEquals("/oldlocation/100", request.getRequestUri());
Assert.assertEquals(target, new HttpHost(request.getScheme(), request.getAuthority()));
}
@Test
public void testBasicRedirect303() throws Exception {
- server.register("*", new Supplier() {
+ final HttpHost target = start(new Decorator() {
@Override
- public AsyncServerExchangeHandler get() {
- return new BasicRedirectService(HttpStatus.SC_SEE_OTHER);
+ public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
+ return new RedirectingAsyncDecorator(
+ exchangeHandler,
+ new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_SEE_OTHER));
}
});
- final HttpHost target = start();
final HttpClientContext context = HttpClientContext.create();
final Future future = httpclient.execute(
- SimpleHttpRequests.get(target, "/oldlocation/"), context, null);
+ SimpleHttpRequests.get(target, "/oldlocation/123"), context, null);
final HttpResponse response = future.get();
Assert.assertNotNull(response);
final HttpRequest request = context.getRequest();
Assert.assertEquals(HttpStatus.SC_OK, response.getCode());
- Assert.assertEquals("/newlocation/", request.getRequestUri());
+ Assert.assertEquals("/random/123", request.getRequestUri());
Assert.assertEquals(target, new HttpHost(request.getScheme(), request.getAuthority()));
}
@Test
public void testBasicRedirect304() throws Exception {
- server.register("*", new Supplier() {
+ server.register("/oldlocation/*", new Supplier() {
@Override
public AsyncServerExchangeHandler get() {
- return new BasicRedirectService(HttpStatus.SC_NOT_MODIFIED);
- }
+ return new AbstractSimpleServerExchangeHandler() {
+
+ @Override
+ protected SimpleHttpResponse handle(final SimpleHttpRequest request,
+ final HttpCoreContext context) throws HttpException {
+ return SimpleHttpResponse.create(HttpStatus.SC_NOT_MODIFIED, (String) null);
+ }
+ };
+
+ }
});
final HttpHost target = start();
final HttpClientContext context = HttpClientContext.create();
@@ -356,13 +266,21 @@ public abstract class AbstractHttpAsyncRedirectsTest () {
+ server.register("/oldlocation/*", new Supplier() {
@Override
public AsyncServerExchangeHandler get() {
- return new BasicRedirectService(HttpStatus.SC_USE_PROXY);
- }
+ return new AbstractSimpleServerExchangeHandler() {
+
+ @Override
+ protected SimpleHttpResponse handle(final SimpleHttpRequest request,
+ final HttpCoreContext context) throws HttpException {
+ return SimpleHttpResponse.create(HttpStatus.SC_USE_PROXY, (String) null);
+ }
+ };
+
+ }
});
final HttpHost target = start();
final HttpClientContext context = HttpClientContext.create();
@@ -379,39 +297,42 @@ public abstract class AbstractHttpAsyncRedirectsTest () {
+ final HttpHost target = start(new Decorator() {
@Override
- public AsyncServerExchangeHandler get() {
- return new BasicRedirectService(HttpStatus.SC_TEMPORARY_REDIRECT);
+ public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
+ return new RedirectingAsyncDecorator(
+ exchangeHandler,
+ new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_TEMPORARY_REDIRECT));
}
});
- final HttpHost target = start();
final HttpClientContext context = HttpClientContext.create();
final Future future = httpclient.execute(
- SimpleHttpRequests.get(target, "/oldlocation/"), context, null);
+ SimpleHttpRequests.get(target, "/oldlocation/123"), context, null);
final HttpResponse response = future.get();
Assert.assertNotNull(response);
final HttpRequest request = context.getRequest();
Assert.assertEquals(HttpStatus.SC_OK, response.getCode());
- Assert.assertEquals("/newlocation/", request.getRequestUri());
+ Assert.assertEquals("/random/123", request.getRequestUri());
Assert.assertEquals(target, new HttpHost(request.getScheme(), request.getAuthority()));
}
@Test(expected=ExecutionException.class)
public void testMaxRedirectCheck() throws Exception {
- server.register("*", new Supplier() {
+ final HttpHost target = start(new Decorator() {
@Override
- public AsyncServerExchangeHandler get() {
- return new CircularRedirectService();
+ public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
+ return new RedirectingAsyncDecorator(
+ exchangeHandler,
+ new OldPathRedirectResolver("/circular-oldlocation/", "/circular-oldlocation/",
+ HttpStatus.SC_MOVED_TEMPORARILY));
}
});
- final HttpHost target = start();
final RequestConfig config = RequestConfig.custom()
.setCircularRedirectsAllowed(true)
@@ -429,15 +350,17 @@ public abstract class AbstractHttpAsyncRedirectsTest () {
+ final HttpHost target = start(new Decorator() {
@Override
- public AsyncServerExchangeHandler get() {
- return new CircularRedirectService();
+ public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
+ return new RedirectingAsyncDecorator(
+ exchangeHandler,
+ new OldPathRedirectResolver("/circular-oldlocation/", "/circular-oldlocation/",
+ HttpStatus.SC_MOVED_TEMPORARILY));
}
});
- final HttpHost target = start();
final RequestConfig config = RequestConfig.custom()
.setCircularRedirectsAllowed(false)
@@ -455,19 +378,20 @@ public abstract class AbstractHttpAsyncRedirectsTest () {
+ final HttpHost target = start(new Decorator() {
@Override
- public AsyncServerExchangeHandler get() {
- return new BasicRedirectService(HttpStatus.SC_SEE_OTHER);
+ public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
+ return new RedirectingAsyncDecorator(
+ exchangeHandler,
+ new OldPathRedirectResolver("/oldlocation", "/echo", HttpStatus.SC_SEE_OTHER));
}
});
- final HttpHost target = start();
final HttpClientContext context = HttpClientContext.create();
- final SimpleHttpRequest post = SimpleHttpRequests.post(target, "/oldlocation/");
+ final SimpleHttpRequest post = SimpleHttpRequests.post(target, "/oldlocation/stuff");
post.setBody("stuff", ContentType.TEXT_PLAIN);
final Future future = httpclient.execute(post, context, null);
final HttpResponse response = future.get();
@@ -476,106 +400,112 @@ public abstract class AbstractHttpAsyncRedirectsTest () {
+ final HttpHost target = start(new Decorator() {
@Override
- public AsyncServerExchangeHandler get() {
- return new RelativeRedirectService();
+ public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
+ return new RedirectingAsyncDecorator(
+ exchangeHandler,
+ new RedirectResolver() {
+
+ @Override
+ public Redirect resolve(final URI requestUri) throws URISyntaxException {
+ final String path = requestUri.getPath();
+ if (path.startsWith("/oldlocation")) {
+ return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, "/random/100");
+
+ }
+ return null;
+ }
+
+ });
}
});
- final HttpHost target = start();
final HttpClientContext context = HttpClientContext.create();
final Future future = httpclient.execute(
- SimpleHttpRequests.get(target, "/oldlocation/"), context, null);
+ SimpleHttpRequests.get(target, "/oldlocation/stuff"), context, null);
final HttpResponse response = future.get();
Assert.assertNotNull(response);
final HttpRequest request = context.getRequest();
Assert.assertEquals(HttpStatus.SC_OK, response.getCode());
- Assert.assertEquals("/relativelocation/", request.getRequestUri());
+ Assert.assertEquals("/random/100", request.getRequestUri());
Assert.assertEquals(target, new HttpHost(request.getScheme(), request.getAuthority()));
}
@Test
public void testRelativeRedirect2() throws Exception {
- server.register("*", new Supplier() {
+ final HttpHost target = start(new Decorator() {
@Override
- public AsyncServerExchangeHandler get() {
- return new RelativeRedirectService2();
+ public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
+ return new RedirectingAsyncDecorator(
+ exchangeHandler,
+ new RedirectResolver() {
+
+ @Override
+ public Redirect resolve(final URI requestUri) throws URISyntaxException {
+ final String path = requestUri.getPath();
+ if (path.equals("/random/oldlocation")) {
+ return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, "100");
+
+ }
+ return null;
+ }
+
+ });
}
});
- final HttpHost target = start();
final HttpClientContext context = HttpClientContext.create();
final Future future = httpclient.execute(
- SimpleHttpRequests.get(target, "/test/oldlocation"), context, null);
+ SimpleHttpRequests.get(target, "/random/oldlocation"), context, null);
final HttpResponse response = future.get();
Assert.assertNotNull(response);
final HttpRequest request = context.getRequest();
Assert.assertEquals(HttpStatus.SC_OK, response.getCode());
- Assert.assertEquals("/test/relativelocation", request.getRequestUri());
+ Assert.assertEquals("/random/100", request.getRequestUri());
Assert.assertEquals(target, new HttpHost(request.getScheme(), request.getAuthority()));
}
- static class BogusRedirectService extends AbstractSimpleServerExchangeHandler {
-
- private final String url;
-
- public BogusRedirectService(final String url) {
- super();
- this.url = url;
- }
-
- @Override
- protected SimpleHttpResponse handle(
- final SimpleHttpRequest request, final HttpCoreContext context) throws HttpException {
- try {
- final URI requestURI = request.getUri();
- final String path = requestURI.getPath();
- if (path.equals("/oldlocation/")) {
- final SimpleHttpResponse response = new SimpleHttpResponse(HttpStatus.SC_MOVED_TEMPORARILY);
- response.addHeader(new BasicHeader("Location", url));
- return response;
- } else if (path.equals("/relativelocation/")) {
- final SimpleHttpResponse response = new SimpleHttpResponse(HttpStatus.SC_OK);
- response.setBody("Successful redirect", ContentType.TEXT_PLAIN);
- return response;
- } else {
- return new SimpleHttpResponse(HttpStatus.SC_NOT_FOUND);
- }
- } catch (final URISyntaxException ex) {
- throw new ProtocolException(ex.getMessage(), ex);
- }
- }
-
- }
-
@Test(expected=ExecutionException.class)
public void testRejectBogusRedirectLocation() throws Exception {
- server.register("*", new Supplier() {
+ final HttpHost target = start(new Decorator() {
@Override
- public AsyncServerExchangeHandler get() {
- return new BogusRedirectService("xxx://bogus");
+ public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
+ return new RedirectingAsyncDecorator(
+ exchangeHandler,
+ new RedirectResolver() {
+
+ @Override
+ public Redirect resolve(final URI requestUri) throws URISyntaxException {
+ final String path = requestUri.getPath();
+ if (path.equals("/oldlocation/")) {
+ return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, "xxx://bogus");
+
+ }
+ return null;
+ }
+
+ });
}
});
- final HttpHost target = start();
try {
final Future future = httpclient.execute(
@@ -589,15 +519,28 @@ public abstract class AbstractHttpAsyncRedirectsTest () {
+ final HttpHost target = start(new Decorator() {
@Override
- public AsyncServerExchangeHandler get() {
- return new BogusRedirectService("/newlocation/?p=I have spaces");
+ public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
+ return new RedirectingAsyncDecorator(
+ exchangeHandler,
+ new RedirectResolver() {
+
+ @Override
+ public Redirect resolve(final URI requestUri) throws URISyntaxException {
+ final String path = requestUri.getPath();
+ if (path.equals("/oldlocation/")) {
+ return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, "/newlocation/?p=I have spaces");
+
+ }
+ return null;
+ }
+
+ });
}
});
- final HttpHost target = start();
try {
final Future future = httpclient.execute(
@@ -611,15 +554,16 @@ public abstract class AbstractHttpAsyncRedirectsTest () {
+ final HttpHost target = start(new Decorator() {
@Override
- public AsyncServerExchangeHandler get() {
- return new BasicRedirectService(HttpStatus.SC_MOVED_TEMPORARILY);
+ public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
+ return new RedirectingAsyncDecorator(
+ exchangeHandler,
+ new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_TEMPORARILY));
}
});
- final HttpHost target = start();
final CookieStore cookieStore = new BasicCookieStore();
final HttpClientContext context = HttpClientContext.create();
@@ -632,214 +576,84 @@ public abstract class AbstractHttpAsyncRedirectsTest future = httpclient.execute(
- SimpleHttpRequests.get(target, "/oldlocation/"), context, null);
+ SimpleHttpRequests.get(target, "/oldlocation/100"), context, null);
final HttpResponse response = future.get();
Assert.assertNotNull(response);
final HttpRequest request = context.getRequest();
Assert.assertEquals(HttpStatus.SC_OK, response.getCode());
- Assert.assertEquals("/newlocation/", request.getRequestUri());
+ Assert.assertEquals("/random/100", request.getRequestUri());
final Header[] headers = request.getHeaders("Cookie");
Assert.assertEquals("There can only be one (cookie)", 1, headers.length);
}
- static class CrossSiteRedirectService extends AbstractSimpleServerExchangeHandler {
-
- private final HttpHost host;
-
- public CrossSiteRedirectService(final HttpHost host) {
- super();
- this.host = host;
- }
-
- @Override
- protected SimpleHttpResponse handle(
- final SimpleHttpRequest request, final HttpCoreContext context) throws HttpException {
- final String location;
- try {
- final URIBuilder uribuilder = new URIBuilder(request.getUri());
- uribuilder.setScheme(host.getSchemeName());
- uribuilder.setHost(host.getHostName());
- uribuilder.setPort(host.getPort());
- uribuilder.setPath("/random/1024");
- location = uribuilder.build().toASCIIString();
- } catch (final URISyntaxException ex) {
- throw new ProtocolException("Invalid request URI", ex);
- }
- final SimpleHttpResponse response = new SimpleHttpResponse(HttpStatus.SC_TEMPORARY_REDIRECT);
- response.addHeader(new BasicHeader("Location", location));
- return response;
- }
- }
-
@Test
public void testCrossSiteRedirect() throws Exception {
- server.register("/random/*", new Supplier() {
-
- @Override
- public AsyncServerExchangeHandler get() {
- return new AsyncRandomHandler();
- }
-
- });
- final HttpHost redirectTarget = start();
-
final H2TestServer secondServer = new H2TestServer(IOReactorConfig.DEFAULT,
scheme == URIScheme.HTTPS ? SSLTestContexts.createServerSSLContext() : null, null, null);
try {
- secondServer.register("/redirect/*", new Supplier() {
+ secondServer.register("/random/*", new Supplier() {
@Override
public AsyncServerExchangeHandler get() {
- return new CrossSiteRedirectService(redirectTarget);
+ if (isReactive()) {
+ return new ReactiveServerExchangeHandler(new ReactiveRandomProcessor());
+ } else {
+ return new AsyncRandomHandler();
+ }
+ }
+
+ });
+ final InetSocketAddress address2;
+ if (version.greaterEquals(HttpVersion.HTTP_2)) {
+ address2 = secondServer.start(H2Config.DEFAULT);
+ } else {
+ address2 = secondServer.start(Http1Config.DEFAULT);
+ }
+ final HttpHost redirectTarget = new HttpHost(scheme.name(), "localhost", address2.getPort());
+
+ final HttpHost target = start(new Decorator() {
+
+ @Override
+ public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
+ return new RedirectingAsyncDecorator(
+ exchangeHandler,
+ new RedirectResolver() {
+
+ @Override
+ public Redirect resolve(final URI requestUri) throws URISyntaxException {
+ final String path = requestUri.getPath();
+ if (path.equals("/oldlocation")) {
+ final URI location = new URIBuilder(requestUri)
+ .setHttpHost(redirectTarget)
+ .setPath("/random/100")
+ .build();
+ return new Redirect(HttpStatus.SC_MOVED_PERMANENTLY, location.toString());
+ }
+ return null;
+ }
+
+ });
}
});
- if (version.greaterEquals(HttpVersion.HTTP_2)) {
- secondServer.start(H2Config.DEFAULT);
- } else {
- secondServer.start(Http1Config.DEFAULT);
- }
- final Future endpointFuture = secondServer.listen(new InetSocketAddress(0));
- final ListenerEndpoint endpoint2 = endpointFuture.get();
+ final HttpClientContext context = HttpClientContext.create();
+ final Future future = httpclient.execute(
+ SimpleHttpRequests.get(target, "/oldlocation"), context, null);
+ final HttpResponse response = future.get();
+ Assert.assertNotNull(response);
- final InetSocketAddress address2 = (InetSocketAddress) endpoint2.getAddress();
- final HttpHost initialTarget = new HttpHost(scheme.name(), "localhost", address2.getPort());
+ final HttpRequest request = context.getRequest();
- final Queue> queue = new ConcurrentLinkedQueue<>();
- for (int i = 0; i < 1; i++) {
- queue.add(httpclient.execute(SimpleHttpRequests.get(initialTarget, "/redirect/anywhere"), null));
- }
- while (!queue.isEmpty()) {
- final Future future = queue.remove();
- final HttpResponse response = future.get();
- Assert.assertNotNull(response);
- Assert.assertEquals(200, response.getCode());
- }
+ Assert.assertEquals(HttpStatus.SC_OK, response.getCode());
+ Assert.assertEquals("/random/100", request.getRequestUri());
+ Assert.assertEquals(redirectTarget, new HttpHost(request.getScheme(), request.getAuthority()));
} finally {
server.shutdown(TimeValue.ofSeconds(5));
}
}
- private static class RomeRedirectService extends AbstractSimpleServerExchangeHandler {
-
- @Override
- protected SimpleHttpResponse handle(
- final SimpleHttpRequest request, final HttpCoreContext context) throws HttpException {
- try {
- final URI requestURI = request.getUri();
- final String path = requestURI.getPath();
- if (path.equals("/rome")) {
- final SimpleHttpResponse response = new SimpleHttpResponse(HttpStatus.SC_OK);
- response.setBody("Successful redirect", ContentType.TEXT_PLAIN);
- return response;
- } else {
- final SimpleHttpResponse response = new SimpleHttpResponse(HttpStatus.SC_MOVED_TEMPORARILY);
- response.addHeader(new BasicHeader("Location", "/rome"));
- return response;
- }
- } catch (final URISyntaxException ex) {
- throw new ProtocolException(ex.getMessage(), ex);
- }
- }
-
- }
-
- @Test
- public void testRepeatRequest() throws Exception {
- server.register("*", new Supplier() {
-
- @Override
- public AsyncServerExchangeHandler get() {
- return new RomeRedirectService();
- }
-
- });
- final HttpHost target = start();
-
- final HttpClientContext context = HttpClientContext.create();
-
- final Future future1 = httpclient.execute(
- SimpleHttpRequests.get(target, "/rome"), context, null);
- final HttpResponse response1 = future1.get();
- Assert.assertNotNull(response1);
-
- final Future future2 = httpclient.execute(
- SimpleHttpRequests.get(target, "/rome"), context, null);
- final HttpResponse response2 = future2.get();
- Assert.assertNotNull(response2);
-
- final HttpRequest request = context.getRequest();
-
- Assert.assertEquals(HttpStatus.SC_OK, response2.getCode());
- Assert.assertEquals("/rome", request.getRequestUri());
- Assert.assertEquals(target, new HttpHost(request.getScheme(), request.getAuthority()));
- }
-
- @Test
- public void testRepeatRequestRedirect() throws Exception {
- server.register("*", new Supplier() {
-
- @Override
- public AsyncServerExchangeHandler get() {
- return new RomeRedirectService();
- }
-
- });
- final HttpHost target = start();
-
- final HttpClientContext context = HttpClientContext.create();
-
- final Future future1 = httpclient.execute(
- SimpleHttpRequests.get(target, "/lille"), context, null);
- final HttpResponse response1 = future1.get();
- Assert.assertNotNull(response1);
-
- final Future future2 = httpclient.execute(
- SimpleHttpRequests.get(target, "/lille"), context, null);
- final HttpResponse response2 = future2.get();
- Assert.assertNotNull(response2);
-
- final HttpRequest request = context.getRequest();
-
- Assert.assertEquals(HttpStatus.SC_OK, response2.getCode());
- Assert.assertEquals("/rome", request.getRequestUri());
- Assert.assertEquals(target, new HttpHost(request.getScheme(), request.getAuthority()));
- }
-
- @Test
- public void testDifferentRequestSameRedirect() throws Exception {
- server.register("*", new Supplier() {
-
- @Override
- public AsyncServerExchangeHandler get() {
- return new RomeRedirectService();
- }
-
- });
- final HttpHost target = start();
-
- final HttpClientContext context = HttpClientContext.create();
-
- final Future future1 = httpclient.execute(
- SimpleHttpRequests.get(target, "/alian"), context, null);
- final HttpResponse response1 = future1.get();
- Assert.assertNotNull(response1);
-
- final Future future2 = httpclient.execute(
- SimpleHttpRequests.get(target, "/lille"), context, null);
- final HttpResponse response2 = future2.get();
- Assert.assertNotNull(response2);
-
-
- final HttpRequest request = context.getRequest();
-
- Assert.assertEquals(HttpStatus.SC_OK, response2.getCode());
- Assert.assertEquals("/rome", request.getRequestUri());
- Assert.assertEquals(target, new HttpHost(request.getScheme(), request.getAuthority()));
- }
-
}
diff --git a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/TestHttp1AsyncRedirects.java b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/TestHttp1AsyncRedirects.java
index 0e2239032..ee72da949 100644
--- a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/TestHttp1AsyncRedirects.java
+++ b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/TestHttp1AsyncRedirects.java
@@ -26,15 +26,12 @@
*/
package org.apache.hc.client5.testing.async;
-import java.net.URI;
-import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.Future;
-import org.apache.hc.client5.http.async.methods.SimpleHttpRequest;
import org.apache.hc.client5.http.async.methods.SimpleHttpRequests;
import org.apache.hc.client5.http.async.methods.SimpleHttpResponse;
import org.apache.hc.client5.http.config.RequestConfig;
@@ -44,23 +41,20 @@ import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManager;
import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManagerBuilder;
import org.apache.hc.client5.http.protocol.HttpClientContext;
import org.apache.hc.client5.http.ssl.DefaultClientTlsStrategy;
+import org.apache.hc.client5.testing.OldPathRedirectResolver;
import org.apache.hc.client5.testing.SSLTestContexts;
-import org.apache.hc.core5.function.Supplier;
-import org.apache.hc.core5.http.ContentType;
+import org.apache.hc.client5.testing.redirect.Redirect;
+import org.apache.hc.core5.function.Decorator;
import org.apache.hc.core5.http.Header;
-import org.apache.hc.core5.http.HttpException;
import org.apache.hc.core5.http.HttpHeaders;
import org.apache.hc.core5.http.HttpHost;
import org.apache.hc.core5.http.HttpRequest;
import org.apache.hc.core5.http.HttpResponse;
import org.apache.hc.core5.http.HttpStatus;
import org.apache.hc.core5.http.HttpVersion;
-import org.apache.hc.core5.http.ProtocolException;
import org.apache.hc.core5.http.URIScheme;
import org.apache.hc.core5.http.message.BasicHeader;
import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
-import org.apache.hc.core5.http.protocol.HttpCoreContext;
-import org.apache.hc.core5.net.URIBuilder;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
@@ -129,54 +123,19 @@ public class TestHttp1AsyncRedirects extends AbstractHttpAsyncRedirectsTest() {
+ public void testBasicRedirect300NoKeepAlive() throws Exception {
+ final HttpHost target = start(new Decorator() {
@Override
- public AsyncServerExchangeHandler get() {
- return new NoKeepAliveRedirectService(HttpStatus.SC_MULTIPLE_CHOICES);
+ public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
+ return new RedirectingAsyncDecorator(
+ exchangeHandler,
+ new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MULTIPLE_CHOICES,
+ Redirect.ConnControl.CLOSE));
}
});
- final HttpHost target = start();
-
final HttpClientContext context = HttpClientContext.create();
final Future future = httpclient.execute(
SimpleHttpRequests.get(target, "/oldlocation/"), context, null);
@@ -191,57 +150,59 @@ public class TestHttp1AsyncRedirects extends AbstractHttpAsyncRedirectsTest() {
+ final HttpHost target = start(new Decorator() {
@Override
- public AsyncServerExchangeHandler get() {
- return new NoKeepAliveRedirectService(HttpStatus.SC_MOVED_PERMANENTLY);
+ public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
+ return new RedirectingAsyncDecorator(
+ exchangeHandler,
+ new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_PERMANENTLY,
+ Redirect.ConnControl.CLOSE));
}
});
-
- final HttpHost target = start();
final HttpClientContext context = HttpClientContext.create();
final Future future = httpclient.execute(
- SimpleHttpRequests.get(target, "/oldlocation/"), context, null);
+ SimpleHttpRequests.get(target, "/oldlocation/100"), context, null);
final HttpResponse response = future.get();
Assert.assertNotNull(response);
final HttpRequest request = context.getRequest();
Assert.assertEquals(HttpStatus.SC_OK, response.getCode());
- Assert.assertEquals("/newlocation/", request.getRequestUri());
+ Assert.assertEquals("/random/100", request.getRequestUri());
Assert.assertEquals(target, new HttpHost(request.getScheme(), request.getAuthority()));
}
@Test
public void testDefaultHeadersRedirect() throws Exception {
- server.register("*", new Supplier() {
-
- @Override
- public AsyncServerExchangeHandler get() {
- return new NoKeepAliveRedirectService(HttpStatus.SC_MOVED_TEMPORARILY);
- }
-
- });
-
final List defaultHeaders = new ArrayList<>(1);
defaultHeaders.add(new BasicHeader(HttpHeaders.USER_AGENT, "my-test-client"));
clientBuilder.setDefaultHeaders(defaultHeaders);
- final HttpHost target = start();
+ final HttpHost target = start(new Decorator() {
+
+ @Override
+ public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
+ return new RedirectingAsyncDecorator(
+ exchangeHandler,
+ new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_PERMANENTLY,
+ Redirect.ConnControl.CLOSE));
+ }
+
+ });
final HttpClientContext context = HttpClientContext.create();
final Future future = httpclient.execute(
- SimpleHttpRequests.get(target, "/oldlocation/"), context, null);
+ SimpleHttpRequests.get(target, "/oldlocation/123"), context, null);
final HttpResponse response = future.get();
Assert.assertNotNull(response);
final HttpRequest request = context.getRequest();
Assert.assertEquals(HttpStatus.SC_OK, response.getCode());
- Assert.assertEquals("/newlocation/", request.getRequestUri());
+ Assert.assertEquals("/random/123", request.getRequestUri());
final Header header = request.getFirstHeader(HttpHeaders.USER_AGENT);
Assert.assertEquals("my-test-client", header.getValue());
diff --git a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestRedirects.java b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestRedirects.java
index aedefd6c4..78b12b1b6 100644
--- a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestRedirects.java
+++ b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestRedirects.java
@@ -43,6 +43,11 @@ import org.apache.hc.client5.http.impl.cookie.BasicClientCookie;
import org.apache.hc.client5.http.protocol.HttpClientContext;
import org.apache.hc.client5.http.protocol.RedirectLocations;
import org.apache.hc.client5.http.utils.URIUtils;
+import org.apache.hc.client5.testing.OldPathRedirectResolver;
+import org.apache.hc.client5.testing.classic.RedirectingDecorator;
+import org.apache.hc.client5.testing.redirect.Redirect;
+import org.apache.hc.client5.testing.redirect.RedirectResolver;
+import org.apache.hc.core5.function.Decorator;
import org.apache.hc.core5.http.ClassicHttpRequest;
import org.apache.hc.core5.http.ClassicHttpResponse;
import org.apache.hc.core5.http.Header;
@@ -53,11 +58,11 @@ import org.apache.hc.core5.http.HttpRequest;
import org.apache.hc.core5.http.HttpStatus;
import org.apache.hc.core5.http.ProtocolException;
import org.apache.hc.core5.http.io.HttpRequestHandler;
+import org.apache.hc.core5.http.io.HttpServerRequestHandler;
import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.apache.hc.core5.http.io.entity.StringEntity;
import org.apache.hc.core5.http.message.BasicHeader;
import org.apache.hc.core5.http.protocol.HttpContext;
-import org.apache.hc.core5.net.URIBuilder;
import org.junit.Assert;
import org.junit.Test;
@@ -66,282 +71,201 @@ import org.junit.Test;
*/
public class TestRedirects extends LocalServerTestBase {
- private static class BasicRedirectService implements HttpRequestHandler {
+ @Test
+ public void testBasicRedirect300() throws Exception {
+ final HttpHost target = start(null, new Decorator() {
- private final int statuscode;
-
- public BasicRedirectService(final int statuscode) {
- super();
- this.statuscode = statuscode > 0 ? statuscode : HttpStatus.SC_MOVED_TEMPORARILY;
- }
-
- public BasicRedirectService() {
- this(-1);
- }
-
- @Override
- public void handle(
- final ClassicHttpRequest request,
- final ClassicHttpResponse response,
- final HttpContext context) throws HttpException, IOException {
-
- try {
- final URI requestURI = request.getUri();
- final String path = requestURI.getPath();
- if (path.equals("/oldlocation/")) {
- response.setCode(this.statuscode);
- response.addHeader(new BasicHeader("Location",
- new URIBuilder(requestURI).setPath("/newlocation/").build()));
- response.addHeader(new BasicHeader("Connection", "close"));
- } else if (path.equals("/newlocation/")) {
- response.setCode(HttpStatus.SC_OK);
- final StringEntity entity = new StringEntity("Successful redirect");
- response.setEntity(entity);
- } else {
- response.setCode(HttpStatus.SC_NOT_FOUND);
- }
-
- } catch (final URISyntaxException ex) {
- throw new ProtocolException(ex.getMessage(), ex);
+ @Override
+ public HttpServerRequestHandler decorate(final HttpServerRequestHandler requestHandler) {
+ return new RedirectingDecorator(
+ requestHandler,
+ new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MULTIPLE_CHOICES));
}
- }
- }
+ });
- private static class CircularRedirectService implements HttpRequestHandler {
+ final HttpClientContext context = HttpClientContext.create();
+ final HttpGet httpget = new HttpGet("/oldlocation/100");
+ try (final ClassicHttpResponse response = this.httpclient.execute(target, httpget, context)) {
+ final HttpRequest reqWrapper = context.getRequest();
- public CircularRedirectService() {
- super();
- }
+ Assert.assertEquals(HttpStatus.SC_MULTIPLE_CHOICES, response.getCode());
+ Assert.assertEquals(URIUtils.create(target, "/oldlocation/100"), reqWrapper.getUri());
- @Override
- public void handle(
- final ClassicHttpRequest request,
- final ClassicHttpResponse response,
- final HttpContext context) throws HttpException, IOException {
- try {
- final URI requestURI = request.getUri();
- final String path = requestURI.getPath();
- if (path.startsWith("/circular-oldlocation")) {
- response.setCode(HttpStatus.SC_MOVED_TEMPORARILY);
- response.addHeader(new BasicHeader("Location", "/circular-location2"));
- } else if (path.startsWith("/circular-location2")) {
- response.setCode(HttpStatus.SC_MOVED_TEMPORARILY);
- response.addHeader(new BasicHeader("Location", "/circular-oldlocation"));
- } else {
- response.setCode(HttpStatus.SC_NOT_FOUND);
- }
- } catch (final URISyntaxException ex) {
- throw new ProtocolException(ex.getMessage(), ex);
- }
- }
- }
+ final RedirectLocations redirects = context.getRedirectLocations();
+ Assert.assertNotNull(redirects);
+ Assert.assertEquals(0, redirects.size());
- private static class RelativeRedirectService implements HttpRequestHandler {
-
- public RelativeRedirectService() {
- super();
- }
-
- @Override
- public void handle(
- final ClassicHttpRequest request,
- final ClassicHttpResponse response,
- final HttpContext context) throws HttpException, IOException {
- try {
- final URI requestURI = request.getUri();
- final String path = requestURI.getPath();
- if (path.equals("/oldlocation/")) {
- response.setCode(HttpStatus.SC_MOVED_TEMPORARILY);
- response.addHeader(new BasicHeader("Location", "/relativelocation/"));
- } else if (path.equals("/relativelocation/")) {
- response.setCode(HttpStatus.SC_OK);
- final StringEntity entity = new StringEntity("Successful redirect");
- response.setEntity(entity);
- } else {
- response.setCode(HttpStatus.SC_NOT_FOUND);
- }
- } catch (final URISyntaxException ex) {
- throw new ProtocolException(ex.getMessage(), ex);
- }
- }
- }
-
- private static class RelativeRedirectService2 implements HttpRequestHandler {
-
- public RelativeRedirectService2() {
- super();
- }
-
- @Override
- public void handle(
- final ClassicHttpRequest request,
- final ClassicHttpResponse response,
- final HttpContext context) throws HttpException, IOException {
- try {
- final URI requestURI = request.getUri();
- final String path = requestURI.getPath();
- if (path.equals("/test/oldlocation")) {
- response.setCode(HttpStatus.SC_MOVED_TEMPORARILY);
- response.addHeader(new BasicHeader("Location", "relativelocation"));
- } else if (path.equals("/test/relativelocation")) {
- response.setCode(HttpStatus.SC_OK);
- final StringEntity entity = new StringEntity("Successful redirect");
- response.setEntity(entity);
- } else {
- response.setCode(HttpStatus.SC_NOT_FOUND);
- }
- } catch (final URISyntaxException ex) {
- throw new ProtocolException(ex.getMessage(), ex);
- }
- }
- }
-
- private static class RomeRedirectService implements HttpRequestHandler {
-
- public RomeRedirectService() {
- super();
- }
-
- @Override
- public void handle(
- final ClassicHttpRequest request,
- final ClassicHttpResponse response,
- final HttpContext context) throws HttpException, IOException {
- try {
- final URI requestURI = request.getUri();
- final String path = requestURI.getPath();
- if (path.equals("/rome")) {
- response.setCode(HttpStatus.SC_OK);
- final StringEntity entity = new StringEntity("Successful redirect");
- response.setEntity(entity);
- } else {
- response.setCode(HttpStatus.SC_MOVED_TEMPORARILY);
- response.addHeader(new BasicHeader("Location", "/rome"));
- }
- } catch (final URISyntaxException ex) {
- throw new ProtocolException(ex.getMessage(), ex);
- }
- }
- }
-
- interface UriTransformation {
-
- String rewrite(URI requestUri);
-
- }
-
- private static class TransformingRedirectService implements HttpRequestHandler {
-
- private final UriTransformation uriTransformation;
-
- public TransformingRedirectService(final UriTransformation uriTransformation) {
- super();
- this.uriTransformation = uriTransformation;
- }
-
- @Override
- public void handle(
- final ClassicHttpRequest request,
- final ClassicHttpResponse response,
- final HttpContext context) throws HttpException, IOException {
- try {
- final URI requestURI = request.getUri();
- final String path = requestURI.getPath();
- if (path.equals("/oldlocation/")) {
- response.setCode(HttpStatus.SC_MOVED_TEMPORARILY);
- response.addHeader(new BasicHeader("Location", uriTransformation.rewrite(requestURI)));
- } else if (path.equals("/relativelocation/")) {
- response.setCode(HttpStatus.SC_OK);
- final StringEntity entity = new StringEntity("Successful redirect");
- response.setEntity(entity);
- } else {
- response.setCode(HttpStatus.SC_NOT_FOUND);
- }
- } catch (final URISyntaxException ex) {
- throw new ProtocolException(ex.getMessage(), ex);
- }
+ EntityUtils.consume(response.getEntity());
}
}
@Test
- public void testBasicRedirect300() throws Exception {
- this.server.registerHandler("*", new BasicRedirectService(HttpStatus.SC_MULTIPLE_CHOICES));
+ public void testBasicRedirect300NoKeepAlive() throws Exception {
+ final HttpHost target = start(null, new Decorator() {
- final HttpHost target = start();
+ @Override
+ public HttpServerRequestHandler decorate(final HttpServerRequestHandler requestHandler) {
+ return new RedirectingDecorator(
+ requestHandler,
+ new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MULTIPLE_CHOICES,
+ Redirect.ConnControl.CLOSE));
+ }
+
+ });
final HttpClientContext context = HttpClientContext.create();
+ final HttpGet httpget = new HttpGet("/oldlocation/100");
+ try (final ClassicHttpResponse response = this.httpclient.execute(target, httpget, context)) {
+ final HttpRequest reqWrapper = context.getRequest();
- final HttpGet httpget = new HttpGet("/oldlocation/");
+ Assert.assertEquals(HttpStatus.SC_MULTIPLE_CHOICES, response.getCode());
+ Assert.assertEquals(URIUtils.create(target, "/oldlocation/100"), reqWrapper.getUri());
- final ClassicHttpResponse response = this.httpclient.execute(target, httpget, context);
- EntityUtils.consume(response.getEntity());
+ final RedirectLocations redirects = context.getRedirectLocations();
+ Assert.assertNotNull(redirects);
+ Assert.assertEquals(0, redirects.size());
- final HttpRequest reqWrapper = context.getRequest();
-
- Assert.assertEquals(HttpStatus.SC_MULTIPLE_CHOICES, response.getCode());
- Assert.assertEquals(URIUtils.create(target, "/oldlocation/"), reqWrapper.getUri());
-
- final RedirectLocations redirects = context.getRedirectLocations();
- Assert.assertNotNull(redirects);
- Assert.assertEquals(0, redirects.size());
+ EntityUtils.consume(response.getEntity());
+ }
}
@Test
public void testBasicRedirect301() throws Exception {
- this.server.registerHandler("*", new BasicRedirectService(HttpStatus.SC_MOVED_PERMANENTLY));
+ final HttpHost target = start(null, new Decorator() {
- final HttpHost target = start();
+ @Override
+ public HttpServerRequestHandler decorate(final HttpServerRequestHandler requestHandler) {
+ return new RedirectingDecorator(
+ requestHandler,
+ new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_PERMANENTLY));
+ }
+
+ });
final HttpClientContext context = HttpClientContext.create();
- final HttpGet httpget = new HttpGet("/oldlocation/");
+ final HttpGet httpget = new HttpGet("/oldlocation/100");
- final ClassicHttpResponse response = this.httpclient.execute(target, httpget, context);
- EntityUtils.consume(response.getEntity());
+ try (final ClassicHttpResponse response = this.httpclient.execute(target, httpget, context)) {
+ final HttpRequest reqWrapper = context.getRequest();
- final HttpRequest reqWrapper = context.getRequest();
+ Assert.assertEquals(HttpStatus.SC_OK, response.getCode());
+ Assert.assertEquals(URIUtils.create(target, "/random/100"), reqWrapper.getUri());
- Assert.assertEquals(HttpStatus.SC_OK, response.getCode());
- Assert.assertEquals(URIUtils.create(target, "/newlocation/"), reqWrapper.getUri());
+ final RedirectLocations redirects = context.getRedirectLocations();
+ Assert.assertNotNull(redirects);
+ Assert.assertEquals(1, redirects.size());
- final RedirectLocations redirects = context.getRedirectLocations();
- Assert.assertNotNull(redirects);
- Assert.assertEquals(1, redirects.size());
+ final URI redirect = URIUtils.rewriteURI(new URI("/random/100"), target);
+ Assert.assertTrue(redirects.contains(redirect));
- final URI redirect = URIUtils.rewriteURI(new URI("/newlocation/"), target);
- Assert.assertTrue(redirects.contains(redirect));
+ EntityUtils.consume(response.getEntity());
+ }
}
@Test
public void testBasicRedirect302() throws Exception {
- this.server.registerHandler("*", new BasicRedirectService(HttpStatus.SC_MOVED_TEMPORARILY));
+ final HttpHost target = start(null, new Decorator() {
- final HttpHost target = start();
+ @Override
+ public HttpServerRequestHandler decorate(final HttpServerRequestHandler requestHandler) {
+ return new RedirectingDecorator(
+ requestHandler,
+ new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_TEMPORARILY));
+ }
+
+ });
final HttpClientContext context = HttpClientContext.create();
- final HttpGet httpget = new HttpGet("/oldlocation/");
+ final HttpGet httpget = new HttpGet("/oldlocation/50");
- final ClassicHttpResponse response = this.httpclient.execute(target, httpget, context);
- EntityUtils.consume(response.getEntity());
+ try (final ClassicHttpResponse response = this.httpclient.execute(target, httpget, context)) {
+ final HttpRequest reqWrapper = context.getRequest();
- final HttpRequest reqWrapper = context.getRequest();
+ Assert.assertEquals(HttpStatus.SC_OK, response.getCode());
+ Assert.assertEquals(URIUtils.create(target, "/random/50"), reqWrapper.getUri());
- Assert.assertEquals(HttpStatus.SC_OK, response.getCode());
- Assert.assertEquals(URIUtils.create(target, "/newlocation/"), reqWrapper.getUri());
+ EntityUtils.consume(response.getEntity());
+ }
}
@Test
public void testBasicRedirect302NoLocation() throws Exception {
- this.server.registerHandler("*", new HttpRequestHandler() {
+ final HttpHost target = start(null, new Decorator() {
@Override
- public void handle(
- final ClassicHttpRequest request,
- final ClassicHttpResponse response,
- final HttpContext context) throws HttpException, IOException {
- response.setCode(HttpStatus.SC_MOVED_TEMPORARILY);
+ public HttpServerRequestHandler decorate(final HttpServerRequestHandler requestHandler) {
+ return new RedirectingDecorator(
+ requestHandler,
+ new RedirectResolver() {
+
+ @Override
+ public Redirect resolve(final URI requestUri) throws URISyntaxException {
+ final String path = requestUri.getPath();
+ if (path.startsWith("/oldlocation")) {
+ return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, null);
+ }
+ return null;
+ }
+
+ });
+ }
+
+ });
+
+ final HttpClientContext context = HttpClientContext.create();
+
+ final HttpGet httpget = new HttpGet("/oldlocation/100");
+
+ try (final ClassicHttpResponse response = this.httpclient.execute(target, httpget, context)) {
+ final HttpRequest reqWrapper = context.getRequest();
+
+ Assert.assertEquals(HttpStatus.SC_MOVED_TEMPORARILY, response.getCode());
+ Assert.assertEquals("/oldlocation/100", reqWrapper.getRequestUri());
+
+ EntityUtils.consume(response.getEntity());
+ }
+ }
+
+ @Test
+ public void testBasicRedirect303() throws Exception {
+ final HttpHost target = start(null, new Decorator() {
+
+ @Override
+ public HttpServerRequestHandler decorate(final HttpServerRequestHandler requestHandler) {
+ return new RedirectingDecorator(
+ requestHandler,
+ new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_SEE_OTHER));
+ }
+
+ });
+
+ final HttpClientContext context = HttpClientContext.create();
+
+ final HttpGet httpget = new HttpGet("/oldlocation/123");
+
+ try (final ClassicHttpResponse response = this.httpclient.execute(target, httpget, context)) {
+ final HttpRequest reqWrapper = context.getRequest();
+
+ Assert.assertEquals(HttpStatus.SC_OK, response.getCode());
+ Assert.assertEquals(URIUtils.create(target, "/random/123"), reqWrapper.getUri());
+
+ EntityUtils.consume(response.getEntity());
+ }
+ }
+
+ @Test
+ public void testBasicRedirect304() throws Exception {
+ this.server.registerHandler("/oldlocation/*", new HttpRequestHandler() {
+
+ @Override
+ public void handle(final ClassicHttpRequest request,
+ final ClassicHttpResponse response,
+ final HttpContext context) throws HttpException, IOException {
+ response.setCode(HttpStatus.SC_NOT_MODIFIED);
+ response.addHeader(HttpHeaders.LOCATION, "/random/100");
}
});
@@ -350,104 +274,103 @@ public class TestRedirects extends LocalServerTestBase {
final HttpClientContext context = HttpClientContext.create();
- final HttpGet httpget = new HttpGet("/oldlocation/");
+ final HttpGet httpget = new HttpGet("/oldlocation/stuff");
- final ClassicHttpResponse response = this.httpclient.execute(target, httpget, context);
- EntityUtils.consume(response.getEntity());
+ try (final ClassicHttpResponse response = this.httpclient.execute(target, httpget, context)) {
+ final HttpRequest reqWrapper = context.getRequest();
- final HttpRequest reqWrapper = context.getRequest();
+ Assert.assertEquals(HttpStatus.SC_NOT_MODIFIED, response.getCode());
+ Assert.assertEquals(URIUtils.create(target, "/oldlocation/stuff"), reqWrapper.getUri());
- Assert.assertEquals(HttpStatus.SC_MOVED_TEMPORARILY, response.getCode());
- Assert.assertEquals("/oldlocation/", reqWrapper.getRequestUri());
- }
+ final RedirectLocations redirects = context.getRedirectLocations();
+ Assert.assertNotNull(redirects);
+ Assert.assertEquals(0, redirects.size());
- @Test
- public void testBasicRedirect303() throws Exception {
- this.server.registerHandler("*", new BasicRedirectService(HttpStatus.SC_SEE_OTHER));
-
- final HttpHost target = start();
-
- final HttpClientContext context = HttpClientContext.create();
-
- final HttpGet httpget = new HttpGet("/oldlocation/");
-
- final ClassicHttpResponse response = this.httpclient.execute(target, httpget, context);
- EntityUtils.consume(response.getEntity());
-
- final HttpRequest reqWrapper = context.getRequest();
-
- Assert.assertEquals(HttpStatus.SC_OK, response.getCode());
- Assert.assertEquals(URIUtils.create(target, "/newlocation/"), reqWrapper.getUri());
- }
-
- @Test
- public void testBasicRedirect304() throws Exception {
- this.server.registerHandler("*", new BasicRedirectService(HttpStatus.SC_NOT_MODIFIED));
-
- final HttpHost target = start();
-
- final HttpClientContext context = HttpClientContext.create();
-
- final HttpGet httpget = new HttpGet("/oldlocation/");
-
- final ClassicHttpResponse response = this.httpclient.execute(target, httpget, context);
- EntityUtils.consume(response.getEntity());
-
- final HttpRequest reqWrapper = context.getRequest();
-
- Assert.assertEquals(HttpStatus.SC_NOT_MODIFIED, response.getCode());
- Assert.assertEquals(URIUtils.create(target, "/oldlocation/"), reqWrapper.getUri());
+ EntityUtils.consume(response.getEntity());
+ }
}
@Test
public void testBasicRedirect305() throws Exception {
- this.server.registerHandler("*", new BasicRedirectService(HttpStatus.SC_USE_PROXY));
+ this.server.registerHandler("/oldlocation/*", new HttpRequestHandler() {
+
+ @Override
+ public void handle(final ClassicHttpRequest request,
+ final ClassicHttpResponse response,
+ final HttpContext context) throws HttpException, IOException {
+ response.setCode(HttpStatus.SC_USE_PROXY);
+ response.addHeader(HttpHeaders.LOCATION, "/random/100");
+ }
+
+ });
+
final HttpHost target = start();
final HttpClientContext context = HttpClientContext.create();
- final HttpGet httpget = new HttpGet("/oldlocation/");
+ final HttpGet httpget = new HttpGet("/oldlocation/stuff");
- final ClassicHttpResponse response = this.httpclient.execute(target, httpget, context);
- EntityUtils.consume(response.getEntity());
+ try (final ClassicHttpResponse response = this.httpclient.execute(target, httpget, context)) {
+ final HttpRequest reqWrapper = context.getRequest();
- final HttpRequest reqWrapper = context.getRequest();
+ Assert.assertEquals(HttpStatus.SC_USE_PROXY, response.getCode());
+ Assert.assertEquals(URIUtils.create(target, "/oldlocation/stuff"), reqWrapper.getUri());
- Assert.assertEquals(HttpStatus.SC_USE_PROXY, response.getCode());
- Assert.assertEquals(URIUtils.create(target, "/oldlocation/"), reqWrapper.getUri());
+ final RedirectLocations redirects = context.getRedirectLocations();
+ Assert.assertNotNull(redirects);
+ Assert.assertEquals(0, redirects.size());
+
+ EntityUtils.consume(response.getEntity());
+ }
}
@Test
public void testBasicRedirect307() throws Exception {
- this.server.registerHandler("*", new BasicRedirectService(HttpStatus.SC_TEMPORARY_REDIRECT));
+ final HttpHost target = start(null, new Decorator() {
- final HttpHost target = start();
+ @Override
+ public HttpServerRequestHandler decorate(final HttpServerRequestHandler requestHandler) {
+ return new RedirectingDecorator(
+ requestHandler,
+ new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_TEMPORARY_REDIRECT));
+ }
+
+ });
final HttpClientContext context = HttpClientContext.create();
- final HttpGet httpget = new HttpGet("/oldlocation/");
+ final HttpGet httpget = new HttpGet("/oldlocation/123");
- final ClassicHttpResponse response = this.httpclient.execute(target, httpget, context);
- EntityUtils.consume(response.getEntity());
+ try (final ClassicHttpResponse response = this.httpclient.execute(target, httpget, context)) {
+ final HttpRequest reqWrapper = context.getRequest();
- final HttpRequest reqWrapper = context.getRequest();
+ Assert.assertEquals(HttpStatus.SC_OK, response.getCode());
+ Assert.assertEquals(URIUtils.create(target, "/random/123"), reqWrapper.getUri());
- Assert.assertEquals(HttpStatus.SC_OK, response.getCode());
- Assert.assertEquals(URIUtils.create(target, "/newlocation/"), reqWrapper.getUri());
+ EntityUtils.consume(response.getEntity());
+ }
}
- @Test(expected=ClientProtocolException.class)
+ @Test(expected = ClientProtocolException.class)
public void testMaxRedirectCheck() throws Exception {
- this.server.registerHandler("*", new CircularRedirectService());
+ final HttpHost target = start(null, new Decorator() {
- final HttpHost target = start();
+ @Override
+ public HttpServerRequestHandler decorate(final HttpServerRequestHandler requestHandler) {
+ return new RedirectingDecorator(
+ requestHandler,
+ new OldPathRedirectResolver("/circular-oldlocation/", "/circular-oldlocation/",
+ HttpStatus.SC_MOVED_TEMPORARILY));
+ }
+
+ });
final RequestConfig config = RequestConfig.custom()
- .setCircularRedirectsAllowed(true)
- .setMaxRedirects(5)
- .build();
+ .setCircularRedirectsAllowed(true)
+ .setMaxRedirects(5)
+ .build();
- final HttpGet httpget = new HttpGet("/circular-oldlocation/");
+ final HttpGet httpget = new HttpGet("/circular-oldlocation/123");
httpget.setConfig(config);
try {
this.httpclient.execute(target, httpget);
@@ -457,17 +380,25 @@ public class TestRedirects extends LocalServerTestBase {
}
}
- @Test(expected=ClientProtocolException.class)
+ @Test(expected = ClientProtocolException.class)
public void testCircularRedirect() throws Exception {
- this.server.registerHandler("*", new CircularRedirectService());
+ final HttpHost target = start(null, new Decorator() {
- final HttpHost target = start();
+ @Override
+ public HttpServerRequestHandler decorate(final HttpServerRequestHandler requestHandler) {
+ return new RedirectingDecorator(
+ requestHandler,
+ new OldPathRedirectResolver("/circular-oldlocation/", "/circular-oldlocation/",
+ HttpStatus.SC_MOVED_TEMPORARILY));
+ }
+
+ });
final RequestConfig config = RequestConfig.custom()
- .setCircularRedirectsAllowed(false)
- .build();
+ .setCircularRedirectsAllowed(false)
+ .build();
- final HttpGet httpget = new HttpGet("/circular-oldlocation/");
+ final HttpGet httpget = new HttpGet("/circular-oldlocation/123");
httpget.setConfig(config);
try {
this.httpclient.execute(target, httpget);
@@ -477,149 +408,140 @@ public class TestRedirects extends LocalServerTestBase {
}
}
- @Test
- public void testRepeatRequest() throws Exception {
- this.server.registerHandler("*", new RomeRedirectService());
-
- final HttpHost target = start();
-
- final HttpClientContext context = HttpClientContext.create();
-
- final HttpGet first = new HttpGet("/rome");
-
- EntityUtils.consume(this.httpclient.execute(target, first, context).getEntity());
-
- final HttpGet second = new HttpGet("/rome");
-
- final ClassicHttpResponse response = this.httpclient.execute(target, second, context);
- EntityUtils.consume(response.getEntity());
-
- final HttpRequest reqWrapper = context.getRequest();
-
- Assert.assertEquals(HttpStatus.SC_OK, response.getCode());
- Assert.assertEquals(URIUtils.create(target, "/rome"), reqWrapper.getUri());
- }
-
- @Test
- public void testRepeatRequestRedirect() throws Exception {
- this.server.registerHandler("*", new RomeRedirectService());
-
- final HttpHost target = start();
-
- final HttpClientContext context = HttpClientContext.create();
-
- final HttpGet first = new HttpGet("/lille");
- final ClassicHttpResponse response1 = this.httpclient.execute(target, first, context);
- EntityUtils.consume(response1.getEntity());
-
- final HttpGet second = new HttpGet("/lille");
-
- final ClassicHttpResponse response2 = this.httpclient.execute(target, second, context);
- EntityUtils.consume(response2.getEntity());
-
- final HttpRequest reqWrapper = context.getRequest();
-
- Assert.assertEquals(HttpStatus.SC_OK, response2.getCode());
- Assert.assertEquals(URIUtils.create(target, "/rome"), reqWrapper.getUri());
- }
-
- @Test
- public void testDifferentRequestSameRedirect() throws Exception {
- this.server.registerHandler("*", new RomeRedirectService());
-
- final HttpHost target = start();
-
- final HttpClientContext context = HttpClientContext.create();
-
- final HttpGet first = new HttpGet("/alian");
-
- final ClassicHttpResponse response1 = this.httpclient.execute(target, first, context);
- EntityUtils.consume(response1.getEntity());
-
- final HttpGet second = new HttpGet("/lille");
-
- final ClassicHttpResponse response2 = this.httpclient.execute(target, second, context);
- EntityUtils.consume(response2.getEntity());
-
- final HttpRequest reqWrapper = context.getRequest();
-
- Assert.assertEquals(HttpStatus.SC_OK, response2.getCode());
- Assert.assertEquals(URIUtils.create(target, "/rome"), reqWrapper.getUri());
- }
-
@Test
public void testPostRedirectSeeOther() throws Exception {
- this.server.registerHandler("*", new BasicRedirectService(HttpStatus.SC_SEE_OTHER));
+ final HttpHost target = start(null, new Decorator() {
- final HttpHost target = start();
+ @Override
+ public HttpServerRequestHandler decorate(final HttpServerRequestHandler requestHandler) {
+ return new RedirectingDecorator(
+ requestHandler,
+ new OldPathRedirectResolver("/oldlocation", "/echo", HttpStatus.SC_SEE_OTHER));
+ }
+
+ });
final HttpClientContext context = HttpClientContext.create();
- final HttpPost httppost = new HttpPost("/oldlocation/");
+ final HttpPost httppost = new HttpPost("/oldlocation/stuff");
httppost.setEntity(new StringEntity("stuff"));
- final ClassicHttpResponse response = this.httpclient.execute(target, httppost, context);
- EntityUtils.consume(response.getEntity());
+ try (final ClassicHttpResponse response = this.httpclient.execute(target, httppost, context)) {
+ final HttpRequest reqWrapper = context.getRequest();
- final HttpRequest reqWrapper = context.getRequest();
+ Assert.assertEquals(HttpStatus.SC_OK, response.getCode());
+ Assert.assertEquals(URIUtils.create(target, "/echo/stuff"), reqWrapper.getUri());
+ Assert.assertEquals("GET", reqWrapper.getMethod());
+
+ EntityUtils.consume(response.getEntity());
+ }
- Assert.assertEquals(HttpStatus.SC_OK, response.getCode());
- Assert.assertEquals(URIUtils.create(target, "/newlocation/"), reqWrapper.getUri());
- Assert.assertEquals("GET", reqWrapper.getMethod());
}
@Test
public void testRelativeRedirect() throws Exception {
- this.server.registerHandler("*", new RelativeRedirectService());
+ final HttpHost target = start(null, new Decorator() {
- final HttpHost target = start();
+ @Override
+ public HttpServerRequestHandler decorate(final HttpServerRequestHandler requestHandler) {
+ return new RedirectingDecorator(
+ requestHandler,
+ new RedirectResolver() {
+ @Override
+ public Redirect resolve(final URI requestUri) throws URISyntaxException {
+ final String path = requestUri.getPath();
+ if (path.startsWith("/oldlocation")) {
+ return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, "/random/100");
+
+ }
+ return null;
+ }
+
+ });
+ }
+
+ });
final HttpClientContext context = HttpClientContext.create();
- final HttpGet httpget = new HttpGet("/oldlocation/");
+ final HttpGet httpget = new HttpGet("/oldlocation/stuff");
- final ClassicHttpResponse response = this.httpclient.execute(target, httpget, context);
- EntityUtils.consume(response.getEntity());
+ try (final ClassicHttpResponse response = this.httpclient.execute(target, httpget, context)) {
+ final HttpRequest reqWrapper = context.getRequest();
- final HttpRequest reqWrapper = context.getRequest();
+ Assert.assertEquals(HttpStatus.SC_OK, response.getCode());
+ Assert.assertEquals(URIUtils.create(target, "/random/100"), reqWrapper.getUri());
- Assert.assertEquals(HttpStatus.SC_OK, response.getCode());
- Assert.assertEquals(URIUtils.create(target, "/relativelocation/"), reqWrapper.getUri());
+ EntityUtils.consume(response.getEntity());
+ }
}
@Test
public void testRelativeRedirect2() throws Exception {
- this.server.registerHandler("*", new RelativeRedirectService2());
+ final HttpHost target = start(null, new Decorator() {
- final HttpHost target = start();
+ @Override
+ public HttpServerRequestHandler decorate(final HttpServerRequestHandler requestHandler) {
+ return new RedirectingDecorator(
+ requestHandler,
+ new RedirectResolver() {
+
+ @Override
+ public Redirect resolve(final URI requestUri) throws URISyntaxException {
+ final String path = requestUri.getPath();
+ if (path.equals("/random/oldlocation")) {
+ return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, "100");
+
+ }
+ return null;
+ }
+
+ });
+ }
+
+ });
final HttpClientContext context = HttpClientContext.create();
- final HttpGet httpget = new HttpGet("/test/oldlocation");
+ final HttpGet httpget = new HttpGet("/random/oldlocation");
- final ClassicHttpResponse response = this.httpclient.execute(target, httpget, context);
- EntityUtils.consume(response.getEntity());
+ try (final ClassicHttpResponse response = this.httpclient.execute(target, httpget, context)) {
+ final HttpRequest reqWrapper = context.getRequest();
- final HttpRequest reqWrapper = context.getRequest();
+ Assert.assertEquals(HttpStatus.SC_OK, response.getCode());
+ Assert.assertEquals(URIUtils.create(target, "/random/100"), reqWrapper.getUri());
+
+ EntityUtils.consume(response.getEntity());
+ }
- Assert.assertEquals(HttpStatus.SC_OK, response.getCode());
- Assert.assertEquals(URIUtils.create(target, "/test/relativelocation"), reqWrapper.getUri());
}
- @Test(expected=ClientProtocolException.class)
+ @Test(expected = ClientProtocolException.class)
public void testRejectBogusRedirectLocation() throws Exception {
- this.server.registerHandler("*", new TransformingRedirectService(new UriTransformation() {
+ final HttpHost target = start(null, new Decorator() {
@Override
- public String rewrite(final URI requestUri) {
- return "xxx://bogus";
+ public HttpServerRequestHandler decorate(final HttpServerRequestHandler requestHandler) {
+ return new RedirectingDecorator(
+ requestHandler,
+ new RedirectResolver() {
+
+ @Override
+ public Redirect resolve(final URI requestUri) throws URISyntaxException {
+ final String path = requestUri.getPath();
+ if (path.equals("/oldlocation")) {
+ return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, "xxx://bogus");
+
+ }
+ return null;
+ }
+
+ });
}
- }));
+ });
- final HttpHost target = start();
-
- final HttpGet httpget = new HttpGet("/oldlocation/");
+ final HttpGet httpget = new HttpGet("/oldlocation");
try {
this.httpclient.execute(target, httpget);
@@ -630,19 +552,32 @@ public class TestRedirects extends LocalServerTestBase {
}
}
- @Test(expected=ClientProtocolException.class)
+ @Test(expected = ClientProtocolException.class)
public void testRejectInvalidRedirectLocation() throws Exception {
- this.server.registerHandler("*", new TransformingRedirectService(new UriTransformation() {
+ final HttpHost target = start(null, new Decorator() {
@Override
- public String rewrite(final URI requestUri) {
- return "/newlocation/?p=I have spaces";
+ public HttpServerRequestHandler decorate(final HttpServerRequestHandler requestHandler) {
+ return new RedirectingDecorator(
+ requestHandler,
+ new RedirectResolver() {
+
+ @Override
+ public Redirect resolve(final URI requestUri) throws URISyntaxException {
+ final String path = requestUri.getPath();
+ if (path.equals("/oldlocation")) {
+ return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, "/newlocation/?p=I have spaces");
+
+ }
+ return null;
+ }
+
+ });
}
- }));
- final HttpHost target = start();
+ });
- final HttpGet httpget = new HttpGet("/oldlocation/");
+ final HttpGet httpget = new HttpGet("/oldlocation");
try {
this.httpclient.execute(target, httpget);
@@ -654,9 +589,16 @@ public class TestRedirects extends LocalServerTestBase {
@Test
public void testRedirectWithCookie() throws Exception {
- this.server.registerHandler("*", new BasicRedirectService());
+ final HttpHost target = start(null, new Decorator() {
- final HttpHost target = start();
+ @Override
+ public HttpServerRequestHandler decorate(final HttpServerRequestHandler requestHandler) {
+ return new RedirectingDecorator(
+ requestHandler,
+ new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_TEMPORARILY));
+ }
+
+ });
final CookieStore cookieStore = new BasicCookieStore();
@@ -668,43 +610,51 @@ public class TestRedirects extends LocalServerTestBase {
final HttpClientContext context = HttpClientContext.create();
context.setCookieStore(cookieStore);
- final HttpGet httpget = new HttpGet("/oldlocation/");
+ final HttpGet httpget = new HttpGet("/oldlocation/100");
- final ClassicHttpResponse response = this.httpclient.execute(target, httpget, context);
- EntityUtils.consume(response.getEntity());
+ try (final ClassicHttpResponse response = this.httpclient.execute(target, httpget, context)) {
+ final HttpRequest reqWrapper = context.getRequest();
- final HttpRequest reqWrapper = context.getRequest();
+ Assert.assertEquals(HttpStatus.SC_OK, response.getCode());
+ Assert.assertEquals(URIUtils.create(target, "/random/100"), reqWrapper.getUri());
- Assert.assertEquals(HttpStatus.SC_OK, response.getCode());
- Assert.assertEquals(URIUtils.create(target, "/newlocation/"), reqWrapper.getUri());
+ final Header[] headers = reqWrapper.getHeaders("Cookie");
+ Assert.assertEquals("There can only be one (cookie)", 1, headers.length);
- final Header[] headers = reqWrapper.getHeaders("Cookie");
- Assert.assertEquals("There can only be one (cookie)", 1, headers.length);
+ EntityUtils.consume(response.getEntity());
+ }
}
@Test
public void testDefaultHeadersRedirect() throws Exception {
this.clientBuilder.setDefaultHeaders(Arrays.asList(new BasicHeader(HttpHeaders.USER_AGENT, "my-test-client")));
- this.server.registerHandler("*", new BasicRedirectService());
+ final HttpHost target = start(null, new Decorator() {
- final HttpHost target = start();
+ @Override
+ public HttpServerRequestHandler decorate(final HttpServerRequestHandler requestHandler) {
+ return new RedirectingDecorator(
+ requestHandler,
+ new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_TEMPORARILY));
+ }
+
+ });
final HttpClientContext context = HttpClientContext.create();
- final HttpGet httpget = new HttpGet("/oldlocation/");
+ final HttpGet httpget = new HttpGet("/oldlocation/100");
+ try (final ClassicHttpResponse response = this.httpclient.execute(target, httpget, context)) {
+ final HttpRequest reqWrapper = context.getRequest();
- final ClassicHttpResponse response = this.httpclient.execute(target, httpget, context);
- EntityUtils.consume(response.getEntity());
+ Assert.assertEquals(HttpStatus.SC_OK, response.getCode());
+ Assert.assertEquals(URIUtils.create(target, "/random/100"), reqWrapper.getUri());
- final HttpRequest reqWrapper = context.getRequest();
+ final Header header = reqWrapper.getFirstHeader(HttpHeaders.USER_AGENT);
+ Assert.assertEquals("my-test-client", header.getValue());
- Assert.assertEquals(HttpStatus.SC_OK, response.getCode());
- Assert.assertEquals(URIUtils.create(target, "/newlocation/"), reqWrapper.getUri());
-
- final Header header = reqWrapper.getFirstHeader(HttpHeaders.USER_AGENT);
- Assert.assertEquals("my-test-client", header.getValue());
+ EntityUtils.consume(response.getEntity());
+ }
}
}