Added HTTP routing support class; simplified HttpRoutePlanner API

This commit is contained in:
Oleg Kalnichevski 2018-01-03 15:36:27 +01:00
parent db4b6db79f
commit b45b72ef77
14 changed files with 159 additions and 136 deletions

View File

@ -38,6 +38,6 @@ public interface SchemePortResolver {
/** /**
* Returns the actual port for the host based on the protocol scheme. * Returns the actual port for the host based on the protocol scheme.
*/ */
int resolve(HttpHost host) throws UnsupportedSchemeException; int resolve(HttpHost host);
} }

View File

@ -27,7 +27,6 @@
package org.apache.hc.client5.http.impl; package org.apache.hc.client5.http.impl;
import org.apache.hc.client5.http.SchemePortResolver; import org.apache.hc.client5.http.SchemePortResolver;
import org.apache.hc.client5.http.UnsupportedSchemeException;
import org.apache.hc.core5.annotation.Contract; import org.apache.hc.core5.annotation.Contract;
import org.apache.hc.core5.annotation.ThreadingBehavior; import org.apache.hc.core5.annotation.ThreadingBehavior;
import org.apache.hc.core5.http.HttpHost; import org.apache.hc.core5.http.HttpHost;
@ -44,7 +43,7 @@ public class DefaultSchemePortResolver implements SchemePortResolver {
public static final DefaultSchemePortResolver INSTANCE = new DefaultSchemePortResolver(); public static final DefaultSchemePortResolver INSTANCE = new DefaultSchemePortResolver();
@Override @Override
public int resolve(final HttpHost host) throws UnsupportedSchemeException { public int resolve(final HttpHost host) {
Args.notNull(host, "HTTP host"); Args.notNull(host, "HTTP host");
final int port = host.getPort(); final int port = host.getPort();
if (port > 0) { if (port > 0) {
@ -56,7 +55,7 @@ public class DefaultSchemePortResolver implements SchemePortResolver {
} else if (name.equalsIgnoreCase("https")) { } else if (name.equalsIgnoreCase("https")) {
return 443; return 443;
} else { } else {
throw new UnsupportedSchemeException(name + " protocol is not supported"); return -1;
} }
} }

View File

@ -39,8 +39,8 @@ import org.apache.hc.client5.http.cookie.CookieSpecProvider;
import org.apache.hc.client5.http.cookie.CookieStore; import org.apache.hc.client5.http.cookie.CookieStore;
import org.apache.hc.client5.http.protocol.HttpClientContext; import org.apache.hc.client5.http.protocol.HttpClientContext;
import org.apache.hc.client5.http.routing.HttpRoutePlanner; import org.apache.hc.client5.http.routing.HttpRoutePlanner;
import org.apache.hc.client5.http.routing.RoutingSupport;
import org.apache.hc.core5.http.HttpException; import org.apache.hc.core5.http.HttpException;
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.config.Lookup; import org.apache.hc.core5.http.config.Lookup;
import org.apache.hc.core5.http2.nio.pool.H2ConnPool; import org.apache.hc.core5.http2.nio.pool.H2ConnPool;
@ -77,8 +77,7 @@ class InternalHttp2AsyncClient extends InternalAbstractHttpAsyncClient {
@Override @Override
HttpRoute determineRoute(final HttpRequest request, final HttpClientContext clientContext) throws HttpException { HttpRoute determineRoute(final HttpRequest request, final HttpClientContext clientContext) throws HttpException {
final HttpHost target = routePlanner.determineTargetHost(request, clientContext); final HttpRoute route = routePlanner.determineRoute(RoutingSupport.determineHost(request), clientContext);
final HttpRoute route = routePlanner.determineRoute(target, clientContext);
if (route.isTunnelled()) { if (route.isTunnelled()) {
throw new HttpException("HTTP/2 tunneling not supported"); throw new HttpException("HTTP/2 tunneling not supported");
} }

View File

@ -40,8 +40,8 @@ import org.apache.hc.client5.http.cookie.CookieStore;
import org.apache.hc.client5.http.nio.AsyncClientConnectionManager; import org.apache.hc.client5.http.nio.AsyncClientConnectionManager;
import org.apache.hc.client5.http.protocol.HttpClientContext; import org.apache.hc.client5.http.protocol.HttpClientContext;
import org.apache.hc.client5.http.routing.HttpRoutePlanner; import org.apache.hc.client5.http.routing.HttpRoutePlanner;
import org.apache.hc.client5.http.routing.RoutingSupport;
import org.apache.hc.core5.http.HttpException; import org.apache.hc.core5.http.HttpException;
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.HttpVersion; import org.apache.hc.core5.http.HttpVersion;
import org.apache.hc.core5.http.ProtocolVersion; import org.apache.hc.core5.http.ProtocolVersion;
@ -83,8 +83,7 @@ class InternalHttpAsyncClient extends InternalAbstractHttpAsyncClient {
@Override @Override
HttpRoute determineRoute(final HttpRequest request, final HttpClientContext clientContext) throws HttpException { HttpRoute determineRoute(final HttpRequest request, final HttpClientContext clientContext) throws HttpException {
final HttpHost target = routePlanner.determineTargetHost(request, clientContext); final HttpRoute route = routePlanner.determineRoute(RoutingSupport.determineHost(request), clientContext);
final HttpRoute route = routePlanner.determineRoute(target, clientContext);
final ProtocolVersion protocolVersion = clientContext.getProtocolVersion(); final ProtocolVersion protocolVersion = clientContext.getProtocolVersion();
if (route.isTunnelled() && protocolVersion.greaterEquals(HttpVersion.HTTP_2_0)) { if (route.isTunnelled() && protocolVersion.greaterEquals(HttpVersion.HTTP_2_0)) {
throw new HttpException("HTTP/2 tunneling not supported"); throw new HttpException("HTTP/2 tunneling not supported");

View File

@ -36,10 +36,10 @@ import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import org.apache.hc.client5.http.SchemePortResolver; import org.apache.hc.client5.http.SchemePortResolver;
import org.apache.hc.client5.http.UnsupportedSchemeException;
import org.apache.hc.client5.http.auth.AuthCache; import org.apache.hc.client5.http.auth.AuthCache;
import org.apache.hc.client5.http.auth.AuthScheme; import org.apache.hc.client5.http.auth.AuthScheme;
import org.apache.hc.client5.http.impl.DefaultSchemePortResolver; import org.apache.hc.client5.http.impl.DefaultSchemePortResolver;
import org.apache.hc.client5.http.routing.RoutingSupport;
import org.apache.hc.core5.annotation.Contract; import org.apache.hc.core5.annotation.Contract;
import org.apache.hc.core5.annotation.ThreadingBehavior; import org.apache.hc.core5.annotation.ThreadingBehavior;
import org.apache.hc.core5.http.HttpHost; import org.apache.hc.core5.http.HttpHost;
@ -73,27 +73,13 @@ public class BasicAuthCache implements AuthCache {
public BasicAuthCache(final SchemePortResolver schemePortResolver) { public BasicAuthCache(final SchemePortResolver schemePortResolver) {
super(); super();
this.map = new ConcurrentHashMap<>(); this.map = new ConcurrentHashMap<>();
this.schemePortResolver = schemePortResolver != null ? schemePortResolver : this.schemePortResolver = schemePortResolver != null ? schemePortResolver : DefaultSchemePortResolver.INSTANCE;
DefaultSchemePortResolver.INSTANCE;
} }
public BasicAuthCache() { public BasicAuthCache() {
this(null); this(null);
} }
protected HttpHost getKey(final HttpHost host) {
if (host.getPort() <= 0) {
final int port;
try {
port = schemePortResolver.resolve(host);
} catch (final UnsupportedSchemeException ignore) {
return host;
}
return new HttpHost(host.getHostName(), port, host.getSchemeName());
}
return host;
}
@Override @Override
public void put(final HttpHost host, final AuthScheme authScheme) { public void put(final HttpHost host, final AuthScheme authScheme) {
Args.notNull(host, "HTTP host"); Args.notNull(host, "HTTP host");
@ -106,7 +92,8 @@ public class BasicAuthCache implements AuthCache {
try (final ObjectOutputStream out = new ObjectOutputStream(buf)) { try (final ObjectOutputStream out = new ObjectOutputStream(buf)) {
out.writeObject(authScheme); out.writeObject(authScheme);
} }
this.map.put(getKey(host), buf.toByteArray()); final HttpHost key = RoutingSupport.normalize(host, schemePortResolver);
this.map.put(key, buf.toByteArray());
} catch (final IOException ex) { } catch (final IOException ex) {
if (log.isWarnEnabled()) { if (log.isWarnEnabled()) {
log.warn("Unexpected I/O error while serializing auth scheme", ex); log.warn("Unexpected I/O error while serializing auth scheme", ex);
@ -122,7 +109,8 @@ public class BasicAuthCache implements AuthCache {
@Override @Override
public AuthScheme get(final HttpHost host) { public AuthScheme get(final HttpHost host) {
Args.notNull(host, "HTTP host"); Args.notNull(host, "HTTP host");
final byte[] bytes = this.map.get(getKey(host)); final HttpHost key = RoutingSupport.normalize(host, schemePortResolver);
final byte[] bytes = this.map.get(key);
if (bytes != null) { if (bytes != null) {
try { try {
final ByteArrayInputStream buf = new ByteArrayInputStream(bytes); final ByteArrayInputStream buf = new ByteArrayInputStream(bytes);
@ -147,7 +135,8 @@ public class BasicAuthCache implements AuthCache {
@Override @Override
public void remove(final HttpHost host) { public void remove(final HttpHost host) {
Args.notNull(host, "HTTP host"); Args.notNull(host, "HTTP host");
this.map.remove(getKey(host)); final HttpHost key = RoutingSupport.normalize(host, schemePortResolver);
this.map.remove(key);
} }
@Override @Override

View File

@ -46,6 +46,7 @@ import org.apache.hc.client5.http.impl.ExecSupport;
import org.apache.hc.client5.http.io.HttpClientConnectionManager; import org.apache.hc.client5.http.io.HttpClientConnectionManager;
import org.apache.hc.client5.http.protocol.HttpClientContext; import org.apache.hc.client5.http.protocol.HttpClientContext;
import org.apache.hc.client5.http.routing.HttpRoutePlanner; import org.apache.hc.client5.http.routing.HttpRoutePlanner;
import org.apache.hc.client5.http.routing.RoutingSupport;
import org.apache.hc.core5.annotation.Contract; import org.apache.hc.core5.annotation.Contract;
import org.apache.hc.core5.annotation.ThreadingBehavior; import org.apache.hc.core5.annotation.ThreadingBehavior;
import org.apache.hc.core5.http.ClassicHttpRequest; import org.apache.hc.core5.http.ClassicHttpRequest;
@ -111,7 +112,7 @@ class InternalHttpClient extends CloseableHttpClient implements Configurable {
final HttpHost host, final HttpHost host,
final HttpRequest request, final HttpRequest request,
final HttpContext context) throws HttpException { final HttpContext context) throws HttpException {
final HttpHost target = host != null ? host : this.routePlanner.determineTargetHost(request, context); final HttpHost target = host != null ? host : RoutingSupport.determineHost(request);
return this.routePlanner.determineRoute(target, context); return this.routePlanner.determineRoute(target, context);
} }

View File

@ -33,6 +33,7 @@ import java.io.InterruptedIOException;
import org.apache.hc.client5.http.CancellableAware; import org.apache.hc.client5.http.CancellableAware;
import org.apache.hc.client5.http.ClientProtocolException; import org.apache.hc.client5.http.ClientProtocolException;
import org.apache.hc.client5.http.HttpRoute; import org.apache.hc.client5.http.HttpRoute;
import org.apache.hc.client5.http.SchemePortResolver;
import org.apache.hc.client5.http.classic.ExecRuntime; import org.apache.hc.client5.http.classic.ExecRuntime;
import org.apache.hc.client5.http.config.Configurable; import org.apache.hc.client5.http.config.Configurable;
import org.apache.hc.client5.http.config.RequestConfig; import org.apache.hc.client5.http.config.RequestConfig;
@ -41,6 +42,7 @@ import org.apache.hc.client5.http.impl.DefaultSchemePortResolver;
import org.apache.hc.client5.http.io.HttpClientConnectionManager; import org.apache.hc.client5.http.io.HttpClientConnectionManager;
import org.apache.hc.client5.http.protocol.HttpClientContext; import org.apache.hc.client5.http.protocol.HttpClientContext;
import org.apache.hc.client5.http.protocol.RequestClientConnControl; import org.apache.hc.client5.http.protocol.RequestClientConnControl;
import org.apache.hc.client5.http.routing.RoutingSupport;
import org.apache.hc.core5.annotation.Contract; import org.apache.hc.core5.annotation.Contract;
import org.apache.hc.core5.annotation.ThreadingBehavior; import org.apache.hc.core5.annotation.ThreadingBehavior;
import org.apache.hc.core5.http.ClassicHttpRequest; import org.apache.hc.core5.http.ClassicHttpRequest;
@ -77,6 +79,7 @@ public class MinimalHttpClient extends CloseableHttpClient {
private final HttpClientConnectionManager connManager; private final HttpClientConnectionManager connManager;
private final ConnectionReuseStrategy reuseStrategy; private final ConnectionReuseStrategy reuseStrategy;
private final SchemePortResolver schemePortResolver;
private final HttpRequestExecutor requestExecutor; private final HttpRequestExecutor requestExecutor;
private final HttpProcessor httpProcessor; private final HttpProcessor httpProcessor;
@ -84,6 +87,7 @@ public class MinimalHttpClient extends CloseableHttpClient {
super(); super();
this.connManager = Args.notNull(connManager, "HTTP connection manager"); this.connManager = Args.notNull(connManager, "HTTP connection manager");
this.reuseStrategy = DefaultConnectionReuseStrategy.INSTANCE; this.reuseStrategy = DefaultConnectionReuseStrategy.INSTANCE;
this.schemePortResolver = DefaultSchemePortResolver.INSTANCE;
this.requestExecutor = new HttpRequestExecutor(this.reuseStrategy); this.requestExecutor = new HttpRequestExecutor(this.reuseStrategy);
this.httpProcessor = new DefaultHttpProcessor( this.httpProcessor = new DefaultHttpProcessor(
new RequestContent(), new RequestContent(),
@ -116,11 +120,7 @@ public class MinimalHttpClient extends CloseableHttpClient {
clientContext.setRequestConfig(config); clientContext.setRequestConfig(config);
} }
final HttpRoute route = new HttpRoute(target.getPort() > 0 ? target : new HttpHost( final HttpRoute route = new HttpRoute(RoutingSupport.normalize(target, schemePortResolver));
target.getHostName(),
DefaultSchemePortResolver.INSTANCE.resolve(target),
target.getSchemeName()));
final ExecRuntime execRuntime = new ExecRuntimeImpl(log, connManager, requestExecutor, final ExecRuntime execRuntime = new ExecRuntimeImpl(log, connManager, requestExecutor,
request instanceof CancellableAware ? (CancellableAware) request : null); request instanceof CancellableAware ? (CancellableAware) request : null);
try { try {

View File

@ -34,10 +34,10 @@ import java.util.concurrent.Future;
import org.apache.hc.client5.http.DnsResolver; import org.apache.hc.client5.http.DnsResolver;
import org.apache.hc.client5.http.SchemePortResolver; import org.apache.hc.client5.http.SchemePortResolver;
import org.apache.hc.client5.http.UnsupportedSchemeException;
import org.apache.hc.client5.http.impl.DefaultSchemePortResolver; import org.apache.hc.client5.http.impl.DefaultSchemePortResolver;
import org.apache.hc.client5.http.nio.AsyncClientConnectionOperator; import org.apache.hc.client5.http.nio.AsyncClientConnectionOperator;
import org.apache.hc.client5.http.nio.ManagedAsyncClientConnection; import org.apache.hc.client5.http.nio.ManagedAsyncClientConnection;
import org.apache.hc.client5.http.routing.RoutingSupport;
import org.apache.hc.core5.annotation.Internal; import org.apache.hc.core5.annotation.Internal;
import org.apache.hc.core5.concurrent.ComplexFuture; import org.apache.hc.core5.concurrent.ComplexFuture;
import org.apache.hc.core5.concurrent.FutureCallback; import org.apache.hc.core5.concurrent.FutureCallback;
@ -81,14 +81,7 @@ final class DefaultAsyncClientConnectionOperator implements AsyncClientConnectio
Args.notNull(connectionInitiator, "Connection initiator"); Args.notNull(connectionInitiator, "Connection initiator");
Args.notNull(host, "Host"); Args.notNull(host, "Host");
final ComplexFuture<ManagedAsyncClientConnection> future = new ComplexFuture<>(callback); final ComplexFuture<ManagedAsyncClientConnection> future = new ComplexFuture<>(callback);
final HttpHost remoteEndpoint; final HttpHost remoteEndpoint = RoutingSupport.normalize(host, schemePortResolver);
try {
remoteEndpoint = host.getPort() > 0 ? host :
new HttpHost(host.getHostName(), schemePortResolver.resolve(host), host.getSchemeName());
} catch (final UnsupportedSchemeException ex) {
future.failed(ex);
return future;
}
final InetAddress remoteAddress = host.getAddress(); final InetAddress remoteAddress = host.getAddress();
final TlsStrategy tlsStrategy = tlsStrategyLookup != null ? tlsStrategyLookup.lookup(host.getSchemeName()) : null; final TlsStrategy tlsStrategy = tlsStrategyLookup != null ? tlsStrategyLookup.lookup(host.getSchemeName()) : null;
final Future<IOSession> sessionFuture = sessionRequester.connect( final Future<IOSession> sessionFuture = sessionRequester.connect(

View File

@ -31,19 +31,17 @@ import java.net.InetAddress;
import org.apache.hc.client5.http.HttpRoute; import org.apache.hc.client5.http.HttpRoute;
import org.apache.hc.client5.http.SchemePortResolver; import org.apache.hc.client5.http.SchemePortResolver;
import org.apache.hc.client5.http.UnsupportedSchemeException;
import org.apache.hc.client5.http.config.RequestConfig; import org.apache.hc.client5.http.config.RequestConfig;
import org.apache.hc.client5.http.impl.DefaultSchemePortResolver; import org.apache.hc.client5.http.impl.DefaultSchemePortResolver;
import org.apache.hc.client5.http.protocol.HttpClientContext; import org.apache.hc.client5.http.protocol.HttpClientContext;
import org.apache.hc.client5.http.routing.HttpRoutePlanner; import org.apache.hc.client5.http.routing.HttpRoutePlanner;
import org.apache.hc.client5.http.routing.RoutingSupport;
import org.apache.hc.core5.annotation.Contract; import org.apache.hc.core5.annotation.Contract;
import org.apache.hc.core5.annotation.ThreadingBehavior; import org.apache.hc.core5.annotation.ThreadingBehavior;
import org.apache.hc.core5.http.HttpException; import org.apache.hc.core5.http.HttpException;
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.ProtocolException; import org.apache.hc.core5.http.ProtocolException;
import org.apache.hc.core5.http.protocol.HttpContext; import org.apache.hc.core5.http.protocol.HttpContext;
import org.apache.hc.core5.net.URIAuthority;
/** /**
* Default implementation of an {@link HttpRoutePlanner}. It will not make use of * Default implementation of an {@link HttpRoutePlanner}. It will not make use of
@ -58,8 +56,7 @@ public class DefaultRoutePlanner implements HttpRoutePlanner {
public DefaultRoutePlanner(final SchemePortResolver schemePortResolver) { public DefaultRoutePlanner(final SchemePortResolver schemePortResolver) {
super(); super();
this.schemePortResolver = schemePortResolver != null ? schemePortResolver : this.schemePortResolver = schemePortResolver != null ? schemePortResolver : DefaultSchemePortResolver.INSTANCE;
DefaultSchemePortResolver.INSTANCE;
} }
@Override @Override
@ -73,19 +70,9 @@ public class DefaultRoutePlanner implements HttpRoutePlanner {
if (proxy == null) { if (proxy == null) {
proxy = determineProxy(host, context); proxy = determineProxy(host, context);
} }
final HttpHost target = RoutingSupport.normalize(host, schemePortResolver);
final HttpHost target; if (target.getPort() < 0) {
if (host.getPort() <= 0) { throw new ProtocolException("Unroutable protocol scheme: " + target);
try {
target = new HttpHost(
host.getHostName(),
this.schemePortResolver.resolve(host),
host.getSchemeName());
} catch (final UnsupportedSchemeException ex) {
throw new HttpException(ex.getMessage());
}
} else {
target = host;
} }
final boolean secure = target.getSchemeName().equalsIgnoreCase("https"); final boolean secure = target.getSchemeName().equalsIgnoreCase("https");
if (proxy == null) { if (proxy == null) {
@ -95,20 +82,6 @@ public class DefaultRoutePlanner implements HttpRoutePlanner {
} }
} }
@Override
public final HttpHost determineTargetHost(final HttpRequest request, final HttpContext context) throws HttpException {
final URIAuthority authority = request.getAuthority();
if (authority != null) {
final String scheme = request.getScheme();
if (scheme == null) {
throw new ProtocolException("Protocol scheme is not specified");
}
return new HttpHost(authority, scheme);
} else {
return null;
}
}
/** /**
* This implementation returns null. * This implementation returns null.
* *

View File

@ -30,7 +30,6 @@ package org.apache.hc.client5.http.routing;
import org.apache.hc.client5.http.HttpRoute; import org.apache.hc.client5.http.HttpRoute;
import org.apache.hc.core5.http.HttpException; import org.apache.hc.core5.http.HttpException;
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.protocol.HttpContext; import org.apache.hc.core5.http.protocol.HttpContext;
/** /**
@ -60,17 +59,4 @@ public interface HttpRoutePlanner {
*/ */
HttpRoute determineRoute(HttpHost target, HttpContext context) throws HttpException; HttpRoute determineRoute(HttpHost target, HttpContext context) throws HttpException;
/**
* Determines the target host for the given request.
*
* @param request the request to be executed
* @param context the context to use for the subsequent execution.
* Implementations may accept {@code null}.
*
* @return the route that the request should take
*
* @throws HttpException in case of a problem
*/
HttpHost determineTargetHost(HttpRequest request, HttpContext context) throws HttpException;
} }

View File

@ -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.http.routing;
import org.apache.hc.client5.http.SchemePortResolver;
import org.apache.hc.client5.http.impl.DefaultSchemePortResolver;
import org.apache.hc.core5.http.HttpException;
import org.apache.hc.core5.http.HttpHost;
import org.apache.hc.core5.http.HttpRequest;
import org.apache.hc.core5.http.ProtocolException;
import org.apache.hc.core5.net.URIAuthority;
public final class RoutingSupport {
public static HttpHost determineHost(final HttpRequest request) throws HttpException {
if (request == null) {
return null;
}
final URIAuthority authority = request.getAuthority();
if (authority != null) {
final String scheme = request.getScheme();
if (scheme == null) {
throw new ProtocolException("Protocol scheme is not specified");
}
return new HttpHost(authority, scheme);
} else {
return null;
}
}
public static HttpHost normalize(final HttpHost host, final SchemePortResolver schemePortResolver) {
if (host == null) {
return null;
}
if (host.getPort() < 0) {
final int port = (schemePortResolver != null ? schemePortResolver: DefaultSchemePortResolver.INSTANCE).resolve(host);
if (port > 0) {
return new HttpHost(host.getHostName(), port, host.getSchemeName());
}
}
return host;
}
}

View File

@ -27,12 +27,10 @@
package org.apache.hc.client5.http.impl.auth; package org.apache.hc.client5.http.impl.auth;
import org.apache.hc.client5.http.SchemePortResolver;
import org.apache.hc.client5.http.auth.AuthScheme; import org.apache.hc.client5.http.auth.AuthScheme;
import org.apache.hc.core5.http.HttpHost; import org.apache.hc.core5.http.HttpHost;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import org.mockito.Mockito;
/** /**
* Unit tests for {@link BasicAuthCache}. * Unit tests for {@link BasicAuthCache}.
@ -67,24 +65,6 @@ public class TestBasicAuthCache {
Assert.assertNull(cache.get(new HttpHost("localhost", 80))); Assert.assertNull(cache.get(new HttpHost("localhost", 80)));
} }
@Test
public void testGetKey() throws Exception {
final BasicAuthCache cache = new BasicAuthCache();
final HttpHost target = new HttpHost("localhost", 443, "https");
Assert.assertSame(target, cache.getKey(target));
Assert.assertEquals(target, cache.getKey(new HttpHost("localhost", -1, "https")));
}
@Test
public void testGetKeyWithSchemeRegistry() throws Exception {
final SchemePortResolver schemePortResolver = Mockito.mock(SchemePortResolver.class);
final BasicAuthCache cache = new BasicAuthCache(schemePortResolver);
Mockito.when(schemePortResolver.resolve(new HttpHost("localhost", -1, "https"))).thenReturn(443);
final HttpHost target = new HttpHost("localhost", 443, "https");
Assert.assertSame(target, cache.getKey(target));
Assert.assertEquals(target, cache.getKey(new HttpHost("localhost", -1, "https")));
}
@Test @Test
public void testStoreNonserializable() throws Exception { public void testStoreNonserializable() throws Exception {
final BasicAuthCache cache = new BasicAuthCache(); final BasicAuthCache cache = new BasicAuthCache();

View File

@ -27,20 +27,14 @@
package org.apache.hc.client5.http.impl.routing; package org.apache.hc.client5.http.impl.routing;
import java.net.URI;
import org.apache.hc.client5.http.HttpRoute; import org.apache.hc.client5.http.HttpRoute;
import org.apache.hc.client5.http.SchemePortResolver; import org.apache.hc.client5.http.SchemePortResolver;
import org.apache.hc.client5.http.config.RequestConfig; import org.apache.hc.client5.http.config.RequestConfig;
import org.apache.hc.client5.http.protocol.HttpClientContext; import org.apache.hc.client5.http.protocol.HttpClientContext;
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.ProtocolException; import org.apache.hc.core5.http.ProtocolException;
import org.apache.hc.core5.http.message.BasicHttpRequest;
import org.apache.hc.core5.http.protocol.BasicHttpContext; import org.apache.hc.core5.http.protocol.BasicHttpContext;
import org.apache.hc.core5.http.protocol.HttpContext; import org.apache.hc.core5.http.protocol.HttpContext;
import org.apache.hc.core5.net.URIAuthority;
import org.hamcrest.CoreMatchers;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
@ -109,24 +103,4 @@ public class TestDefaultRoutePlanner {
routePlanner.determineRoute(null, context); routePlanner.determineRoute(null, context);
} }
@Test
public void testDetermineHost() throws Exception {
final HttpContext context = new BasicHttpContext();
final HttpRequest request1 = new BasicHttpRequest("GET", "/");
final HttpHost host1 = routePlanner.determineTargetHost(request1, context);
Assert.assertThat(host1, CoreMatchers.nullValue());
final HttpRequest request2 = new BasicHttpRequest("GET", new URI("https://somehost:8443/"));
final HttpHost host2 = routePlanner.determineTargetHost(request2, context);
Assert.assertThat(host2, CoreMatchers.equalTo(new HttpHost("somehost", 8443, "https")));
}
@Test(expected = ProtocolException.class)
public void testDetermineHostMissingScheme() throws Exception {
final HttpContext context = new BasicHttpContext();
final HttpRequest request1 = new BasicHttpRequest("GET", "/");
request1.setAuthority(new URIAuthority("host"));
routePlanner.determineTargetHost(request1, context);
}
} }

View File

@ -0,0 +1,62 @@
/*
* ====================================================================
* 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.http.impl.routing;
import java.net.URI;
import org.apache.hc.client5.http.routing.RoutingSupport;
import org.apache.hc.core5.http.HttpHost;
import org.apache.hc.core5.http.HttpRequest;
import org.apache.hc.core5.http.ProtocolException;
import org.apache.hc.core5.http.message.BasicHttpRequest;
import org.apache.hc.core5.net.URIAuthority;
import org.hamcrest.CoreMatchers;
import org.junit.Assert;
import org.junit.Test;
public class TestRoutingSupport {
@Test
public void testDetermineHost() throws Exception {
final HttpRequest request1 = new BasicHttpRequest("GET", "/");
final HttpHost host1 = RoutingSupport.determineHost(request1);
Assert.assertThat(host1, CoreMatchers.nullValue());
final HttpRequest request2 = new BasicHttpRequest("GET", new URI("https://somehost:8443/"));
final HttpHost host2 = RoutingSupport.determineHost(request2);
Assert.assertThat(host2, CoreMatchers.equalTo(new HttpHost("somehost", 8443, "https")));
}
@Test(expected = ProtocolException.class)
public void testDetermineHostMissingScheme() throws Exception {
final HttpRequest request1 = new BasicHttpRequest("GET", "/");
request1.setAuthority(new URIAuthority("host"));
RoutingSupport.determineHost(request1);
}
}