From 0155ae761c12164bc27f3c6d20223ed4c29fde7f Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Wed, 31 Aug 2016 16:43:42 +1000 Subject: [PATCH 1/2] Issue #880 Improve IPv6 support For #880 added the HostPort class, which was used to fix #878, #879, #884 and #886 --- .../eclipse/jetty/client/HttpDestination.java | 3 +- .../jetty/client/ProxyConfiguration.java | 12 +- .../eclipse/jetty/client/HttpClientTest.java | 28 ++++ .../jetty/client/ProxyConfigurationTest.java | 12 ++ .../org/eclipse/jetty/http/HttpParser.java | 45 ++---- .../eclipse/jetty/http/HttpParserTest.java | 2 +- .../eclipse/jetty/jmx/ConnectorServer.java | 14 +- .../eclipse/jetty/proxy/ConnectHandler.java | 12 +- .../jetty/proxy/ConnectHandlerTest.java | 24 +++- .../org/eclipse/jetty/server/Request.java | 46 ++----- .../java/org/eclipse/jetty/util/HostPort.java | 129 ++++++++++++++++++ .../org/eclipse/jetty/util/IPAddressMap.java | 1 + .../org/eclipse/jetty/util/StringUtil.java | 9 +- .../java/org/eclipse/jetty/util/URIUtil.java | 10 +- .../org/eclipse/jetty/util/HostPortTest.java | 92 +++++++++++++ 15 files changed, 328 insertions(+), 111 deletions(-) create mode 100644 jetty-util/src/main/java/org/eclipse/jetty/util/HostPort.java create mode 100644 jetty-util/src/test/java/org/eclipse/jetty/util/HostPortTest.java diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpDestination.java b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpDestination.java index 692fc71a3ef..d827adb073d 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpDestination.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpDestination.java @@ -35,6 +35,7 @@ import org.eclipse.jetty.http.HttpScheme; import org.eclipse.jetty.io.ClientConnectionFactory; import org.eclipse.jetty.io.ssl.SslClientConnectionFactory; import org.eclipse.jetty.util.BlockingArrayQueue; +import org.eclipse.jetty.util.HostPort; import org.eclipse.jetty.util.Promise; import org.eclipse.jetty.util.component.ContainerLifeCycle; import org.eclipse.jetty.util.component.Dumpable; @@ -78,7 +79,7 @@ public abstract class HttpDestination implements Destination, Closeable, Dumpabl } this.connectionFactory = connectionFactory; - String host = getHost(); + String host = HostPort.normalizeHost(getHost()); if (!client.isDefaultPort(getScheme(), getPort())) host += ":" + getPort(); hostField = new HttpField(HttpHeader.HOST, host); diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/ProxyConfiguration.java b/jetty-client/src/main/java/org/eclipse/jetty/client/ProxyConfiguration.java index a72cbf09db8..641c17a0d28 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/ProxyConfiguration.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/ProxyConfiguration.java @@ -25,6 +25,7 @@ import java.util.List; import java.util.Set; import org.eclipse.jetty.io.ClientConnectionFactory; +import org.eclipse.jetty.util.HostPort; /** * The configuration of the forward proxy to use with {@link org.eclipse.jetty.client.HttpClient}. @@ -58,6 +59,7 @@ public class ProxyConfiguration public static abstract class Proxy { + // TO use IPAddress Map private final Set included = new HashSet<>(); private final Set excluded = new HashSet<>(); private final Origin.Address address; @@ -146,12 +148,10 @@ public class ProxyConfiguration private boolean matches(Origin.Address address, String pattern) { // TODO: add support for CIDR notation like 192.168.0.0/24, see DoSFilter - int colon = pattern.indexOf(':'); - if (colon < 0) - return pattern.equals(address.getHost()); - String host = pattern.substring(0, colon); - String port = pattern.substring(colon + 1); - return host.equals(address.getHost()) && port.equals(String.valueOf(address.getPort())); + HostPort hostPort = new HostPort(pattern); + String host = hostPort.getHost(); + int port = hostPort.getPort(); + return host.equals(address.getHost()) && ( port<=0 || port==address.getPort() ); } /** diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientTest.java index 87a0da063af..910da8b39fe 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientTest.java @@ -81,6 +81,7 @@ import org.eclipse.jetty.util.FuturePromise; import org.eclipse.jetty.util.IO; import org.eclipse.jetty.util.Promise; import org.eclipse.jetty.util.ssl.SslContextFactory; +import org.hamcrest.Matchers; import org.junit.Assert; import org.junit.Assume; import org.junit.Rule; @@ -1491,6 +1492,33 @@ public class HttpClientTest extends AbstractHttpClientServerTest Assert.assertTrue(latch.await(5, TimeUnit.SECONDS)); } + + @Test + public void test_IPv6_Host() throws Exception + { + start(new AbstractHandler() + { + @Override + public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException + { + baseRequest.setHandled(true); + response.setContentType("text/plain"); + response.getOutputStream().print(request.getHeader("Host")); + } + }); + + URI uri = URI.create(scheme + "://[::1]:" + connector.getLocalPort() + "/path"); + ContentResponse response = client.newRequest(uri) + .method(HttpMethod.PUT) + .timeout(5, TimeUnit.SECONDS) + .send(); + + Assert.assertNotNull(response); + Assert.assertEquals(200, response.getStatus()); + Assert.assertThat(new String(response.getContent(), StandardCharsets.ISO_8859_1),Matchers.startsWith("[::1]:")); + } + + private void consume(InputStream input) throws IOException { while (true) diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/ProxyConfigurationTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/ProxyConfigurationTest.java index 3b485dfccaa..902d0a960d5 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/ProxyConfigurationTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/ProxyConfigurationTest.java @@ -63,4 +63,16 @@ public class ProxyConfigurationTest Assert.assertTrue(proxy.matches(new Origin("http", "1.2.3.4", 0))); Assert.assertFalse(proxy.matches(new Origin("http", "1.2.3.4", 5))); } + + @Test + public void testProxyMatchesWithIncludesAndExcludesIPv6() throws Exception + { + HttpProxy proxy = new HttpProxy("host", 0); + proxy.getIncludedAddresses().add("[1::2:3:4]"); + proxy.getExcludedAddresses().add("[1::2:3:4]:5"); + + Assert.assertFalse(proxy.matches(new Origin("http", "any", 0))); + Assert.assertTrue(proxy.matches(new Origin("http", "[1::2:3:4]", 0))); + Assert.assertFalse(proxy.matches(new Origin("http", "[1::2:3:4]", 5))); + } } diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java index e1ddee838c2..2e73ecc395c 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java @@ -27,6 +27,7 @@ import org.eclipse.jetty.http.HttpTokens.EndOfContent; import org.eclipse.jetty.util.ArrayTernaryTrie; import org.eclipse.jetty.util.ArrayTrie; import org.eclipse.jetty.util.BufferUtil; +import org.eclipse.jetty.util.HostPort; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.Trie; import org.eclipse.jetty.util.TypeUtil; @@ -831,50 +832,22 @@ public class HttpParser case HOST: add_to_connection_trie=_connectionFields!=null && _field==null; _host=true; - String host=_valueString; - int port=0; - if (host==null || host.length()==0) + if (_valueString==null || _valueString.length()==0) { throw new BadMessageException(HttpStatus.BAD_REQUEST_400,"Bad Host header"); } - int len=host.length(); - loop: for (int i = len; i-- > 0;) + try { - char c2 = (char)(0xff & host.charAt(i)); - switch (c2) - { - case ']': - break loop; - - case ':': - try - { - len=i; - port = StringUtil.toInt(host.substring(i+1)); - } - catch (NumberFormatException e) - { - if (DEBUG) - LOG.debug(e); - throw new BadMessageException(HttpStatus.BAD_REQUEST_400,"Bad Host header"); - } - break loop; - } + HostPort authority = new HostPort(_valueString); + if (_requestHandler!=null) + _requestHandler.parsedHostHeader(authority.getHost(),authority.getPort()); } - if (host.charAt(0)=='[') + catch (final Exception e) { - if (host.charAt(len-1)!=']') - { - throw new BadMessageException(HttpStatus.BAD_REQUEST_400,"Bad IPv6 Host header"); - } - host = host.substring(0,len); + throw new BadMessageException(HttpStatus.BAD_REQUEST_400,"Bad Host header") + {{initCause(e);}}; } - else if (len!=host.length()) - host = host.substring(0,len); - - if (_requestHandler!=null) - _requestHandler.parsedHostHeader(host,port); break; diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpParserTest.java b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpParserTest.java index 4d8f23a899d..140bdb9aa8b 100644 --- a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpParserTest.java +++ b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpParserTest.java @@ -1346,7 +1346,7 @@ public class HttpParserTest HttpParser.RequestHandler handler = new Handler(); HttpParser parser= new HttpParser(handler); parser.parseNext(buffer); - assertEquals("Bad IPv6 Host header",_bad); + assertEquals("Bad Host header",_bad); } @Test diff --git a/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/ConnectorServer.java b/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/ConnectorServer.java index 612a1c17b5c..36359b55f07 100644 --- a/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/ConnectorServer.java +++ b/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/ConnectorServer.java @@ -32,6 +32,7 @@ import javax.management.remote.JMXConnectorServer; import javax.management.remote.JMXConnectorServerFactory; import javax.management.remote.JMXServiceURL; +import org.eclipse.jetty.util.HostPort; import org.eclipse.jetty.util.component.AbstractLifeCycle; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; @@ -134,15 +135,10 @@ public class ConnectorServer extends AbstractLifeCycle */ private String startRegistry(String hostPath) throws Exception { - int rmiPort = 1099; // default RMI registry port - String rmiHost = hostPath; + HostPort hostPort = new HostPort(hostPath); - int idx = hostPath.indexOf(':'); - if (idx > 0) - { - rmiPort = Integer.parseInt(hostPath.substring(idx + 1)); - rmiHost = hostPath.substring(0,idx); - } + String rmiHost = hostPort.getHost(); + int rmiPort = hostPort.getPort(1099); // Verify that local registry is being used InetAddress hostAddress = InetAddress.getByName(rmiHost); @@ -171,7 +167,7 @@ public class ConnectorServer extends AbstractLifeCycle _registry = LocateRegistry.createRegistry(rmiPort); Thread.sleep(1000); - rmiHost = InetAddress.getLocalHost().getCanonicalHostName(); + rmiHost = HostPort.normalizeHost(InetAddress.getLocalHost().getCanonicalHostName()); return rmiHost + ':' + Integer.toString(rmiPort); } diff --git a/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/ConnectHandler.java b/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/ConnectHandler.java index a0d499739d0..ebc1fa6aed8 100644 --- a/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/ConnectHandler.java +++ b/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/ConnectHandler.java @@ -51,6 +51,7 @@ import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.handler.HandlerWrapper; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.Callback; +import org.eclipse.jetty.util.HostPort; import org.eclipse.jetty.util.Promise; import org.eclipse.jetty.util.TypeUtil; import org.eclipse.jetty.util.log.Log; @@ -221,14 +222,9 @@ public class ConnectHandler extends HandlerWrapper return; } - String host = serverAddress; - int port = 80; - int colon = serverAddress.indexOf(':'); - if (colon > 0) - { - host = serverAddress.substring(0, colon); - port = Integer.parseInt(serverAddress.substring(colon + 1)); - } + HostPort hostPort = new HostPort(serverAddress); + String host = hostPort.getHost(); + int port = hostPort.getPort(80); if (!validateDestination(host, port)) { diff --git a/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ConnectHandlerTest.java b/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ConnectHandlerTest.java index 4ef15e3e648..d559620c9af 100644 --- a/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ConnectHandlerTest.java +++ b/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ConnectHandlerTest.java @@ -66,7 +66,7 @@ public class ConnectHandlerTest extends AbstractConnectHandlerTest @Test public void testCONNECT() throws Exception - { + { String hostPort = "localhost:" + serverConnector.getLocalPort(); String request = "" + "CONNECT " + hostPort + " HTTP/1.1\r\n" + @@ -86,6 +86,28 @@ public class ConnectHandlerTest extends AbstractConnectHandlerTest } } + @Test + public void testCONNECTwithIPv6() throws Exception + { + String hostPort = "[::1]:" + serverConnector.getLocalPort(); + String request = "" + + "CONNECT " + hostPort + " HTTP/1.1\r\n" + + "Host: " + hostPort + "\r\n" + + "\r\n"; + try (Socket socket = newSocket()) + { + OutputStream output = socket.getOutputStream(); + BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream())); + + output.write(request.getBytes(StandardCharsets.UTF_8)); + output.flush(); + + // Expect 200 OK from the CONNECT request + SimpleHttpResponse response = readResponse(input); + Assert.assertEquals("200", response.getCode()); + } + } + @Test public void testCONNECTAndGET() throws Exception { diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java index a39a1397888..5b7429a8412 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java @@ -75,6 +75,7 @@ import org.eclipse.jetty.server.handler.ContextHandler.Context; import org.eclipse.jetty.server.session.AbstractSession; import org.eclipse.jetty.util.Attributes; import org.eclipse.jetty.util.AttributesMap; +import org.eclipse.jetty.util.HostPort; import org.eclipse.jetty.util.IO; import org.eclipse.jetty.util.MultiException; import org.eclipse.jetty.util.MultiMap; @@ -1212,46 +1213,19 @@ public class Request implements HttpServletRequest _port=0; if (hostPort != null) { - int len=hostPort.length(); - loop: for (int i = len; i-- > 0;) + try { - char c2 = (char)(0xff & hostPort.charAt(i)); - switch (c2) - { - case ']': - break loop; - - case ':': - try - { - len=i; - _port = StringUtil.toInt(hostPort.substring(i+1)); - } - catch (NumberFormatException e) - { - LOG.warn(e); - _serverName=hostPort; - _port=0; - return _serverName; - } - break loop; - } + HostPort authority = new HostPort(hostPort); + _serverName=authority.getHost(); + _port=authority.getPort(); } - if (hostPort.charAt(0)=='[') + catch (Exception e) { - if (hostPort.charAt(len-1)!=']') - { - LOG.warn("Bad IPv6 "+hostPort); - _serverName=hostPort; - _port=0; - return _serverName; - } - _serverName = hostPort.substring(0,len); - } - else if (len==hostPort.length()) + LOG.warn(e); _serverName=hostPort; - else - _serverName = hostPort.substring(0,len); + _port=0; + return _serverName; + } return _serverName; } diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/HostPort.java b/jetty-util/src/main/java/org/eclipse/jetty/util/HostPort.java new file mode 100644 index 00000000000..62da04b5dfd --- /dev/null +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/HostPort.java @@ -0,0 +1,129 @@ +// +// ======================================================================== +// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.util; + +/** + * Parse an authority string into Host and Port + *

Parse a string in the form "host:port", handling IPv4 an IPv6 hosts

+ * + */ +public class HostPort +{ + private final String _host; + private final int _port; + + public HostPort(String authority) throws IllegalArgumentException + { + if (authority==null || authority.length()==0) + throw new IllegalArgumentException("No Authority"); + try + { + if (authority.charAt(0)=='[') + { + // ipv6reference + int close=authority.lastIndexOf(']'); + if (close<0) + throw new IllegalArgumentException("Bad IPv6 host"); + _host=authority.substring(0,close+1); + + if (authority.length()>close+1) + { + if (authority.charAt(close+1)!=':') + throw new IllegalArgumentException("Bad IPv6 port"); + _port=StringUtil.toInt(authority,close+2); + } + else + _port=0; + } + else + { + // ipv4address or hostname + int c = authority.lastIndexOf(':'); + if (c>=0) + { + _host=authority.substring(0,c); + _port=StringUtil.toInt(authority,c+1); + } + else + { + _host=authority; + _port=0; + } + } + } + catch (IllegalArgumentException iae) + { + throw iae; + } + catch(final Exception ex) + { + throw new IllegalArgumentException("Bad HostPort") + { + {initCause(ex);} + }; + } + if(_host.isEmpty()) + throw new IllegalArgumentException("Bad host"); + if(_port<0) + throw new IllegalArgumentException("Bad port"); + } + + /* ------------------------------------------------------------ */ + /** Get the host. + * @return the host + */ + public String getHost() + { + return _host; + } + + /* ------------------------------------------------------------ */ + /** Get the port. + * @return the port + */ + public int getPort() + { + return _port; + } + + /* ------------------------------------------------------------ */ + /** Get the port. + * @param defaultPort, the default port to return if a port is not specified + * @return the port + */ + public int getPort(int defaultPort) + { + return _port>0?_port:defaultPort; + } + + /* ------------------------------------------------------------ */ + /** Normalize IPv6 address as per https://www.ietf.org/rfc/rfc2732.txt + * @param host A host name + * @return Host name surrounded by '[' and ']' as needed. + */ + public static String normalizeHost(String host) + { + // if it is normalized IPv6 or could not be IPv6, return + if (host.isEmpty() || host.charAt(0)=='[' || host.indexOf(':')<0) + return host; + + // normalize with [ ] + return "["+host+"]"; + } +} diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/IPAddressMap.java b/jetty-util/src/main/java/org/eclipse/jetty/util/IPAddressMap.java index 5395724353a..18f48ac32f9 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/IPAddressMap.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/IPAddressMap.java @@ -40,6 +40,7 @@ import java.util.StringTokenizer; * - => 0-255 * a,b,... - a list of wildcard specifications * + * @deprecated */ @SuppressWarnings("serial") public class IPAddressMap extends HashMap diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/StringUtil.java b/jetty-util/src/main/java/org/eclipse/jetty/util/StringUtil.java index 9dbd9e49b73..417767d1304 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/StringUtil.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/StringUtil.java @@ -668,22 +668,21 @@ public class StringUtil return sidBytes; } - /** * Convert String to an integer. Parses up to the first non-numeric character. If no number is found an IllegalArgumentException is thrown * - * @param string - * A String containing an integer. + * @param string A String containing an integer. + * @param from The index to start parsing from * @return an int */ - public static int toInt(String string) + public static int toInt(String string,int from) { int val = 0; boolean started = false; boolean minus = false; - for (int i = 0; i < string.length(); i++) + for (int i = from; i < string.length(); i++) { char b = string.charAt(i); if (b <= ' ') diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/URIUtil.java b/jetty-util/src/main/java/org/eclipse/jetty/util/URIUtil.java index 193a118081c..de4847eb74f 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/URIUtil.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/URIUtil.java @@ -708,10 +708,7 @@ public class URIUtil */ public static void appendSchemeHostPort(StringBuilder url,String scheme,String server, int port) { - if (server.indexOf(':')>=0&&server.charAt(0)!='[') - url.append(scheme).append("://").append('[').append(server).append(']'); - else - url.append(scheme).append("://").append(server); + url.append(scheme).append("://").append(HostPort.normalizeHost(server)); if (port > 0) { @@ -745,10 +742,7 @@ public class URIUtil { synchronized (url) { - if (server.indexOf(':')>=0&&server.charAt(0)!='[') - url.append(scheme).append("://").append('[').append(server).append(']'); - else - url.append(scheme).append("://").append(server); + url.append(scheme).append("://").append(HostPort.normalizeHost(server)); if (port > 0) { diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/HostPortTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/HostPortTest.java new file mode 100644 index 00000000000..e1a2b33f905 --- /dev/null +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/HostPortTest.java @@ -0,0 +1,92 @@ +// +// ======================================================================== +// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.util; + +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.*; + +import java.util.Arrays; +import java.util.List; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameter; +import org.junit.runners.Parameterized.Parameters; + +@RunWith(Parameterized.class) +public class HostPortTest +{ + @Parameters(name="{0}") + public static List testCases() + { + String data[][] = new String[][] { + {"host","host",null}, + {"host:80","host","80"}, + {"10.10.10.1","10.10.10.1",null}, + {"10.10.10.1:80","10.10.10.1","80"}, + {"[0::0::0::1]","[0::0::0::1]",null}, + {"[0::0::0::1]:80","[0::0::0::1]","80"}, + + {null,null,null}, + {"host:",null,null}, + {"",null,null}, + {":80",null,"80"}, + {"127.0.0.1:",null,null}, + {"[0::0::0::0::1]:",null,null}, + {"host:xxx",null,null}, + {"127.0.0.1:xxx",null,null}, + {"[0::0::0::0::1]:xxx",null,null}, + {"host:-80",null,null}, + {"127.0.0.1:-80",null,null}, + {"[0::0::0::0::1]:-80",null,null}, + }; + return Arrays.asList(data); + } + + @Parameter(0) + public String _authority; + + @Parameter(1) + public String _expectedHost; + + @Parameter(2) + public String _expectedPort; + + + @Test + public void test() + { + try + { + HostPort hostPort = new HostPort(_authority); + assertThat(hostPort.getHost(),is(_expectedHost)); + + if (_expectedPort==null) + assertThat(hostPort.getPort(),is(0)); + else + assertThat(hostPort.getPort(),is(Integer.valueOf(_expectedPort))); + } + catch (Exception e) + { + assertNull(_expectedHost); + } + } + +} From e0c83757aa997c65b23b1c1fffd36b5cde3dd424 Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Wed, 31 Aug 2016 12:25:19 +0200 Subject: [PATCH 2/2] Fixes #889 - ConstantThrowable.name can be removed. --- .../eclipse/jetty/util/ConstantThrowable.java | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/ConstantThrowable.java b/jetty-util/src/main/java/org/eclipse/jetty/util/ConstantThrowable.java index b368c90f909..a0c693eb76a 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/ConstantThrowable.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/ConstantThrowable.java @@ -22,22 +22,21 @@ package org.eclipse.jetty.util; * A {@link Throwable} that may be used in static contexts. It uses Java 7 * constructor that prevents setting stackTrace inside exception object. */ -public class ConstantThrowable extends Throwable { - - private String name; - - public ConstantThrowable() { +public class ConstantThrowable extends Throwable +{ + public ConstantThrowable() + { this(null); } - public ConstantThrowable(String name) { - super(null, null, false, false); - this.name = name; + public ConstantThrowable(String name) + { + super(name, null, false, false); } @Override - public String toString() { - return name; + public String toString() + { + return String.valueOf(getMessage()); } - }