HostAndPort { public static HostAndPort fromString(String hostPort, int defaultPort) { if (hostPort == null) throw new NullPointerException("hostPort == null"); String host = hostPort; int endHostIndex = hostPort.length(); if (hostPort.startsWith("[")) { endHostIndex = hostPort.lastIndexOf(']') + 1; host = hostPort.substring(1, endHostIndex == 0 ? 1 : endHostIndex - 1); if (!Endpoint.newBuilder().parseIp(host)) { throw new IllegalArgumentException(hostPort + " contains an invalid IPv6 literal"); } } else { int colonIndex = hostPort.indexOf(':'), nextColonIndex = hostPort.lastIndexOf(':'); if (colonIndex >= 0) { if (colonIndex == nextColonIndex) { host = hostPort.substring(0, colonIndex); endHostIndex = colonIndex; } else if (!Endpoint.newBuilder().parseIp(hostPort)) { throw new IllegalArgumentException(hostPort + " is an invalid IPv6 literal"); } } } if (host.isEmpty()) throw new IllegalArgumentException(hostPort + " has an empty host"); if (endHostIndex + 1 < hostPort.length() && hostPort.charAt(endHostIndex) == ':') { return new HostAndPort(host, validatePort(hostPort.substring(endHostIndex + 1), hostPort)); } return new HostAndPort(host, defaultPort); } HostAndPort(String host, int port); String getHost(); int getPort(); @Override boolean equals(Object o); @Override int hashCode(); @Override String toString(); static HostAndPort fromString(String hostPort, int defaultPort);  }
@Test public void parsesHost() { Stream.of( "google.com", "google.com", "192.0.2.1", "2001::3" ).forEach(host -> { assertThat(HostAndPort.fromString(host, 77)) .isEqualTo(new HostAndPort(host, 77)); }); }
@Test public void parsesHost_emptyPortOk() { assertThat(HostAndPort.fromString("gmail.com:", 77)) .isEqualTo(new HostAndPort("gmail.com", 77)); assertThat(HostAndPort.fromString("192.0.2.2:", 77)) .isEqualTo(new HostAndPort("192.0.2.2", 77)); assertThat(HostAndPort.fromString("[2001::2]:", 77)) .isEqualTo(new HostAndPort("2001::2", 77)); }
@Test public void parsesHostAndPort() { assertThat(HostAndPort.fromString("gmail.com:77", 1)) .isEqualTo(new HostAndPort("gmail.com", 77)); assertThat(HostAndPort.fromString("192.0.2.2:77", 1)) .isEqualTo(new HostAndPort("192.0.2.2", 77)); assertThat(HostAndPort.fromString("[2001::2]:77", 1)) .isEqualTo(new HostAndPort("2001::2", 77)); }
@Test public void throwsOnInvalidInput() { Stream.of( "google.com:65536", "google.com:9999999999", "google.com:port", "google.com:-25", "google.com:+25", "google.com:25 ", "google.com:25\t", "google.com:0x25 ", "[goo.gl]", "[goo.gl]:80", "[", "[]:", "[]:80", "[]bad", "[[:]]", "x:y:z", "", ":", ":123" ).forEach(hostPort -> { try { HostAndPort.fromString(hostPort, 77); throw new AssertionError(hostPort + " should have failed to parse"); } catch (IllegalArgumentException e) { } }); }