Merge remote-tracking branch 'origin/jetty-9.3.x' into jetty-9.4.x

This commit is contained in:
Greg Wilkins 2016-08-31 20:32:54 +10:00
commit 5ab9846ac5
17 changed files with 347 additions and 98 deletions

View File

@ -37,6 +37,7 @@ import org.eclipse.jetty.io.ClientConnectionFactory;
import org.eclipse.jetty.io.ssl.SslClientConnectionFactory; import org.eclipse.jetty.io.ssl.SslClientConnectionFactory;
import org.eclipse.jetty.util.BlockingArrayQueue; import org.eclipse.jetty.util.BlockingArrayQueue;
import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.HostPort;
import org.eclipse.jetty.util.Promise; import org.eclipse.jetty.util.Promise;
import org.eclipse.jetty.util.annotation.ManagedAttribute; import org.eclipse.jetty.util.annotation.ManagedAttribute;
import org.eclipse.jetty.util.annotation.ManagedObject; import org.eclipse.jetty.util.annotation.ManagedObject;
@ -87,7 +88,7 @@ public abstract class HttpDestination extends ContainerLifeCycle implements Dest
} }
this.connectionFactory = connectionFactory; this.connectionFactory = connectionFactory;
String host = getHost(); String host = HostPort.normalizeHost(getHost());
if (!client.isDefaultPort(getScheme(), getPort())) if (!client.isDefaultPort(getScheme(), getPort()))
host += ":" + getPort(); host += ":" + getPort();
hostField = new HttpField(HttpHeader.HOST, host); hostField = new HttpField(HttpHeader.HOST, host);

View File

