Merge remote-tracking branch 'origin/jetty-9.3.x' into jetty-9.4.x
This commit is contained in:
commit
5ab9846ac5
|
@ -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);
|
||||||
|
|
|
@ -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()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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))
|
||||||
{
|
{
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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+"]";
|
||||||
|
}
|
||||||
|
}
|
|
@ -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>
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue