diff --git a/httpclient/src/main/java/org/apache/http/conn/routing/HttpRoute.java b/httpclient/src/main/java/org/apache/http/conn/routing/HttpRoute.java index 82793fa0c..847fa7e8f 100644 --- a/httpclient/src/main/java/org/apache/http/conn/routing/HttpRoute.java +++ b/httpclient/src/main/java/org/apache/http/conn/routing/HttpRoute.java @@ -71,8 +71,7 @@ public final class HttpRoute implements RouteInfo, Cloneable { private HttpRoute(final HttpHost target, final InetAddress local, final List proxies, final boolean secure, final TunnelType tunnelled, final LayerType layered) { Args.notNull(target, "Target host"); - Args.check(target.getPort() != -1, "target host port must be specified"); - this.targetHost = target; + this.targetHost = normalize(target); this.localAddress = local; if (proxies != null && !proxies.isEmpty()) { this.proxyChain = new ArrayList(proxies); @@ -87,6 +86,34 @@ public final class HttpRoute implements RouteInfo, Cloneable { this.layered = layered != null ? layered : LayerType.PLAIN; } + //TODO: to be removed in 5.0 + private static int getDefaultPort(final String schemeName) { + if ("http".equalsIgnoreCase(schemeName)) { + return 80; + } else if ("https".equalsIgnoreCase(schemeName)) { + return 443; + } else { + return -1; + } + + } + + //TODO: to be removed in 5.0 + private static HttpHost normalize(final HttpHost target) { + if (target.getPort() >= 0 ) { + return target; + } else { + final InetAddress address = target.getAddress(); + final String schemeName = target.getSchemeName(); + if (address != null) { + return new HttpHost(address, getDefaultPort(schemeName), schemeName); + } else { + final String hostName = target.getHostName(); + return new HttpHost(hostName, getDefaultPort(schemeName), schemeName); + } + } + } + /** * Creates a new route with all attributes specified explicitly. * diff --git a/httpclient/src/test/java/org/apache/http/conn/routing/TestHttpRoute.java b/httpclient/src/test/java/org/apache/http/conn/routing/TestHttpRoute.java index 1a27a23b2..206951ab1 100644 --- a/httpclient/src/test/java/org/apache/http/conn/routing/TestHttpRoute.java +++ b/httpclient/src/test/java/org/apache/http/conn/routing/TestHttpRoute.java @@ -577,10 +577,49 @@ public class TestHttpRoute { Assert.assertEquals("route was modified", route3, route1); } - @Test(expected = IllegalArgumentException.class) - public void testFailOnConstructionWithoutExplicitTargetPort() { + @Test + public void testTargetHostNormalizationHttp() { + final HttpHost target = new HttpHost("somehost", -1, "http"); + final HttpRoute route = new HttpRoute(target); + final HttpHost targetHost = route.getTargetHost(); + Assert.assertEquals("somehost", targetHost.getHostName()); + Assert.assertEquals(80, targetHost.getPort()); + Assert.assertEquals("http", targetHost.getSchemeName()); + Assert.assertEquals(null, targetHost.getAddress()); + } + + @Test + public void testTargetHostNormalizationHttps() { final HttpHost target = new HttpHost("somehost", -1, "https"); - new HttpRoute(target); + final HttpRoute route = new HttpRoute(target); + final HttpHost targetHost = route.getTargetHost(); + Assert.assertEquals("somehost", targetHost.getHostName()); + Assert.assertEquals(443, targetHost.getPort()); + Assert.assertEquals("https", targetHost.getSchemeName()); + Assert.assertEquals(null, targetHost.getAddress()); + } + + @Test + public void testTargetHostNormalizationUnknownPorotocol() { + final HttpHost target = new HttpHost("somehost", -1, "blah"); + final HttpRoute route = new HttpRoute(target); + final HttpHost targetHost = route.getTargetHost(); + Assert.assertEquals("somehost", targetHost.getHostName()); + Assert.assertEquals(-1, targetHost.getPort()); + Assert.assertEquals("blah", targetHost.getSchemeName()); + Assert.assertEquals(null, targetHost.getAddress()); + } + + @Test + public void testTargetHostNormalizationAddress() throws Exception { + final InetAddress address = InetAddress.getByAddress(new byte[]{127, 0, 0, 1}); + final HttpHost target = new HttpHost(address, -1, "http"); + final HttpRoute route = new HttpRoute(target); + final HttpHost targetHost = route.getTargetHost(); + Assert.assertEquals("localhost", targetHost.getHostName()); + Assert.assertEquals(80, targetHost.getPort()); + Assert.assertEquals("http", targetHost.getSchemeName()); + Assert.assertEquals(address, targetHost.getAddress()); } }