Rewrite of redirect integration test cases
This commit is contained in:
parent
ffa0530bb2
commit
1928f8db40
|
@ -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
|
||||||
|
* <http://www.apache.org/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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
|
||||||
|
* <http://www.apache.org/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
|
||||||
|
* <http://www.apache.org/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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
|
||||||
|
* <http://www.apache.org/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.apache.hc.client5.testing.redirect;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
|
||||||
|
public interface RedirectResolver {
|
||||||
|
|
||||||
|
Redirect resolve(URI requestUri) throws URISyntaxException;
|
||||||
|
|
||||||
|
}
|
|
@ -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
|
||||||
|
* <http://www.apache.org/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -29,8 +29,6 @@ package org.apache.hc.client5.testing.async;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import java.util.Queue;
|
|
||||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.Future;
|
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.async.CloseableHttpAsyncClient;
|
||||||
import org.apache.hc.client5.http.impl.cookie.BasicClientCookie;
|
import org.apache.hc.client5.http.impl.cookie.BasicClientCookie;
|
||||||
import org.apache.hc.client5.http.protocol.HttpClientContext;
|
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.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.function.Supplier;
|
||||||
import org.apache.hc.core5.http.ContentType;
|
import org.apache.hc.core5.http.ContentType;
|
||||||
import org.apache.hc.core5.http.Header;
|
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.ProtocolException;
|
||||||
import org.apache.hc.core5.http.URIScheme;
|
import org.apache.hc.core5.http.URIScheme;
|
||||||
import org.apache.hc.core5.http.config.Http1Config;
|
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.nio.AsyncServerExchangeHandler;
|
||||||
import org.apache.hc.core5.http.protocol.HttpCoreContext;
|
import org.apache.hc.core5.http.protocol.HttpCoreContext;
|
||||||
import org.apache.hc.core5.http2.config.H2Config;
|
import org.apache.hc.core5.http2.config.H2Config;
|
||||||
import org.apache.hc.core5.net.URIBuilder;
|
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.IOReactorConfig;
|
||||||
import org.apache.hc.core5.reactor.ListenerEndpoint;
|
|
||||||
import org.apache.hc.core5.testing.nio.H2TestServer;
|
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.apache.hc.core5.util.TimeValue;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
@ -88,132 +90,26 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static class BasicRedirectService extends AbstractSimpleServerExchangeHandler {
|
public final HttpHost start(final Decorator<AsyncServerExchangeHandler> exchangeHandlerDecorator) throws Exception {
|
||||||
|
if (version.greaterEquals(HttpVersion.HTTP_2)) {
|
||||||
private final int statuscode;
|
return super.start(null, exchangeHandlerDecorator, H2Config.DEFAULT);
|
||||||
|
} else {
|
||||||
public BasicRedirectService(final int statuscode) {
|
return super.start(null, exchangeHandlerDecorator, Http1Config.DEFAULT);
|
||||||
super();
|
|
||||||
this.statuscode = statuscode;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@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
|
@Test
|
||||||
public void testBasicRedirect300() throws Exception {
|
public void testBasicRedirect300() throws Exception {
|
||||||
server.register("*", new Supplier<AsyncServerExchangeHandler>() {
|
final HttpHost target = start(new Decorator<AsyncServerExchangeHandler>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AsyncServerExchangeHandler get() {
|
public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
|
||||||
return new BasicRedirectService(HttpStatus.SC_MULTIPLE_CHOICES);
|
return new RedirectingAsyncDecorator(
|
||||||
|
exchangeHandler,
|
||||||
|
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MULTIPLE_CHOICES));
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
final HttpHost target = start();
|
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
final Future<SimpleHttpResponse> future = httpclient.execute(
|
final Future<SimpleHttpResponse> future = httpclient.execute(
|
||||||
|
@ -229,117 +125,131 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicRedirect301() throws Exception {
|
public void testBasicRedirect301() throws Exception {
|
||||||
server.register("*", new Supplier<AsyncServerExchangeHandler>() {
|
final HttpHost target = start(new Decorator<AsyncServerExchangeHandler>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AsyncServerExchangeHandler get() {
|
public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
|
||||||
return new BasicRedirectService(HttpStatus.SC_MOVED_PERMANENTLY);
|
return new RedirectingAsyncDecorator(
|
||||||
|
exchangeHandler,
|
||||||
|
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_PERMANENTLY));
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
final HttpHost target = start();
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
final Future<SimpleHttpResponse> future = httpclient.execute(
|
final Future<SimpleHttpResponse> future = httpclient.execute(
|
||||||
SimpleHttpRequests.get(target, "/oldlocation/"), context, null);
|
SimpleHttpRequests.get(target, "/oldlocation/100"), context, null);
|
||||||
final HttpResponse response = future.get();
|
final HttpResponse response = future.get();
|
||||||
Assert.assertNotNull(response);
|
Assert.assertNotNull(response);
|
||||||
|
|
||||||
final HttpRequest request = context.getRequest();
|
final HttpRequest request = context.getRequest();
|
||||||
|
|
||||||
Assert.assertEquals(HttpStatus.SC_OK, response.getCode());
|
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()));
|
Assert.assertEquals(target, new HttpHost(request.getScheme(), request.getAuthority()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicRedirect302() throws Exception {
|
public void testBasicRedirect302() throws Exception {
|
||||||
server.register("*", new Supplier<AsyncServerExchangeHandler>() {
|
final HttpHost target = start(new Decorator<AsyncServerExchangeHandler>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AsyncServerExchangeHandler get() {
|
public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
|
||||||
return new BasicRedirectService(HttpStatus.SC_MOVED_TEMPORARILY);
|
return new RedirectingAsyncDecorator(
|
||||||
|
exchangeHandler,
|
||||||
|
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_TEMPORARILY));
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
final HttpHost target = start();
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
final Future<SimpleHttpResponse> future = httpclient.execute(
|
final Future<SimpleHttpResponse> future = httpclient.execute(
|
||||||
SimpleHttpRequests.get(target, "/oldlocation/"), context, null);
|
SimpleHttpRequests.get(target, "/oldlocation/123"), context, null);
|
||||||
final HttpResponse response = future.get();
|
final HttpResponse response = future.get();
|
||||||
Assert.assertNotNull(response);
|
Assert.assertNotNull(response);
|
||||||
|
|
||||||
final HttpRequest request = context.getRequest();
|
final HttpRequest request = context.getRequest();
|
||||||
|
|
||||||
Assert.assertEquals(HttpStatus.SC_OK, response.getCode());
|
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()));
|
Assert.assertEquals(target, new HttpHost(request.getScheme(), request.getAuthority()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicRedirect302NoLocation() throws Exception {
|
public void testBasicRedirect302NoLocation() throws Exception {
|
||||||
server.register("*", new Supplier<AsyncServerExchangeHandler>() {
|
final HttpHost target = start(new Decorator<AsyncServerExchangeHandler>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AsyncServerExchangeHandler get() {
|
public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
|
||||||
return new AbstractSimpleServerExchangeHandler() {
|
return new RedirectingAsyncDecorator(
|
||||||
|
exchangeHandler,
|
||||||
|
new RedirectResolver() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected SimpleHttpResponse handle(
|
public Redirect resolve(final URI requestUri) throws URISyntaxException {
|
||||||
final SimpleHttpRequest request, final HttpCoreContext context) throws HttpException {
|
final String path = requestUri.getPath();
|
||||||
return new SimpleHttpResponse(HttpStatus.SC_MOVED_TEMPORARILY);
|
if (path.startsWith("/oldlocation")) {
|
||||||
}
|
return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, null);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
};
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
final HttpHost target = start();
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
final Future<SimpleHttpResponse> future = httpclient.execute(
|
final Future<SimpleHttpResponse> future = httpclient.execute(
|
||||||
SimpleHttpRequests.get(target, "/oldlocation/"), context, null);
|
SimpleHttpRequests.get(target, "/oldlocation/100"), context, null);
|
||||||
final HttpResponse response = future.get();
|
final HttpResponse response = future.get();
|
||||||
Assert.assertNotNull(response);
|
Assert.assertNotNull(response);
|
||||||
|
|
||||||
final HttpRequest request = context.getRequest();
|
final HttpRequest request = context.getRequest();
|
||||||
Assert.assertEquals(HttpStatus.SC_MOVED_TEMPORARILY, response.getCode());
|
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()));
|
Assert.assertEquals(target, new HttpHost(request.getScheme(), request.getAuthority()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicRedirect303() throws Exception {
|
public void testBasicRedirect303() throws Exception {
|
||||||
server.register("*", new Supplier<AsyncServerExchangeHandler>() {
|
final HttpHost target = start(new Decorator<AsyncServerExchangeHandler>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AsyncServerExchangeHandler get() {
|
public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
|
||||||
return new BasicRedirectService(HttpStatus.SC_SEE_OTHER);
|
return new RedirectingAsyncDecorator(
|
||||||
|
exchangeHandler,
|
||||||
|
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_SEE_OTHER));
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
final HttpHost target = start();
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
final Future<SimpleHttpResponse> future = httpclient.execute(
|
final Future<SimpleHttpResponse> future = httpclient.execute(
|
||||||
SimpleHttpRequests.get(target, "/oldlocation/"), context, null);
|
SimpleHttpRequests.get(target, "/oldlocation/123"), context, null);
|
||||||
final HttpResponse response = future.get();
|
final HttpResponse response = future.get();
|
||||||
Assert.assertNotNull(response);
|
Assert.assertNotNull(response);
|
||||||
|
|
||||||
final HttpRequest request = context.getRequest();
|
final HttpRequest request = context.getRequest();
|
||||||
|
|
||||||
Assert.assertEquals(HttpStatus.SC_OK, response.getCode());
|
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()));
|
Assert.assertEquals(target, new HttpHost(request.getScheme(), request.getAuthority()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicRedirect304() throws Exception {
|
public void testBasicRedirect304() throws Exception {
|
||||||
server.register("*", new Supplier<AsyncServerExchangeHandler>() {
|
server.register("/oldlocation/*", new Supplier<AsyncServerExchangeHandler>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AsyncServerExchangeHandler get() {
|
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 HttpHost target = start();
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
|
@ -356,13 +266,21 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicRedirect305() throws Exception {
|
public void testBasicRedirect305() throws Exception {
|
||||||
server.register("*", new Supplier<AsyncServerExchangeHandler>() {
|
server.register("/oldlocation/*", new Supplier<AsyncServerExchangeHandler>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AsyncServerExchangeHandler get() {
|
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 HttpHost target = start();
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
|
@ -379,39 +297,42 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicRedirect307() throws Exception {
|
public void testBasicRedirect307() throws Exception {
|
||||||
server.register("*", new Supplier<AsyncServerExchangeHandler>() {
|
final HttpHost target = start(new Decorator<AsyncServerExchangeHandler>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AsyncServerExchangeHandler get() {
|
public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
|
||||||
return new BasicRedirectService(HttpStatus.SC_TEMPORARY_REDIRECT);
|
return new RedirectingAsyncDecorator(
|
||||||
|
exchangeHandler,
|
||||||
|
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_TEMPORARY_REDIRECT));
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
final HttpHost target = start();
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
final Future<SimpleHttpResponse> future = httpclient.execute(
|
final Future<SimpleHttpResponse> future = httpclient.execute(
|
||||||
SimpleHttpRequests.get(target, "/oldlocation/"), context, null);
|
SimpleHttpRequests.get(target, "/oldlocation/123"), context, null);
|
||||||
final HttpResponse response = future.get();
|
final HttpResponse response = future.get();
|
||||||
Assert.assertNotNull(response);
|
Assert.assertNotNull(response);
|
||||||
|
|
||||||
final HttpRequest request = context.getRequest();
|
final HttpRequest request = context.getRequest();
|
||||||
|
|
||||||
Assert.assertEquals(HttpStatus.SC_OK, response.getCode());
|
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()));
|
Assert.assertEquals(target, new HttpHost(request.getScheme(), request.getAuthority()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected=ExecutionException.class)
|
@Test(expected=ExecutionException.class)
|
||||||
public void testMaxRedirectCheck() throws Exception {
|
public void testMaxRedirectCheck() throws Exception {
|
||||||
server.register("*", new Supplier<AsyncServerExchangeHandler>() {
|
final HttpHost target = start(new Decorator<AsyncServerExchangeHandler>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AsyncServerExchangeHandler get() {
|
public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
|
||||||
return new CircularRedirectService();
|
return new RedirectingAsyncDecorator(
|
||||||
|
exchangeHandler,
|
||||||
|
new OldPathRedirectResolver("/circular-oldlocation/", "/circular-oldlocation/",
|
||||||
|
HttpStatus.SC_MOVED_TEMPORARILY));
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
final HttpHost target = start();
|
|
||||||
|
|
||||||
final RequestConfig config = RequestConfig.custom()
|
final RequestConfig config = RequestConfig.custom()
|
||||||
.setCircularRedirectsAllowed(true)
|
.setCircularRedirectsAllowed(true)
|
||||||
|
@ -429,15 +350,17 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
|
||||||
|
|
||||||
@Test(expected=ExecutionException.class)
|
@Test(expected=ExecutionException.class)
|
||||||
public void testCircularRedirect() throws Exception {
|
public void testCircularRedirect() throws Exception {
|
||||||
server.register("*", new Supplier<AsyncServerExchangeHandler>() {
|
final HttpHost target = start(new Decorator<AsyncServerExchangeHandler>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AsyncServerExchangeHandler get() {
|
public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
|
||||||
return new CircularRedirectService();
|
return new RedirectingAsyncDecorator(
|
||||||
|
exchangeHandler,
|
||||||
|
new OldPathRedirectResolver("/circular-oldlocation/", "/circular-oldlocation/",
|
||||||
|
HttpStatus.SC_MOVED_TEMPORARILY));
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
final HttpHost target = start();
|
|
||||||
|
|
||||||
final RequestConfig config = RequestConfig.custom()
|
final RequestConfig config = RequestConfig.custom()
|
||||||
.setCircularRedirectsAllowed(false)
|
.setCircularRedirectsAllowed(false)
|
||||||
|
@ -455,19 +378,20 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPostRedirectSeeOther() throws Exception {
|
public void testPostRedirectSeeOther() throws Exception {
|
||||||
server.register("*", new Supplier<AsyncServerExchangeHandler>() {
|
final HttpHost target = start(new Decorator<AsyncServerExchangeHandler>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AsyncServerExchangeHandler get() {
|
public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
|
||||||
return new BasicRedirectService(HttpStatus.SC_SEE_OTHER);
|
return new RedirectingAsyncDecorator(
|
||||||
|
exchangeHandler,
|
||||||
|
new OldPathRedirectResolver("/oldlocation", "/echo", HttpStatus.SC_SEE_OTHER));
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
final HttpHost target = start();
|
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
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);
|
post.setBody("stuff", ContentType.TEXT_PLAIN);
|
||||||
final Future<SimpleHttpResponse> future = httpclient.execute(post, context, null);
|
final Future<SimpleHttpResponse> future = httpclient.execute(post, context, null);
|
||||||
final HttpResponse response = future.get();
|
final HttpResponse response = future.get();
|
||||||
|
@ -476,106 +400,112 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
|
||||||
final HttpRequest request = context.getRequest();
|
final HttpRequest request = context.getRequest();
|
||||||
|
|
||||||
Assert.assertEquals(HttpStatus.SC_OK, response.getCode());
|
Assert.assertEquals(HttpStatus.SC_OK, response.getCode());
|
||||||
Assert.assertEquals("/newlocation/", request.getRequestUri());
|
Assert.assertEquals("/echo/stuff", request.getRequestUri());
|
||||||
Assert.assertEquals("GET", request.getMethod());
|
Assert.assertEquals("GET", request.getMethod());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRelativeRedirect() throws Exception {
|
public void testRelativeRedirect() throws Exception {
|
||||||
server.register("*", new Supplier<AsyncServerExchangeHandler>() {
|
final HttpHost target = start(new Decorator<AsyncServerExchangeHandler>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AsyncServerExchangeHandler get() {
|
public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
|
||||||
return new RelativeRedirectService();
|
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 HttpClientContext context = HttpClientContext.create();
|
||||||
|
|
||||||
final Future<SimpleHttpResponse> future = httpclient.execute(
|
final Future<SimpleHttpResponse> future = httpclient.execute(
|
||||||
SimpleHttpRequests.get(target, "/oldlocation/"), context, null);
|
SimpleHttpRequests.get(target, "/oldlocation/stuff"), context, null);
|
||||||
final HttpResponse response = future.get();
|
final HttpResponse response = future.get();
|
||||||
Assert.assertNotNull(response);
|
Assert.assertNotNull(response);
|
||||||
|
|
||||||
final HttpRequest request = context.getRequest();
|
final HttpRequest request = context.getRequest();
|
||||||
|
|
||||||
Assert.assertEquals(HttpStatus.SC_OK, response.getCode());
|
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()));
|
Assert.assertEquals(target, new HttpHost(request.getScheme(), request.getAuthority()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRelativeRedirect2() throws Exception {
|
public void testRelativeRedirect2() throws Exception {
|
||||||
server.register("*", new Supplier<AsyncServerExchangeHandler>() {
|
final HttpHost target = start(new Decorator<AsyncServerExchangeHandler>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AsyncServerExchangeHandler get() {
|
public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
|
||||||
return new RelativeRedirectService2();
|
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 HttpClientContext context = HttpClientContext.create();
|
||||||
|
|
||||||
final Future<SimpleHttpResponse> future = httpclient.execute(
|
final Future<SimpleHttpResponse> future = httpclient.execute(
|
||||||
SimpleHttpRequests.get(target, "/test/oldlocation"), context, null);
|
SimpleHttpRequests.get(target, "/random/oldlocation"), context, null);
|
||||||
final HttpResponse response = future.get();
|
final HttpResponse response = future.get();
|
||||||
Assert.assertNotNull(response);
|
Assert.assertNotNull(response);
|
||||||
|
|
||||||
final HttpRequest request = context.getRequest();
|
final HttpRequest request = context.getRequest();
|
||||||
|
|
||||||
Assert.assertEquals(HttpStatus.SC_OK, response.getCode());
|
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()));
|
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)
|
@Test(expected=ExecutionException.class)
|
||||||
public void testRejectBogusRedirectLocation() throws Exception {
|
public void testRejectBogusRedirectLocation() throws Exception {
|
||||||
server.register("*", new Supplier<AsyncServerExchangeHandler>() {
|
final HttpHost target = start(new Decorator<AsyncServerExchangeHandler>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AsyncServerExchangeHandler get() {
|
public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
|
||||||
return new BogusRedirectService("xxx://bogus");
|
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 {
|
try {
|
||||||
final Future<SimpleHttpResponse> future = httpclient.execute(
|
final Future<SimpleHttpResponse> future = httpclient.execute(
|
||||||
|
@ -589,15 +519,28 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
|
||||||
|
|
||||||
@Test(expected=ExecutionException.class)
|
@Test(expected=ExecutionException.class)
|
||||||
public void testRejectInvalidRedirectLocation() throws Exception {
|
public void testRejectInvalidRedirectLocation() throws Exception {
|
||||||
server.register("*", new Supplier<AsyncServerExchangeHandler>() {
|
final HttpHost target = start(new Decorator<AsyncServerExchangeHandler>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AsyncServerExchangeHandler get() {
|
public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
|
||||||
return new BogusRedirectService("/newlocation/?p=I have spaces");
|
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 {
|
try {
|
||||||
final Future<SimpleHttpResponse> future = httpclient.execute(
|
final Future<SimpleHttpResponse> future = httpclient.execute(
|
||||||
|
@ -611,15 +554,16 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRedirectWithCookie() throws Exception {
|
public void testRedirectWithCookie() throws Exception {
|
||||||
server.register("*", new Supplier<AsyncServerExchangeHandler>() {
|
final HttpHost target = start(new Decorator<AsyncServerExchangeHandler>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AsyncServerExchangeHandler get() {
|
public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
|
||||||
return new BasicRedirectService(HttpStatus.SC_MOVED_TEMPORARILY);
|
return new RedirectingAsyncDecorator(
|
||||||
|
exchangeHandler,
|
||||||
|
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_TEMPORARILY));
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
final HttpHost target = start();
|
|
||||||
|
|
||||||
final CookieStore cookieStore = new BasicCookieStore();
|
final CookieStore cookieStore = new BasicCookieStore();
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
|
@ -632,214 +576,84 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
|
||||||
cookieStore.addCookie(cookie);
|
cookieStore.addCookie(cookie);
|
||||||
|
|
||||||
final Future<SimpleHttpResponse> future = httpclient.execute(
|
final Future<SimpleHttpResponse> future = httpclient.execute(
|
||||||
SimpleHttpRequests.get(target, "/oldlocation/"), context, null);
|
SimpleHttpRequests.get(target, "/oldlocation/100"), context, null);
|
||||||
final HttpResponse response = future.get();
|
final HttpResponse response = future.get();
|
||||||
Assert.assertNotNull(response);
|
Assert.assertNotNull(response);
|
||||||
|
|
||||||
final HttpRequest request = context.getRequest();
|
final HttpRequest request = context.getRequest();
|
||||||
|
|
||||||
Assert.assertEquals(HttpStatus.SC_OK, response.getCode());
|
Assert.assertEquals(HttpStatus.SC_OK, response.getCode());
|
||||||
Assert.assertEquals("/newlocation/", request.getRequestUri());
|
Assert.assertEquals("/random/100", request.getRequestUri());
|
||||||
|
|
||||||
final Header[] headers = request.getHeaders("Cookie");
|
final Header[] headers = request.getHeaders("Cookie");
|
||||||
Assert.assertEquals("There can only be one (cookie)", 1, headers.length);
|
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
|
@Test
|
||||||
public void testCrossSiteRedirect() throws Exception {
|
public void testCrossSiteRedirect() throws Exception {
|
||||||
server.register("/random/*", new Supplier<AsyncServerExchangeHandler>() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AsyncServerExchangeHandler get() {
|
|
||||||
return new AsyncRandomHandler();
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
final HttpHost redirectTarget = start();
|
|
||||||
|
|
||||||
final H2TestServer secondServer = new H2TestServer(IOReactorConfig.DEFAULT,
|
final H2TestServer secondServer = new H2TestServer(IOReactorConfig.DEFAULT,
|
||||||
scheme == URIScheme.HTTPS ? SSLTestContexts.createServerSSLContext() : null, null, null);
|
scheme == URIScheme.HTTPS ? SSLTestContexts.createServerSSLContext() : null, null, null);
|
||||||
try {
|
try {
|
||||||
secondServer.register("/redirect/*", new Supplier<AsyncServerExchangeHandler>() {
|
secondServer.register("/random/*", new Supplier<AsyncServerExchangeHandler>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AsyncServerExchangeHandler get() {
|
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<AsyncServerExchangeHandler>() {
|
||||||
|
|
||||||
|
@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)) {
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
secondServer.start(H2Config.DEFAULT);
|
final Future<SimpleHttpResponse> future = httpclient.execute(
|
||||||
} else {
|
SimpleHttpRequests.get(target, "/oldlocation"), context, null);
|
||||||
secondServer.start(Http1Config.DEFAULT);
|
final HttpResponse response = future.get();
|
||||||
}
|
Assert.assertNotNull(response);
|
||||||
final Future<ListenerEndpoint> endpointFuture = secondServer.listen(new InetSocketAddress(0));
|
|
||||||
final ListenerEndpoint endpoint2 = endpointFuture.get();
|
|
||||||
|
|
||||||
final InetSocketAddress address2 = (InetSocketAddress) endpoint2.getAddress();
|
final HttpRequest request = context.getRequest();
|
||||||
final HttpHost initialTarget = new HttpHost(scheme.name(), "localhost", address2.getPort());
|
|
||||||
|
|
||||||
final Queue<Future<SimpleHttpResponse>> queue = new ConcurrentLinkedQueue<>();
|
Assert.assertEquals(HttpStatus.SC_OK, response.getCode());
|
||||||
for (int i = 0; i < 1; i++) {
|
Assert.assertEquals("/random/100", request.getRequestUri());
|
||||||
queue.add(httpclient.execute(SimpleHttpRequests.get(initialTarget, "/redirect/anywhere"), null));
|
Assert.assertEquals(redirectTarget, new HttpHost(request.getScheme(), request.getAuthority()));
|
||||||
}
|
|
||||||
while (!queue.isEmpty()) {
|
|
||||||
final Future<SimpleHttpResponse> future = queue.remove();
|
|
||||||
final HttpResponse response = future.get();
|
|
||||||
Assert.assertNotNull(response);
|
|
||||||
Assert.assertEquals(200, response.getCode());
|
|
||||||
}
|
|
||||||
} finally {
|
} finally {
|
||||||
server.shutdown(TimeValue.ofSeconds(5));
|
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<AsyncServerExchangeHandler>() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AsyncServerExchangeHandler get() {
|
|
||||||
return new RomeRedirectService();
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
final HttpHost target = start();
|
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
|
||||||
|
|
||||||
final Future<SimpleHttpResponse> future1 = httpclient.execute(
|
|
||||||
SimpleHttpRequests.get(target, "/rome"), context, null);
|
|
||||||
final HttpResponse response1 = future1.get();
|
|
||||||
Assert.assertNotNull(response1);
|
|
||||||
|
|
||||||
final Future<SimpleHttpResponse> 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<AsyncServerExchangeHandler>() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AsyncServerExchangeHandler get() {
|
|
||||||
return new RomeRedirectService();
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
final HttpHost target = start();
|
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
|
||||||
|
|
||||||
final Future<SimpleHttpResponse> future1 = httpclient.execute(
|
|
||||||
SimpleHttpRequests.get(target, "/lille"), context, null);
|
|
||||||
final HttpResponse response1 = future1.get();
|
|
||||||
Assert.assertNotNull(response1);
|
|
||||||
|
|
||||||
final Future<SimpleHttpResponse> 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<AsyncServerExchangeHandler>() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AsyncServerExchangeHandler get() {
|
|
||||||
return new RomeRedirectService();
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
final HttpHost target = start();
|
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
|
||||||
|
|
||||||
final Future<SimpleHttpResponse> future1 = httpclient.execute(
|
|
||||||
SimpleHttpRequests.get(target, "/alian"), context, null);
|
|
||||||
final HttpResponse response1 = future1.get();
|
|
||||||
Assert.assertNotNull(response1);
|
|
||||||
|
|
||||||
final Future<SimpleHttpResponse> 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()));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,15 +26,12 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.hc.client5.testing.async;
|
package org.apache.hc.client5.testing.async;
|
||||||
|
|
||||||
import java.net.URI;
|
|
||||||
import java.net.URISyntaxException;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.Future;
|
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.SimpleHttpRequests;
|
||||||
import org.apache.hc.client5.http.async.methods.SimpleHttpResponse;
|
import org.apache.hc.client5.http.async.methods.SimpleHttpResponse;
|
||||||
import org.apache.hc.client5.http.config.RequestConfig;
|
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.impl.nio.PoolingAsyncClientConnectionManagerBuilder;
|
||||||
import org.apache.hc.client5.http.protocol.HttpClientContext;
|
import org.apache.hc.client5.http.protocol.HttpClientContext;
|
||||||
import org.apache.hc.client5.http.ssl.DefaultClientTlsStrategy;
|
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.client5.testing.SSLTestContexts;
|
||||||
import org.apache.hc.core5.function.Supplier;
|
import org.apache.hc.client5.testing.redirect.Redirect;
|
||||||
import org.apache.hc.core5.http.ContentType;
|
import org.apache.hc.core5.function.Decorator;
|
||||||
import org.apache.hc.core5.http.Header;
|
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.HttpHeaders;
|
||||||
import org.apache.hc.core5.http.HttpHost;
|
import org.apache.hc.core5.http.HttpHost;
|
||||||
import org.apache.hc.core5.http.HttpRequest;
|
import org.apache.hc.core5.http.HttpRequest;
|
||||||
import org.apache.hc.core5.http.HttpResponse;
|
import org.apache.hc.core5.http.HttpResponse;
|
||||||
import org.apache.hc.core5.http.HttpStatus;
|
import org.apache.hc.core5.http.HttpStatus;
|
||||||
import org.apache.hc.core5.http.HttpVersion;
|
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.URIScheme;
|
||||||
import org.apache.hc.core5.http.message.BasicHeader;
|
import org.apache.hc.core5.http.message.BasicHeader;
|
||||||
import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
|
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.Assert;
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
@ -129,54 +123,19 @@ public class TestHttp1AsyncRedirects extends AbstractHttpAsyncRedirectsTest<Clos
|
||||||
return clientBuilder.build();
|
return clientBuilder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
static class NoKeepAliveRedirectService extends AbstractSimpleServerExchangeHandler {
|
|
||||||
|
|
||||||
private final int statuscode;
|
|
||||||
|
|
||||||
public NoKeepAliveRedirectService(final int statuscode) {
|
|
||||||
super();
|
|
||||||
this.statuscode = statuscode;
|
|
||||||
}
|
|
||||||
|
|
||||||
@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()));
|
|
||||||
response.addHeader(new BasicHeader("Connection", "close"));
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicRedirect300() throws Exception {
|
public void testBasicRedirect300NoKeepAlive() throws Exception {
|
||||||
server.register("*", new Supplier<AsyncServerExchangeHandler>() {
|
final HttpHost target = start(new Decorator<AsyncServerExchangeHandler>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AsyncServerExchangeHandler get() {
|
public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
|
||||||
return new NoKeepAliveRedirectService(HttpStatus.SC_MULTIPLE_CHOICES);
|
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 HttpClientContext context = HttpClientContext.create();
|
||||||
final Future<SimpleHttpResponse> future = httpclient.execute(
|
final Future<SimpleHttpResponse> future = httpclient.execute(
|
||||||
SimpleHttpRequests.get(target, "/oldlocation/"), context, null);
|
SimpleHttpRequests.get(target, "/oldlocation/"), context, null);
|
||||||
|
@ -191,57 +150,59 @@ public class TestHttp1AsyncRedirects extends AbstractHttpAsyncRedirectsTest<Clos
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicRedirect301NoKeepAlive() throws Exception {
|
public void testBasicRedirect301NoKeepAlive() throws Exception {
|
||||||
server.register("*", new Supplier<AsyncServerExchangeHandler>() {
|
final HttpHost target = start(new Decorator<AsyncServerExchangeHandler>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AsyncServerExchangeHandler get() {
|
public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
|
||||||
return new NoKeepAliveRedirectService(HttpStatus.SC_MOVED_PERMANENTLY);
|
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 HttpClientContext context = HttpClientContext.create();
|
||||||
final Future<SimpleHttpResponse> future = httpclient.execute(
|
final Future<SimpleHttpResponse> future = httpclient.execute(
|
||||||
SimpleHttpRequests.get(target, "/oldlocation/"), context, null);
|
SimpleHttpRequests.get(target, "/oldlocation/100"), context, null);
|
||||||
final HttpResponse response = future.get();
|
final HttpResponse response = future.get();
|
||||||
Assert.assertNotNull(response);
|
Assert.assertNotNull(response);
|
||||||
|
|
||||||
final HttpRequest request = context.getRequest();
|
final HttpRequest request = context.getRequest();
|
||||||
|
|
||||||
Assert.assertEquals(HttpStatus.SC_OK, response.getCode());
|
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()));
|
Assert.assertEquals(target, new HttpHost(request.getScheme(), request.getAuthority()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDefaultHeadersRedirect() throws Exception {
|
public void testDefaultHeadersRedirect() throws Exception {
|
||||||
server.register("*", new Supplier<AsyncServerExchangeHandler>() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AsyncServerExchangeHandler get() {
|
|
||||||
return new NoKeepAliveRedirectService(HttpStatus.SC_MOVED_TEMPORARILY);
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
final List<Header> defaultHeaders = new ArrayList<>(1);
|
final List<Header> defaultHeaders = new ArrayList<>(1);
|
||||||
defaultHeaders.add(new BasicHeader(HttpHeaders.USER_AGENT, "my-test-client"));
|
defaultHeaders.add(new BasicHeader(HttpHeaders.USER_AGENT, "my-test-client"));
|
||||||
clientBuilder.setDefaultHeaders(defaultHeaders);
|
clientBuilder.setDefaultHeaders(defaultHeaders);
|
||||||
|
|
||||||
final HttpHost target = start();
|
final HttpHost target = start(new Decorator<AsyncServerExchangeHandler>() {
|
||||||
|
|
||||||
|
@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 HttpClientContext context = HttpClientContext.create();
|
||||||
|
|
||||||
final Future<SimpleHttpResponse> future = httpclient.execute(
|
final Future<SimpleHttpResponse> future = httpclient.execute(
|
||||||
SimpleHttpRequests.get(target, "/oldlocation/"), context, null);
|
SimpleHttpRequests.get(target, "/oldlocation/123"), context, null);
|
||||||
final HttpResponse response = future.get();
|
final HttpResponse response = future.get();
|
||||||
Assert.assertNotNull(response);
|
Assert.assertNotNull(response);
|
||||||
|
|
||||||
final HttpRequest request = context.getRequest();
|
final HttpRequest request = context.getRequest();
|
||||||
|
|
||||||
Assert.assertEquals(HttpStatus.SC_OK, response.getCode());
|
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);
|
final Header header = request.getFirstHeader(HttpHeaders.USER_AGENT);
|
||||||
Assert.assertEquals("my-test-client", header.getValue());
|
Assert.assertEquals("my-test-client", header.getValue());
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue