From 05072b34dce43064e87ad0d59065f14666c1f34e Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Wed, 8 May 2019 13:28:16 +0200 Subject: [PATCH] Issue #3630 Forwarded-Port Added support for the X-Forwarded-Port header. Reimplemented header scanning using more efficient Trie and MethodHandles Signed-off-by: Greg Wilkins --- .../eclipse/jetty/http/HostPortHttpField.java | 13 + .../org/eclipse/jetty/http/HttpHeader.java | 1 + .../main/config/etc/jetty-http-forwarded.xml | 1 + .../main/config/modules/http-forwarded.mod | 1 + .../server/ForwardedRequestCustomizer.java | 274 +++++++++++++----- .../ForwardedRequestCustomizerTest.java | 27 +- .../java/org/eclipse/jetty/util/HostPort.java | 30 +- .../org/eclipse/jetty/util/HostPortTest.java | 13 +- 8 files changed, 269 insertions(+), 91 deletions(-) diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/HostPortHttpField.java b/jetty-http/src/main/java/org/eclipse/jetty/http/HostPortHttpField.java index 215c353b4b9..dc386665339 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/HostPortHttpField.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/HostPortHttpField.java @@ -49,6 +49,19 @@ protected HostPortHttpField(HttpHeader header, String name, String authority) } } + /* ------------------------------------------------------------ */ + public HostPortHttpField(String host, int port) + { + this(new HostPort(host, port)); + } + + /* ------------------------------------------------------------ */ + protected HostPortHttpField(HostPort hostport) + { + super(HttpHeader.HOST,HttpHeader.HOST.asString(),hostport.toString()); + _hostPort = hostport; + } + /* ------------------------------------------------------------ */ /** Get the host. * @return the host diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpHeader.java b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpHeader.java index f39c0f7df98..ac6bf2be8da 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpHeader.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpHeader.java @@ -82,6 +82,7 @@ TE("TE"), USER_AGENT("User-Agent"), X_FORWARDED_FOR("X-Forwarded-For"), + X_FORWARDED_PORT("X-Forwarded-Port"), X_FORWARDED_PROTO("X-Forwarded-Proto"), X_FORWARDED_SERVER("X-Forwarded-Server"), X_FORWARDED_HOST("X-Forwarded-Host"), diff --git a/jetty-server/src/main/config/etc/jetty-http-forwarded.xml b/jetty-server/src/main/config/etc/jetty-http-forwarded.xml index 50b80976a2a..648d6c6a94f 100644 --- a/jetty-server/src/main/config/etc/jetty-http-forwarded.xml +++ b/jetty-server/src/main/config/etc/jetty-http-forwarded.xml @@ -11,6 +11,7 @@ + diff --git a/jetty-server/src/main/config/modules/http-forwarded.mod b/jetty-server/src/main/config/modules/http-forwarded.mod index 34e25642b2c..f67822065a4 100644 --- a/jetty-server/src/main/config/modules/http-forwarded.mod +++ b/jetty-server/src/main/config/modules/http-forwarded.mod @@ -23,6 +23,7 @@ etc/jetty-http-forwarded.xml # jetty.httpConfig.forwardedServerHeader=X-Forwarded-Server # jetty.httpConfig.forwardedProtoHeader=X-Forwarded-Proto # jetty.httpConfig.forwardedForHeader=X-Forwarded-For +# jetty.httpConfig.forwardedPortHeader=X-Forwarded-Port # jetty.httpConfig.forwardedHttpsHeader=X-Proxied-Https # jetty.httpConfig.forwardedSslSessionIdHeader=Proxy-ssl-id # jetty.httpConfig.forwardedCipherSuiteHeader=Proxy-auth-cert diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/ForwardedRequestCustomizer.java b/jetty-server/src/main/java/org/eclipse/jetty/server/ForwardedRequestCustomizer.java index f2ffe24fb85..1e64892cbe9 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/ForwardedRequestCustomizer.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/ForwardedRequestCustomizer.java @@ -18,6 +18,9 @@ package org.eclipse.jetty.server; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; import java.net.InetSocketAddress; import javax.servlet.ServletRequest; @@ -29,11 +32,15 @@ import org.eclipse.jetty.http.HttpScheme; import org.eclipse.jetty.http.QuotedCSV; import org.eclipse.jetty.server.HttpConfiguration.Customizer; +import org.eclipse.jetty.util.ArrayTrie; import org.eclipse.jetty.util.HostPort; import org.eclipse.jetty.util.StringUtil; +import org.eclipse.jetty.util.Trie; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; +import static java.lang.invoke.MethodType.methodType; + /* ------------------------------------------------------------ */ /** Customize Requests for Proxy Forwarding. @@ -63,14 +70,21 @@ private String _forwardedHeader = HttpHeader.FORWARDED.toString(); private String _forwardedHostHeader = HttpHeader.X_FORWARDED_HOST.toString(); private String _forwardedServerHeader = HttpHeader.X_FORWARDED_SERVER.toString(); - private String _forwardedForHeader = HttpHeader.X_FORWARDED_FOR.toString(); private String _forwardedProtoHeader = HttpHeader.X_FORWARDED_PROTO.toString(); + private String _forwardedForHeader = HttpHeader.X_FORWARDED_FOR.toString(); + private String _forwardedPortHeader = HttpHeader.X_FORWARDED_PORT.toString(); private String _forwardedHttpsHeader = "X-Proxied-Https"; private String _forwardedCipherSuiteHeader = "Proxy-auth-cert"; private String _forwardedSslSessionIdHeader = "Proxy-ssl-id"; private boolean _proxyAsAuthority=false; private boolean _sslIsSecure=true; - + private Trie _handles; + + public ForwardedRequestCustomizer() + { + updateHandles(); + } + /** * @return true if the proxy address obtained via * {@code X-Forwarded-Server} or RFC7239 "by" is used as @@ -103,9 +117,9 @@ public void setForwardedOnly(boolean rfc7239only) if (_forwardedHeader==null) _forwardedHeader=HttpHeader.FORWARDED.toString(); _forwardedHostHeader=null; - _forwardedHostHeader=null; _forwardedServerHeader=null; _forwardedForHeader=null; + _forwardedPortHeader=null; _forwardedProtoHeader=null; _forwardedHttpsHeader=null; } @@ -117,11 +131,15 @@ public void setForwardedOnly(boolean rfc7239only) _forwardedServerHeader = HttpHeader.X_FORWARDED_SERVER.toString(); if (_forwardedForHeader==null) _forwardedForHeader = HttpHeader.X_FORWARDED_FOR.toString(); + if (_forwardedPortHeader==null) + _forwardedPortHeader = HttpHeader.X_FORWARDED_PORT.toString(); if (_forwardedProtoHeader==null) _forwardedProtoHeader = HttpHeader.X_FORWARDED_PROTO.toString(); if (_forwardedHttpsHeader==null) _forwardedHttpsHeader = "X-Proxied-Https"; } + + updateHandles(); } public String getForcedHost() @@ -138,6 +156,7 @@ public String getForcedHost() public void setForcedHost(String hostAndPort) { _forcedHost = new HostPortHttpField(hostAndPort); + updateHandles(); } /** @@ -155,6 +174,7 @@ public String getForwardedHeader() public void setForwardedHeader(String forwardedHeader) { _forwardedHeader = forwardedHeader; + updateHandles(); } public String getForwardedHostHeader() @@ -169,6 +189,7 @@ public String getForwardedHostHeader() public void setForwardedHostHeader(String forwardedHostHeader) { _forwardedHostHeader = forwardedHostHeader; + updateHandles(); } /** @@ -186,6 +207,7 @@ public String getForwardedServerHeader() public void setForwardedServerHeader(String forwardedServerHeader) { _forwardedServerHeader = forwardedServerHeader; + updateHandles(); } /** @@ -203,6 +225,22 @@ public String getForwardedForHeader() public void setForwardedForHeader(String forwardedRemoteAddressHeader) { _forwardedForHeader = forwardedRemoteAddressHeader; + updateHandles(); + } + + public String getForwardedPortHeader() + { + return _forwardedHostHeader; + } + + /** + * @param forwardedPortHeader + * The header name for forwarded hosts (default {@code X-Forwarded-Port}) + */ + public void setForwardedPortHeader(String forwardedPortHeader) + { + _forwardedHostHeader = forwardedPortHeader; + updateHandles(); } /** @@ -224,6 +262,7 @@ public String getForwardedProtoHeader() public void setForwardedProtoHeader(String forwardedProtoHeader) { _forwardedProtoHeader = forwardedProtoHeader; + updateHandles(); } /** @@ -241,6 +280,7 @@ public String getForwardedCipherSuiteHeader() public void setForwardedCipherSuiteHeader(String forwardedCipherSuite) { _forwardedCipherSuiteHeader = forwardedCipherSuite; + updateHandles(); } /** @@ -258,6 +298,7 @@ public String getForwardedSslSessionIdHeader() public void setForwardedSslSessionIdHeader(String forwardedSslSessionId) { _forwardedSslSessionIdHeader = forwardedSslSessionId; + updateHandles(); } /** @@ -274,6 +315,7 @@ public String getForwardedHttpsHeader() public void setForwardedHttpsHeader(String forwardedHttpsHeader) { _forwardedHttpsHeader = forwardedHttpsHeader; + updateHandles(); } /** @@ -299,118 +341,84 @@ public void customize(Connector connector, HttpConfiguration config, Request req { HttpFields httpFields = request.getHttpFields(); - RFC7239 rfc7239 = null; - String forwardedHost = null; - String forwardedServer = null; - HostPort forwardedFor = null; - String forwardedProto = null; - String forwardedHttps = null; - // Do a single pass through the header fields as it is a more efficient single iteration. - for (HttpField field : httpFields) + Forwarded forwarded = new Forwarded(request, config); + try { - String name = field.getName(); - - if (getForwardedCipherSuiteHeader()!=null && getForwardedCipherSuiteHeader().equalsIgnoreCase(name)) + for (HttpField field : httpFields) { - request.setAttribute("javax.servlet.request.cipher_suite",field.getValue()); - if (isSslIsSecure()) - { - request.setSecure(true); - request.setScheme(config.getSecureScheme()); - } - } - - if (getForwardedSslSessionIdHeader()!=null && getForwardedSslSessionIdHeader().equalsIgnoreCase(name)) - { - request.setAttribute("javax.servlet.request.ssl_session_id", field.getValue()); - if (isSslIsSecure()) - { - request.setSecure(true); - request.setScheme(config.getSecureScheme()); - } - } - - if (forwardedHost==null && _forwardedHostHeader!=null && _forwardedHostHeader.equalsIgnoreCase(name)) - forwardedHost = getLeftMost(field.getValue()); - - if (forwardedServer==null && _forwardedServerHeader!=null && _forwardedServerHeader.equalsIgnoreCase(name)) - forwardedServer = getLeftMost(field.getValue()); - - if (forwardedFor==null && _forwardedForHeader!=null && _forwardedForHeader.equalsIgnoreCase(name)) - forwardedFor = getRemoteAddr(field.getValue()); - - if (forwardedProto==null && _forwardedProtoHeader!=null && _forwardedProtoHeader.equalsIgnoreCase(name)) - forwardedProto = getLeftMost(field.getValue()); - - if (forwardedHttps==null && _forwardedHttpsHeader!=null && _forwardedHttpsHeader.equalsIgnoreCase(name)) - forwardedHttps = getLeftMost(field.getValue()); - - if (_forwardedHeader!=null && _forwardedHeader.equalsIgnoreCase(name)) - { - if (rfc7239==null) - rfc7239= new RFC7239(); - rfc7239.addValue(field.getValue()); + MethodHandle handle = _handles.get(field.getName()); + if (handle != null) + handle.invoke(forwarded, field); } } - - // Handle host header if if not available any RFC7230.by or X-ForwardedServer header + catch (Throwable e) + { + throw new RuntimeException(e); + } + + // Determine host if (_forcedHost != null) { // Update host header httpFields.put(_forcedHost); request.setAuthority(_forcedHost.getHost(),_forcedHost.getPort()); } - else if (rfc7239!=null && rfc7239._host!=null) + else if (forwarded._rfc7239!=null && forwarded._rfc7239._host!=null) { - HostPortHttpField auth = rfc7239._host; + HostPortHttpField auth = forwarded._rfc7239._host; httpFields.put(auth); request.setAuthority(auth.getHost(),auth.getPort()); } - else if (forwardedHost != null) + else if (forwarded._forwardedHost != null) { - HostPortHttpField auth = new HostPortHttpField(forwardedHost); + HostPortHttpField auth = new HostPortHttpField(forwarded._forwardedHost); httpFields.put(auth); - request.setAuthority(auth.getHost(),auth.getPort()); + request.setAuthority(auth.getHost(), auth.getPort()); } else if (_proxyAsAuthority) { - if (rfc7239!=null && rfc7239._by!=null) + if (forwarded._rfc7239!=null && forwarded._rfc7239._by!=null) { - HostPortHttpField auth = rfc7239._by; + HostPortHttpField auth = forwarded._rfc7239._by; httpFields.put(auth); request.setAuthority(auth.getHost(),auth.getPort()); } - else if (forwardedServer != null) + else if (forwarded._forwardedServer != null) { - request.setAuthority(forwardedServer,request.getServerPort()); + request.setAuthority(forwarded._forwardedServer,request.getServerPort()); } } // handle remote end identifier - if (rfc7239!=null && rfc7239._for!=null) + if (forwarded._rfc7239!=null && forwarded._rfc7239._for!=null) { - request.setRemoteAddr(InetSocketAddress.createUnresolved(rfc7239._for.getHost(),rfc7239._for.getPort())); + request.setRemoteAddr(InetSocketAddress.createUnresolved(forwarded._rfc7239._for.getHost(),forwarded._rfc7239._for.getPort())); } - else if (forwardedFor != null) + else if (forwarded._forwardedFor != null) { - request.setRemoteAddr(InetSocketAddress.createUnresolved(forwardedFor.getHost(), (forwardedFor.getPort() > 0) ? forwardedFor.getPort() : request.getRemotePort())); + int port = (forwarded._forwardedPort>0) + ? forwarded._forwardedPort + : (forwarded._forwardedFor.getPort() > 0) + ? forwarded._forwardedFor.getPort() + : request.getRemotePort(); + request.setRemoteAddr(InetSocketAddress.createUnresolved(forwarded._forwardedFor.getHost(), port)); } // handle protocol identifier - if (rfc7239!=null && rfc7239._proto!=null) + if (forwarded._rfc7239!=null && forwarded._rfc7239._proto!=null) { - request.setScheme(rfc7239._proto); - if (rfc7239._proto.equals(config.getSecureScheme())) + request.setScheme(forwarded._rfc7239._proto); + if (forwarded._rfc7239._proto.equals(config.getSecureScheme())) request.setSecure(true); } - else if (forwardedProto != null) + else if (forwarded._forwardedProto != null) { - request.setScheme(forwardedProto); - if (forwardedProto.equals(config.getSecureScheme())) + request.setScheme(forwarded._forwardedProto); + if (forwarded._forwardedProto.equals(config.getSecureScheme())) request.setSecure(true); } - else if (forwardedHttps !=null && ("on".equalsIgnoreCase(forwardedHttps)||"true".equalsIgnoreCase(forwardedHttps))) + else if (forwarded._forwardedHttps !=null && ("on".equalsIgnoreCase(forwarded._forwardedHttps)||"true".equalsIgnoreCase(forwarded._forwardedHttps))) { request.setScheme(HttpScheme.HTTPS.asString()); if (HttpScheme.HTTPS.asString().equals(config.getSecureScheme())) @@ -521,4 +529,122 @@ protected void parsedParam(StringBuffer buffer, int valueLength, int paramName, } } } + + private void updateHandles() + { + int size = 0; + MethodHandles.Lookup lookup = MethodHandles.lookup(); + MethodType type = methodType(Void.TYPE, HttpField.class); + + while(true) + { + try + { + size += 128; + _handles = new ArrayTrie<>(size); + + if (_forwardedCipherSuiteHeader != null && !_handles.put(_forwardedCipherSuiteHeader, lookup.findVirtual(Forwarded.class, "handleCipherSuite", type))) + continue; + if (_forwardedSslSessionIdHeader != null && !_handles.put(_forwardedSslSessionIdHeader, lookup.findVirtual(Forwarded.class, "handleSslSessionId", type))) + continue; + if (_forwardedHeader != null && !_handles.put(_forwardedHeader, lookup.findVirtual(Forwarded.class, "handleRFC7239", type))) + continue; + if (_forwardedForHeader != null && !_handles.put(_forwardedForHeader, lookup.findVirtual(Forwarded.class, "handleFor", type))) + continue; + if (_forwardedPortHeader != null && !_handles.put(_forwardedPortHeader, lookup.findVirtual(Forwarded.class, "handlePort", type))) + continue; + if (_forwardedHostHeader != null && !_handles.put(_forwardedHostHeader, lookup.findVirtual(Forwarded.class, "handleHost", type))) + continue; + if (_forwardedProtoHeader != null && !_handles.put(_forwardedProtoHeader, lookup.findVirtual(Forwarded.class, "handleProto", type))) + continue; + if (_forwardedHttpsHeader != null && !_handles.put(_forwardedHttpsHeader, lookup.findVirtual(Forwarded.class, "handleHttps", type))) + continue; + if (_forwardedServerHeader != null && !_handles.put(_forwardedServerHeader, lookup.findVirtual(Forwarded.class, "handleServer", type))) + continue; + break; + } + catch (NoSuchMethodException|IllegalAccessException e) + { + throw new IllegalStateException(e); + } + } + } + + private class Forwarded + { + HttpConfiguration _config; + Request _request; + + RFC7239 _rfc7239 = null; + String _forwardedHost = null; + String _forwardedServer = null; + String _forwardedProto = null; + HostPort _forwardedFor = null; + int _forwardedPort = -1; + String _forwardedHttps = null; + + public Forwarded(Request request, HttpConfiguration config) + { + _request = request; + _config = config; + } + + public void handleCipherSuite(HttpField field) + { + _request.setAttribute("javax.servlet.request.cipher_suite",field.getValue()); + if (isSslIsSecure()) + { + _request.setSecure(true); + _request.setScheme(_config.getSecureScheme()); + } + } + + public void handleSslSessionId(HttpField field) + { + _request.setAttribute("javax.servlet.request.ssl_session_id", field.getValue()); + if (isSslIsSecure()) + { + _request.setSecure(true); + _request.setScheme(_config.getSecureScheme()); + } + } + + public void handleHost(HttpField field) + { + _forwardedHost = getLeftMost(field.getValue()); + } + + public void handleServer(HttpField field) + { + _forwardedServer = getLeftMost(field.getValue()); + } + + public void handleProto(HttpField field) + { + _forwardedProto = getLeftMost(field.getValue()); + } + + public void handleFor(HttpField field) + { + _forwardedFor = getRemoteAddr(field.getValue()); + } + + public void handlePort(HttpField field) + { + _forwardedPort = field.getIntValue(); + } + public void handleHttps(HttpField field) + { + _forwardedHttps = getLeftMost(field.getValue()); + } + + public void handleRFC7239(HttpField field) + { + if (_rfc7239 ==null) + _rfc7239 = new RFC7239(); + _rfc7239.addValue(field.getValue()); + } + + + } } diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ForwardedRequestCustomizerTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ForwardedRequestCustomizerTest.java index 5d5467f73bd..0a1cecec0c2 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/ForwardedRequestCustomizerTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ForwardedRequestCustomizerTest.java @@ -18,11 +18,6 @@ package org.eclipse.jetty.server; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertTrue; - import java.io.IOException; import java.util.ArrayDeque; import java.util.Deque; @@ -41,6 +36,11 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + public class ForwardedRequestCustomizerTest { private Server _server; @@ -249,6 +249,23 @@ public void testForIpv6WithPort() throws Exception assertEquals("1111",_results.poll()); } + @Test + public void testForIpv6AndPort() throws Exception + { + String response=_connector.getResponse( + "GET / HTTP/1.1\n"+ + "Host: myhost\n"+ + "X-Forwarded-For: 1:2:3:4:5:6:7:8\n"+ + "X-Forwarded-Port: 2222\n"+ + "\n"); + assertThat(response, Matchers.containsString("200 OK")); + assertEquals("http",_results.poll()); + assertEquals("myhost",_results.poll()); + assertEquals("80",_results.poll()); + assertEquals("[1:2:3:4:5:6:7:8]",_results.poll()); + assertEquals("2222",_results.poll()); + } + @Test public void testLegacyProto() throws Exception { 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 index 1824dd799d1..8fde487ae19 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/HostPort.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/HostPort.java @@ -32,6 +32,12 @@ private final String _host; private final int _port; + public HostPort(String host, int port) throws IllegalArgumentException + { + _host = host; + _port = port; + } + public HostPort(String authority) throws IllegalArgumentException { if (authority==null) @@ -66,8 +72,16 @@ else if (authority.charAt(0)=='[') int c = authority.lastIndexOf(':'); if (c>=0) { - _host=authority.substring(0,c); - _port=StringUtil.toInt(authority,c+1); + if (c!=authority.indexOf(':')) + { + _host="[" + authority + "]"; + _port=0; + } + else + { + _host = authority.substring(0, c); + _port = StringUtil.toInt(authority, c + 1); + } } else { @@ -93,7 +107,6 @@ else if (authority.charAt(0)=='[') throw new IllegalArgumentException("Bad port"); } - /* ------------------------------------------------------------ */ /** Get the host. * @return the host */ @@ -102,7 +115,6 @@ public String getHost() return _host; } - /* ------------------------------------------------------------ */ /** Get the port. * @return the port */ @@ -111,7 +123,6 @@ public int getPort() return _port; } - /* ------------------------------------------------------------ */ /** Get the port. * @param defaultPort, the default port to return if a port is not specified * @return the port @@ -121,7 +132,14 @@ public int getPort(int defaultPort) return _port>0?_port:defaultPort; } - /* ------------------------------------------------------------ */ + @Override + public String toString() + { + if (_port>0) + return normalizeHost(_host) + ":" + _port; + return _host; + } + /** 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. 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 index 705bbbf6fa6..a700262cb90 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/HostPortTest.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/HostPortTest.java @@ -18,17 +18,17 @@ package org.eclipse.jetty.util; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.is; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertThrows; - import java.util.stream.Stream; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; + public class HostPortTest { private static Stream validAuthorityProvider() @@ -41,7 +41,8 @@ Arguments.of("10.10.10.1", "10.10.10.1", null), Arguments.of("10.10.10.1:80", "10.10.10.1", "80"), Arguments.of("[0::0::0::1]", "[0::0::0::1]", null), - Arguments.of("[0::0::0::1]:80", "[0::0::0::1]", "80") + Arguments.of("[0::0::0::1]:80", "[0::0::0::1]", "80"), + Arguments.of("0:1:2:3:4:5:6","[0:1:2:3:4:5:6]",null) ); }