@ -25,6 +25,7 @@ import java.util.List;
import java.util.Set; import java.util.Set;
import org.eclipse.jetty.io.ClientConnectionFactory; 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}. * 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 public static abstract class Proxy
{ {
// TO use IPAddress Map
private final Set<String> included = new HashSet<>(); private final Set<String> included = new HashSet<>();
private final Set<String> excluded = new HashSet<>(); private final Set<String> excluded = new HashSet<>();
private final Origin.Address address; private final Origin.Address address;
@ -149,12 +151,10 @@ public class ProxyConfiguration
private boolean matches(Origin.Address address, String pattern) private boolean matches(Origin.Address address, String pattern)
{ {
// TODO: add support for CIDR notation like 192.168.0.0/24, see DoSFilter // TODO: add support for CIDR notation like 192.168.0.0/24, see DoSFilter
int colon = pattern.indexOf(':'); HostPort hostPort = new HostPort(pattern);
if (colon < 0) String host = hostPort.getHost();
return pattern.equals(address.getHost()); int port = hostPort.getPort();
String host = pattern.substring(0, colon); return host.equals(address.getHost()) && ( port<=0 || port==address.getPort() );
String port = pattern.substring(colon + 1);
return host.equals(address.getHost()) && port.equals(String.valueOf(address.getPort()));
} }
/** /**

View File

@ -89,6 +89,7 @@ import org.eclipse.jetty.util.Promise;
import org.eclipse.jetty.util.SocketAddressResolver; import org.eclipse.jetty.util.SocketAddressResolver;
import org.eclipse.jetty.util.log.StacklessLogging; import org.eclipse.jetty.util.log.StacklessLogging;
import org.eclipse.jetty.util.ssl.SslContextFactory; import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.hamcrest.Matchers;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Assume; import org.junit.Assume;
import org.junit.Rule; import org.junit.Rule;
@ -1535,6 +1536,31 @@ public class HttpClientTest extends AbstractHttpClientServerTest
} }
} }
@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, boolean eof) throws IOException private void consume(InputStream input, boolean eof) throws IOException
{ {
int crlfs = 0; int crlfs = 0;

View File

@ -63,4 +63,16 @@ public class ProxyConfigurationTest
Assert.assertTrue(proxy.matches(new Origin("http", "1.2.3.4", 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))); 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)));
}
} }

View File

@ -19,7 +19,7 @@
package org.eclipse.jetty.http; package org.eclipse.jetty.http;
import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.HostPort;
@ -28,57 +28,20 @@ import org.eclipse.jetty.util.StringUtil;
*/ */
public class HostPortHttpField extends HttpField public class HostPortHttpField extends HttpField
{ {
private final String _host; final HostPort _hostPort;
private final int _port;
public HostPortHttpField(String authority) public HostPortHttpField(String authority)
{ {
this(HttpHeader.HOST,HttpHeader.HOST.asString(),authority); this(HttpHeader.HOST,HttpHeader.HOST.asString(),authority);
} }
public HostPortHttpField(HttpHeader header, String name, String authority) /* ------------------------------------------------------------ */
protected HostPortHttpField(HttpHeader header, String name, String authority)
{ {
super(header,name,authority); super(header,name,authority);
if (authority==null || authority.length()==0)
throw new IllegalArgumentException("No Authority");
try try
{ {
if (authority.charAt(0)=='[') _hostPort=new HostPort(authority);
{
// ipv6reference
int close=authority.lastIndexOf(']');
if (close<0)
throw new BadMessageException(HttpStatus.BAD_REQUEST_400,"Bad ipv6");
_host=authority.substring(0,close+1);
if (authority.length()>close+1)
{
if (authority.charAt(close+1)!=':')
throw new BadMessageException(HttpStatus.BAD_REQUEST_400,"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 (BadMessageException bm)
{
throw bm;
} }
catch(Exception e) catch(Exception e)
{ {
@ -92,7 +55,7 @@ public class HostPortHttpField extends HttpField
*/ */
public String getHost() public String getHost()
{ {
return _host; return _hostPort.getHost();
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
@ -101,6 +64,16 @@ public class HostPortHttpField extends HttpField
*/ */
public int getPort() public int getPort()
{ {
return _port; return _hostPort.getPort();
}
/* ------------------------------------------------------------ */
/** Get the port.
* @param defaultPort
* @return the port
*/
public int getPort(int defaultPort)
{
return _hostPort.getPort(defaultPort);
} }
} }

View File

@ -28,6 +28,8 @@ import org.eclipse.jetty.http.HttpTokens.EndOfContent;
import org.eclipse.jetty.util.ArrayTernaryTrie; import org.eclipse.jetty.util.ArrayTernaryTrie;
import org.eclipse.jetty.util.ArrayTrie; import org.eclipse.jetty.util.ArrayTrie;
import org.eclipse.jetty.util.BufferUtil; 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.Trie;
import org.eclipse.jetty.util.TypeUtil; import org.eclipse.jetty.util.TypeUtil;
import org.eclipse.jetty.util.Utf8StringBuilder; import org.eclipse.jetty.util.Utf8StringBuilder;
@ -933,6 +935,7 @@ public class HttpParser
break; break;
default: break; default: break;
} }
if (add_to_connection_trie && !_connectionFields.isFull() && _header!=null && _valueString!=null) if (add_to_connection_trie && !_connectionFields.isFull() && _header!=null && _valueString!=null)

View File

@ -25,6 +25,7 @@ import java.util.List;
import org.eclipse.jetty.http.HttpParser.State; import org.eclipse.jetty.http.HttpParser.State;
import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.log.StacklessLogging;
import org.hamcrest.Matchers; import org.hamcrest.Matchers;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
@ -1632,16 +1633,19 @@ public class HttpParserTest
@Test @Test
public void testBadIPv6Host() throws Exception public void testBadIPv6Host() throws Exception
{ {
ByteBuffer buffer = BufferUtil.toBuffer( try(StacklessLogging s = new StacklessLogging(HttpParser.class))
{
ByteBuffer buffer = BufferUtil.toBuffer(
"GET / HTTP/1.1\r\n" "GET / HTTP/1.1\r\n"
+ "Host: [::1\r\n" + "Host: [::1\r\n"
+ "Connection: close\r\n" + "Connection: close\r\n"
+ "\r\n"); + "\r\n");
HttpParser.RequestHandler handler = new Handler(); HttpParser.RequestHandler handler = new Handler();
HttpParser parser = new HttpParser(handler); HttpParser parser = new HttpParser(handler);
parser.parseNext(buffer); parser.parseNext(buffer);
Assert.assertThat(_bad, Matchers.containsString("Bad")); Assert.assertThat(_bad, Matchers.containsString("Bad"));
}
} }
@Test @Test

View File

@ -32,6 +32,7 @@ import javax.management.remote.JMXConnectorServer;
import javax.management.remote.JMXConnectorServerFactory; import javax.management.remote.JMXConnectorServerFactory;
import javax.management.remote.JMXServiceURL; import javax.management.remote.JMXServiceURL;
import org.eclipse.jetty.util.HostPort;
import org.eclipse.jetty.util.component.AbstractLifeCycle; import org.eclipse.jetty.util.component.AbstractLifeCycle;
import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.log.Logger;
@ -134,15 +135,10 @@ public class ConnectorServer extends AbstractLifeCycle
*/ */
private String startRegistry(String hostPath) throws Exception private String startRegistry(String hostPath) throws Exception
{ {
int rmiPort = 1099; // default RMI registry port HostPort hostPort = new HostPort(hostPath);
String rmiHost = hostPath;
int idx = hostPath.indexOf(':'); String rmiHost = hostPort.getHost();
if (idx > 0) int rmiPort = hostPort.getPort(1099);
{
rmiPort = Integer.parseInt(hostPath.substring(idx + 1));
rmiHost = hostPath.substring(0,idx);
}
// Verify that local registry is being used // Verify that local registry is being used
InetAddress hostAddress = InetAddress.getByName(rmiHost); InetAddress hostAddress = InetAddress.getByName(rmiHost);
@ -171,7 +167,7 @@ public class ConnectorServer extends AbstractLifeCycle
_registry = LocateRegistry.createRegistry(rmiPort); _registry = LocateRegistry.createRegistry(rmiPort);
Thread.sleep(1000); Thread.sleep(1000);
rmiHost = InetAddress.getLocalHost().getCanonicalHostName(); rmiHost = HostPort.normalizeHost(InetAddress.getLocalHost().getCanonicalHostName());
return rmiHost + ':' + Integer.toString(rmiPort); return rmiHost + ':' + Integer.toString(rmiPort);
} }

View File

@ -54,6 +54,7 @@ import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.handler.HandlerWrapper; import org.eclipse.jetty.server.handler.HandlerWrapper;
import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.HostPort;
import org.eclipse.jetty.util.Promise; import org.eclipse.jetty.util.Promise;
import org.eclipse.jetty.util.TypeUtil; import org.eclipse.jetty.util.TypeUtil;
import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Log;
@ -224,14 +225,9 @@ public class ConnectHandler extends HandlerWrapper
return; return;
} }
String host = serverAddress; HostPort hostPort = new HostPort(serverAddress);
int port = 80; String host = hostPort.getHost();
int colon = serverAddress.indexOf(':'); int port = hostPort.getPort(80);
if (colon > 0)
{
host = serverAddress.substring(0, colon);
port = Integer.parseInt(serverAddress.substring(colon + 1));
}
if (!validateDestination(host, port)) if (!validateDestination(host, port))
{ {

View File

@ -18,9 +18,11 @@
package org.eclipse.jetty.proxy; package org.eclipse.jetty.proxy;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream; import java.io.OutputStream;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.Socket; import java.net.Socket;
@ -65,7 +67,7 @@ public class ConnectHandlerTest extends AbstractConnectHandlerTest
@Test @Test
public void testCONNECT() throws Exception public void testCONNECT() throws Exception
{ {
String hostPort = "localhost:" + serverConnector.getLocalPort(); String hostPort = "localhost:" + serverConnector.getLocalPort();
String request = "" + String request = "" +
"CONNECT " + hostPort + " HTTP/1.1\r\n" + "CONNECT " + hostPort + " HTTP/1.1\r\n" +
@ -84,6 +86,27 @@ 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();
output.write(request.getBytes(StandardCharsets.UTF_8));
output.flush();
// Expect 200 OK from the CONNECT request
HttpTester.Response response = readResponse(socket.getInputStream());
Assert.assertEquals(HttpStatus.OK_200, response.getStatus());
}
}
@Test @Test
public void testCONNECTAndGET() throws Exception public void testCONNECTAndGET() throws Exception
{ {

View File

@ -80,6 +80,7 @@ import org.eclipse.jetty.server.session.Session;
import org.eclipse.jetty.server.session.SessionHandler; import org.eclipse.jetty.server.session.SessionHandler;
import org.eclipse.jetty.util.Attributes; import org.eclipse.jetty.util.Attributes;
import org.eclipse.jetty.util.AttributesMap; import org.eclipse.jetty.util.AttributesMap;
import org.eclipse.jetty.util.HostPort;
import org.eclipse.jetty.util.IO; import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.util.MultiMap; import org.eclipse.jetty.util.MultiMap;
import org.eclipse.jetty.util.MultiPartInputStreamParser; import org.eclipse.jetty.util.MultiPartInputStreamParser;

View File

@ -22,22 +22,21 @@ package org.eclipse.jetty.util;
* A {@link Throwable} that may be used in static contexts. It uses Java 7 * A {@link Throwable} that may be used in static contexts. It uses Java 7
* constructor that prevents setting stackTrace inside exception object. * constructor that prevents setting stackTrace inside exception object.
*/ */
public class ConstantThrowable extends Throwable { public class ConstantThrowable extends Throwable
{
private String name; public ConstantThrowable()
{
public ConstantThrowable() {
this(null); this(null);
} }
public ConstantThrowable(String name) { public ConstantThrowable(String name)
super(null, null, false, false); {
this.name = name; super(name, null, false, false);
} }
@Override @Override
public String toString() { public String toString()
return name; {
return String.valueOf(getMessage());
} }
} }

View File

@ -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
* <p>Parse a string in the form "host:port", handling IPv4 an IPv6 hosts</p>
*
*/
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+"]";
}
}

View File

@ -41,6 +41,7 @@ import java.util.StringTokenizer;
* a,b,... - a list of wildcard specifications * a,b,... - a list of wildcard specifications
* </pre> * </pre>
* @param <TYPE> the Map Entry value type * @param <TYPE> the Map Entry value type
* @deprecated
*/ */
@SuppressWarnings("serial") @SuppressWarnings("serial")
public class IPAddressMap<TYPE> extends HashMap<String, TYPE> public class IPAddressMap<TYPE> extends HashMap<String, TYPE>

View File

@ -682,7 +682,6 @@ public class StringUtil
return sidBytes; return sidBytes;
} }
/** /**
* Convert String to an integer. Parses up to the first non-numeric character. If no number is found an IllegalArgumentException is thrown * Convert String to an integer. Parses up to the first non-numeric character. If no number is found an IllegalArgumentException is thrown

View File

@ -720,10 +720,7 @@ public class URIUtil
*/ */
public static void appendSchemeHostPort(StringBuilder url,String scheme,String server, int port) public static void appendSchemeHostPort(StringBuilder url,String scheme,String server, int port)
{ {
if (server.indexOf(':')>=0&&server.charAt(0)!='[') url.append(scheme).append("://").append(HostPort.normalizeHost(server));
url.append(scheme).append("://").append('[').append(server).append(']');
else
url.append(scheme).append("://").append(server);
if (port > 0) if (port > 0)
{ {
@ -757,10 +754,7 @@ public class URIUtil
{ {
synchronized (url) synchronized (url)
{ {
if (server.indexOf(':')>=0&&server.charAt(0)!='[') url.append(scheme).append("://").append(HostPort.normalizeHost(server));
url.append(scheme).append("://").append('[').append(server).append(']');
else
url.append(scheme).append("://").append(server);
if (port > 0) if (port > 0)
{ {

View File

@ -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<String[]> 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);
}
}
}