下面列出了怎么用java.net.IDN的API类实例代码及写法,或者点击链接到github查看源代码。
private InetAddress parseAddress(DnsRecord r, String name) {
if (!(r instanceof DnsRawRecord)) {
return null;
}
final ByteBuf content = ((ByteBufHolder) r).content();
final int contentLen = content.readableBytes();
if (contentLen != INADDRSZ4 && contentLen != INADDRSZ6) {
return null;
}
final byte[] addrBytes = new byte[contentLen];
content.getBytes(content.readerIndex(), addrBytes);
try {
return InetAddress.getByAddress(
parent.isDecodeIdn() ? IDN.toUnicode(name) : name, addrBytes);
} catch (UnknownHostException e) {
// Should never reach here.
throw new Error(e);
}
}
@Test
public void testIDNEncodeToAsciiForDomain() {
String host = "тест.рф";
String asciiHost = IDN.toASCII(host);
short port = 10000;
SocksCmdRequest rq = new SocksCmdRequest(SocksCmdType.BIND, SocksAddressType.DOMAIN, host, port);
assertEquals(host, rq.host());
ByteBuf buffer = Unpooled.buffer(24);
rq.encodeAsByteBuf(buffer);
buffer.resetReaderIndex();
assertEquals(SocksProtocolVersion.SOCKS5.byteValue(), buffer.readByte());
assertEquals(SocksCmdType.BIND.byteValue(), buffer.readByte());
assertEquals((byte) 0x00, buffer.readByte());
assertEquals(SocksAddressType.DOMAIN.byteValue(), buffer.readByte());
assertEquals((byte) asciiHost.length(), buffer.readUnsignedByte());
assertEquals(asciiHost, buffer.readCharSequence(asciiHost.length(), CharsetUtil.US_ASCII));
assertEquals(port, buffer.readUnsignedShort());
buffer.release();
}
private static void test(
Socks5CommandType type, Socks5AddressType dstAddrType, String dstAddr, int dstPort) {
logger.debug(
"Testing type: " + type + " dstAddrType: " + dstAddrType +
" dstAddr: " + dstAddr + " dstPort: " + dstPort);
Socks5CommandRequest msg =
new DefaultSocks5CommandRequest(type, dstAddrType, dstAddr, dstPort);
EmbeddedChannel embedder = new EmbeddedChannel(new Socks5CommandRequestDecoder());
Socks5CommonTestUtils.writeFromClientToServer(embedder, msg);
msg = embedder.readInbound();
assertSame(msg.type(), type);
assertSame(msg.dstAddrType(), dstAddrType);
assertEquals(msg.dstAddr(), IDN.toASCII(dstAddr));
assertEquals(msg.dstPort(), dstPort);
assertNull(embedder.readInbound());
}
/**
* Performs IDN ToASCII encoding and canonicalize the result to lowercase. e.g. This converts
* {@code ☃.net} to {@code xn--n3h.net}, and {@code WwW.GoOgLe.cOm} to {@code www.google.com}.
* {@code null} will be returned if the input cannot be ToASCII encoded or if the result
* contains unsupported ASCII characters.
*/
public static String domainToAscii(String input) {
try {
String result = IDN.toASCII(input).toLowerCase(Locale.US);
if (result.isEmpty()) return null;
// Confirm that the IDN ToASCII result doesn't contain any illegal characters.
if (containsInvalidHostnameAsciiCodes(result)) {
return null;
}
// TODO: implement all label limits.
return result;
} catch (IllegalArgumentException e) {
return null;
}
}
/**
* Performs IDN ToASCII encoding and canonicalize the result to lowercase. e.g. This converts
* {@code ☃.net} to {@code xn--n3h.net}, and {@code WwW.GoOgLe.cOm} to {@code www.google.com}.
* {@code null} will be returned if the input cannot be ToASCII encoded or if the result
* contains unsupported ASCII characters.
*/
public static String domainToAscii(String input) {
try {
String result = IDN.toASCII(input).toLowerCase(Locale.US);
if (result.isEmpty()) return null;
// Confirm that the IDN ToASCII result doesn't contain any illegal characters.
if (containsInvalidHostnameAsciiCodes(result)) {
return null;
}
// TODO: implement all label limits.
return result;
} catch (IllegalArgumentException e) {
return null;
}
}
/**
* Checks whether a given string represents a valid host name for PKP and converts it
* to ASCII Compatible Encoding representation according to RFC 1122, RFC 1123 and
* RFC 3490. This method is more restrictive than required by RFC 7469. Thus, a host
* that contains digits and the dot character only is considered invalid.
*
* Note: Currently Cronet doesn't have native implementation of host name validation that
* can be used. There is code that parses a provided URL but doesn't ensure its
* correctness. The implementation relies on {@code getaddrinfo} function.
*
* @param hostName host name to check and convert.
* @return true if the string is a valid host name.
* @throws IllegalArgumentException if the the given string does not represent a valid
* hostname.
*/
private static String validateHostNameForPinningAndConvert(String hostName)
throws IllegalArgumentException {
if (INVALID_PKP_HOST_NAME.matcher(hostName).matches()) {
throw new IllegalArgumentException("Hostname " + hostName + " is illegal."
+ " A hostname should not consist of digits and/or dots only.");
}
// Workaround for crash, see crbug.com/634914
if (hostName.length() > 255) {
throw new IllegalArgumentException("Hostname " + hostName + " is too long."
+ " The name of the host does not comply with RFC 1122 and RFC 1123.");
}
try {
return IDN.toASCII(hostName, IDN.USE_STD3_ASCII_RULES);
} catch (IllegalArgumentException ex) {
throw new IllegalArgumentException("Hostname " + hostName + " is illegal."
+ " The name of the host does not comply with RFC 1122 and RFC 1123.");
}
}
@Override
public String filter(URL sourceUrl, Metadata sourceMetadata,
String urlToFilter) {
try {
URL url = new URL(urlToFilter);
String hostName = url.getHost();
if (isAscii(hostName)) {
return urlToFilter;
}
hostName = IDN.toASCII(url.getHost());
if (hostName.equals(url.getHost())) {
return urlToFilter;
}
urlToFilter = new URL(url.getProtocol(), hostName, url.getPort(),
url.getFile()).toString();
} catch (MalformedURLException e) {
return null;
}
return urlToFilter;
}
URL encodeUri(Uri uri) throws MalformedURLException {
StringBuilder uriStringBuilder = new StringBuilder();
uriStringBuilder.append(uri.getScheme()).append("://");
String host = IDN.toASCII(uri.getHost());
uriStringBuilder.append(host);
int port = uri.getPort();
if (port != -1) {
uriStringBuilder.append(':').append(port);
}
String path = uri.getEncodedPath();
if (!StringUtils.isEmpty(path)) {
encodeUriAppend(uriStringBuilder, path);
}
String query = uri.getEncodedQuery();
if (!StringUtils.isEmpty(query)) {
uriStringBuilder.append('?');
encodeUriAppend(uriStringBuilder, query);
}
return new URL(uriStringBuilder.toString());
}
/**
* {@link java.net.IDN#toUnicode(String)}
* @since 1.6
*/
public void test_ToUnicode_LString() {
try {
IDN.toUnicode(null);
fail("should throw NullPointerException");
} catch (NullPointerException e) {
// expected
}
assertEquals("", IDN.toUnicode(""));
assertEquals("www.bcher.de", IDN.toUnicode("www.bcher.de"));
assertEquals("www.b\u00FCcher.de", IDN.toUnicode("www.b\u00FCcher.de"));
assertEquals("www.\u65E5\u672C\u5E73.jp", IDN
.toUnicode("www.\u65E5\u672C\u5E73.jp"));
assertEquals("www.\u65E5\u672C\u5E73.jp", IDN.toUnicode("www\uFF0Exn--gwtq9nb2a\uFF61jp"));
assertEquals("www.\u65E5\u672C\u5E73.jp", IDN.toUnicode("www.xn--gwtq9nb2a.jp"));
}
public static String toASCII(String url) {
try {
URL u = new URL(url);
String host = u.getHost();
if (host == null || host.isEmpty()) {
// no host name => no punycoded domain name
// also do not add additional slashes for file: URLs (NUTCH-1880)
return url;
}
URI p = new URI(u.getProtocol(), u.getUserInfo(), IDN.toASCII(host),
u.getPort(), u.getPath(), u.getQuery(), u.getRef());
return p.toString();
} catch (Exception e) {
return null;
}
}
/**
* Performs IDN ToASCII encoding and canonicalize the result to lowercase. e.g. This converts
* {@code ☃.net} to {@code xn--n3h.net}, and {@code WwW.GoOgLe.cOm} to {@code www.google.com}.
* {@code null} will be returned if the input cannot be ToASCII encoded or if the result
* contains unsupported ASCII characters.
*/
public static String domainToAscii(String input) {
try {
String result = IDN.toASCII(input).toLowerCase(Locale.US);
if (result.isEmpty()) {
return null;
}
// Confirm that the IDN ToASCII result doesn't contain any illegal characters.
if (containsInvalidHostnameAsciiCodes(result)) {
return null;
}
// TODO: implement all label limits.
return result;
} catch (IllegalArgumentException e) {
return null;
}
}
public static String encodeDomainName(String domainName) throws Exception {
if (domainName == null) {
return null;
} else {
return IDN.toASCII(domainName);
}
}
/**
* {@link java.net.IDN#toUnicode(String, int)}
* @since 1.6
*/
public void test_ToUnicode_LString_I() {
assertEquals("", IDN.toUnicode("", IDN.ALLOW_UNASSIGNED));
assertEquals("www.f\u00E4rgbolaget.nu", IDN.toUnicode(
"www.f\u00E4rgbolaget.nu", IDN.USE_STD3_ASCII_RULES));
assertEquals("www.r\u00E4ksm\u00F6rg\u00E5s.nu", IDN.toUnicode(
"www.r\u00E4ksm\u00F6rg\u00E5s\u3002nu",
IDN.USE_STD3_ASCII_RULES));
// RI bug. It cannot parse "www.xn--gwtq9nb2a.jp" when
// USE_STD3_ASCII_RULES is set.
assertEquals("www.\u65E5\u672C\u5E73.jp", IDN.toUnicode(
"www\uFF0Exn--gwtq9nb2a\uFF61jp", IDN.USE_STD3_ASCII_RULES));
}
public static String punycodeDomain (String domain) {
try {
return IDN.toASCII (domain);
} catch (Exception e) {
return domain;
}
}
/**
* Attempts to match the given {@link SNIServerName}.
*
* @param serverName
* the {@link SNIServerName} instance on which this matcher
* performs match operations
*
* @return {@code true} if, and only if, the matcher matches the
* given {@code serverName}
*
* @throws NullPointerException if {@code serverName} is {@code null}
* @throws IllegalArgumentException if {@code serverName} is
* not of {@code StandardConstants#SNI_HOST_NAME} type
*
* @see SNIServerName
*/
@Override
public boolean matches(SNIServerName serverName) {
if (serverName == null) {
throw new NullPointerException(
"The SNIServerName argument cannot be null");
}
SNIHostName hostname;
if (!(serverName instanceof SNIHostName)) {
if (serverName.getType() != StandardConstants.SNI_HOST_NAME) {
throw new IllegalArgumentException(
"The server name type is not host_name");
}
try {
hostname = new SNIHostName(serverName.getEncoded());
} catch (NullPointerException | IllegalArgumentException e) {
return false;
}
} else {
hostname = (SNIHostName)serverName;
}
// Let's first try the ascii name matching
String asciiName = hostname.getAsciiName();
if (pattern.matcher(asciiName).matches()) {
return true;
}
// May be an internationalized domain name, check the Unicode
// representations.
return pattern.matcher(IDN.toUnicode(asciiName)).matches();
}
public SocksCmdRequest(SocksCmdType cmdType, SocksAddressType addressType, String host, int port) {
super(SocksRequestType.CMD);
if (cmdType == null) {
throw new NullPointerException("cmdType");
}
if (addressType == null) {
throw new NullPointerException("addressType");
}
if (host == null) {
throw new NullPointerException("host");
}
switch (addressType) {
case IPv4:
if (!NetUtil.isValidIpV4Address(host)) {
throw new IllegalArgumentException(host + " is not a valid IPv4 address");
}
break;
case DOMAIN:
String asciiHost = IDN.toASCII(host);
if (asciiHost.length() > 255) {
throw new IllegalArgumentException(host + " IDN: " + asciiHost + " exceeds 255 char limit");
}
host = asciiHost;
break;
case IPv6:
if (!NetUtil.isValidIpV6Address(host)) {
throw new IllegalArgumentException(host + " is not a valid IPv6 address");
}
break;
case UNKNOWN:
break;
}
if (port <= 0 || port >= 65536) {
throw new IllegalArgumentException(port + " is not in bounds 0 < x < 65536");
}
this.cmdType = cmdType;
this.addressType = addressType;
this.host = host;
this.port = port;
}
public static URL getIDNizedURL(URL inUrl) throws IllegalArgumentException {
try {
return new URL(inUrl.getProtocol(),
IDN.toASCII(inUrl.getHost()),
inUrl.getPort(),
inUrl.getFile());
}
catch(MalformedURLException ex) {
throw new IllegalArgumentException(ex);
}
}
/**
* Constructs new response and includes provided host and port as part of it.
*
* @param cmdStatus status of the response
* @param addressType type of host parameter
* @param host host (BND.ADDR field) is address that server used when connecting to the target host.
* When null a value of 4/8 0x00 octets will be used for IPv4/IPv6 and a single 0x00 byte will be
* used for domain addressType. Value is converted to ASCII using {@link IDN#toASCII(String)}.
* @param port port (BND.PORT field) that the server assigned to connect to the target host
* @throws NullPointerException in case cmdStatus or addressType are missing
* @throws IllegalArgumentException in case host or port cannot be validated
* @see IDN#toASCII(String)
*/
public SocksCmdResponse(SocksCmdStatus cmdStatus, SocksAddressType addressType, String host, int port) {
super(SocksResponseType.CMD);
if (cmdStatus == null) {
throw new NullPointerException("cmdStatus");
}
if (addressType == null) {
throw new NullPointerException("addressType");
}
if (host != null) {
switch (addressType) {
case IPv4:
if (!NetUtil.isValidIpV4Address(host)) {
throw new IllegalArgumentException(host + " is not a valid IPv4 address");
}
break;
case DOMAIN:
String asciiHost = IDN.toASCII(host);
if (asciiHost.length() > 255) {
throw new IllegalArgumentException(host + " IDN: " + asciiHost + " exceeds 255 char limit");
}
host = asciiHost;
break;
case IPv6:
if (!NetUtil.isValidIpV6Address(host)) {
throw new IllegalArgumentException(host + " is not a valid IPv6 address");
}
break;
case UNKNOWN:
break;
}
}
if (port < 0 || port > 65535) {
throw new IllegalArgumentException(port + " is not in bounds 0 <= x <= 65535");
}
this.cmdStatus = cmdStatus;
this.addressType = addressType;
this.host = host;
this.port = port;
}
@Nullable
private static String normalizeHostname(String line) {
final String hostname = IDN.toASCII(line.trim(), IDN.ALLOW_UNASSIGNED);
if (!HOSTNAME_PATTERN.matcher(hostname).matches()) {
return null;
}
return Ascii.toLowerCase(hostname);
}
public DefaultSocks5CommandResponse(
Socks5CommandStatus status, Socks5AddressType bndAddrType, String bndAddr, int bndPort) {
if (status == null) {
throw new NullPointerException("status");
}
if (bndAddrType == null) {
throw new NullPointerException("bndAddrType");
}
if (bndAddr != null) {
if (bndAddrType == Socks5AddressType.IPv4) {
if (!NetUtil.isValidIpV4Address(bndAddr)) {
throw new IllegalArgumentException("bndAddr: " + bndAddr + " (expected: a valid IPv4 address)");
}
} else if (bndAddrType == Socks5AddressType.DOMAIN) {
bndAddr = IDN.toASCII(bndAddr);
if (bndAddr.length() > 255) {
throw new IllegalArgumentException("bndAddr: " + bndAddr + " (expected: less than 256 chars)");
}
} else if (bndAddrType == Socks5AddressType.IPv6) {
if (!NetUtil.isValidIpV6Address(bndAddr)) {
throw new IllegalArgumentException("bndAddr: " + bndAddr + " (expected: a valid IPv6 address)");
}
}
}
if (bndPort < 0 || bndPort > 65535) {
throw new IllegalArgumentException("bndPort: " + bndPort + " (expected: 0~65535)");
}
this.status = status;
this.bndAddrType = bndAddrType;
this.bndAddr = bndAddr;
this.bndPort = bndPort;
}
@Override
public Set<String> generateCandidates(String originalString) {
Set<String> result = new HashSet<>();
String domain = originalString;
if(StringUtils.isEmpty(domain)) {
return result;
}
if(isAce(domain)) {
//this is an ace domain.
domain = IDN.toUnicode(domain);
}
for(int ws = 0;ws < domain.length();ws++) {
for(int i = 0;i < domain.length() - ws + 1;++i) {
String win = domain.substring(i, i+ws);
for(int j = 0;j < ws;j++) {
char c = win.charAt(j);
if( glyphs.containsKey(c)) {
for( String g : glyphs.get(c)) {
String winNew = win.replaceAll("" + c, g);
String d = domain.substring(0, i) + winNew + domain.substring(i + ws);
result.add(d);
if(!isAce(d)) {
try {
String dAscii = IDN.toASCII(d, IDN.ALLOW_UNASSIGNED);
if (!d.equals(dAscii)) {
result.add(dAscii);
}
}
catch(IllegalArgumentException iae) {
LOG.debug("Unable to parse " + d + ": " + iae.getMessage(), iae);
}
}
}
}
}
}
}
return result;
}
/**
* IDNA ASCII conversion and case normalization IDNA ASCII转换和大小写规范化
*/
static String normalizeHostname(String hostname) {
if (needsNormalization(hostname)) {
hostname = IDN.toASCII(hostname, IDN.ALLOW_UNASSIGNED);
}
return hostname.toLowerCase(Locale.US);
}
/**
* Attempts to match the given {@link SNIServerName}.
*
* @param serverName
* the {@link SNIServerName} instance on which this matcher
* performs match operations
*
* @return {@code true} if, and only if, the matcher matches the
* given {@code serverName}
*
* @throws NullPointerException if {@code serverName} is {@code null}
* @throws IllegalArgumentException if {@code serverName} is
* not of {@code StandardConstants#SNI_HOST_NAME} type
*
* @see SNIServerName
*/
@Override
public boolean matches(SNIServerName serverName) {
if (serverName == null) {
throw new NullPointerException(
"The SNIServerName argument cannot be null");
}
SNIHostName hostname;
if (!(serverName instanceof SNIHostName)) {
if (serverName.getType() != StandardConstants.SNI_HOST_NAME) {
throw new IllegalArgumentException(
"The server name type is not host_name");
}
try {
hostname = new SNIHostName(serverName.getEncoded());
} catch (NullPointerException | IllegalArgumentException e) {
return false;
}
} else {
hostname = (SNIHostName)serverName;
}
// Let's first try the ascii name matching
String asciiName = hostname.getAsciiName();
if (pattern.matcher(asciiName).matches()) {
return true;
}
// May be an internationalized domain name, check the Unicode
// representations.
return pattern.matcher(IDN.toUnicode(asciiName)).matches();
}
/**
* List duplicate systems by hostname
* @param user the user doing the search
* @param inactiveHours the number of hours a system hasn't checked in
* to consider it inactive
* @return List of DuplicateSystemBucket objects
*/
public static List<DuplicateSystemGrouping> listDuplicatesByHostname(User user,
Long inactiveHours) {
List<DuplicateSystemGrouping> duplicateSystems = listDuplicates(user,
"duplicate_system_ids_hostname",
new ArrayList<String>(), inactiveHours);
ListIterator<DuplicateSystemGrouping> litr = duplicateSystems.listIterator();
while (litr.hasNext()) {
DuplicateSystemGrouping element = litr.next();
element.setKey(IDN.toUnicode(element.getKey()));
}
return duplicateSystems;
}
/**
* Converts an internationalized domain name (IDN) in an URL to and from ASCII/Unicode.
* @param url the URL where the domain name should be converted
* @param toASCII if true converts from Unicode to ASCII, if false converts from ASCII to Unicode
* @return the URL containing the converted domain name
*/
@TargetApi(Build.VERSION_CODES.GINGERBREAD)
public static String convertIdn(String url, boolean toASCII) {
String urlNoDots = url;
String dots="";
while (urlNoDots.startsWith(".")) {
urlNoDots = url.substring(1);
dots = dots + ".";
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
// Find host name after '//' or '@'
int hostStart = 0;
if (urlNoDots.contains("//")) {
hostStart = url.indexOf("//") + "//".length();
} else if (url.contains("@")) {
hostStart = url.indexOf("@") + "@".length();
}
int hostEnd = url.substring(hostStart).indexOf("/");
// Handle URL which doesn't have a path (path is implicitly '/')
hostEnd = (hostEnd == -1 ? urlNoDots.length() : hostStart + hostEnd);
String host = urlNoDots.substring(hostStart, hostEnd);
host = (toASCII ? IDN.toASCII(host) : IDN.toUnicode(host));
return dots + urlNoDots.substring(0, hostStart) + host + urlNoDots.substring(hostEnd);
} else {
return dots + url;
}
}
/**
* IDNA ASCII conversion and case normalization
*/
private static String normalizeHostname(String hostname) {
if (needsNormalization(hostname)) {
hostname = IDN.toASCII(hostname, IDN.ALLOW_UNASSIGNED);
}
return hostname.toLowerCase(Locale.US);
}
/**
* Normalise ENS name as per the
* <a href="http://docs.ens.domains/en/latest/implementers.html#normalising-and-validating-names">specification</a>.
*
* @param ensName our user input ENS name
* @return normalised ens name
* @throws EnsResolutionException if the name cannot be normalised
*/
static String normalise(String ensName) {
try {
return IDN.toASCII(ensName, IDN.USE_STD3_ASCII_RULES)
.toLowerCase();
} catch (IllegalArgumentException e) {
throw new EnsResolutionException("Invalid ENS name provided: " + ensName);
}
}
/**
* Returns the effective top-level domain plus one (eTLD+1) by referencing the public suffix list.
* Returns null if the domain is a public suffix.
*
* <p>Here are some examples: <pre>{@code
* assertEquals("google.com", getEffectiveTldPlusOne("google.com"));
* assertEquals("google.com", getEffectiveTldPlusOne("www.google.com"));
* assertNull(getEffectiveTldPlusOne("com"));
* }</pre>
*
* @param domain A canonicalized domain. An International Domain Name (IDN) should be punycode
* encoded.
*/
public String getEffectiveTldPlusOne(String domain) {
if (domain == null) throw new NullPointerException("domain == null");
// We use UTF-8 in the list so we need to convert to Unicode.
String unicodeDomain = IDN.toUnicode(domain);
String[] domainLabels = unicodeDomain.split("\\.");
String[] rule = findMatchingRule(domainLabels);
if (domainLabels.length == rule.length && rule[0].charAt(0) != EXCEPTION_MARKER) {
// The domain is a public suffix.
return null;
}
int firstLabelOffset;
if (rule[0].charAt(0) == EXCEPTION_MARKER) {
// Exception rules hold the effective TLD plus one.
firstLabelOffset = domainLabels.length - rule.length;
} else {
// Otherwise the rule is for a public suffix, so we must take one more label.
firstLabelOffset = domainLabels.length - (rule.length + 1);
}
StringBuilder effectiveTldPlusOne = new StringBuilder();
String[] punycodeLabels = domain.split("\\.");
for (int i = firstLabelOffset; i < punycodeLabels.length; i++) {
effectiveTldPlusOne.append(punycodeLabels[i]).append('.');
}
effectiveTldPlusOne.deleteCharAt(effectiveTldPlusOne.length() - 1);
return effectiveTldPlusOne.toString();
}
/**
* IDNA ASCII conversion, case normalization and validation.
*/
static String normalizeHostnamePattern(String hostnamePattern) {
requireNonNull(hostnamePattern, "hostnamePattern");
if (needsNormalization(hostnamePattern)) {
hostnamePattern = IDN.toASCII(hostnamePattern, IDN.ALLOW_UNASSIGNED);
}
if (!"*".equals(hostnamePattern) &&
!HOSTNAME_PATTERN.matcher(hostnamePattern.startsWith("*.") ? hostnamePattern.substring(2)
: hostnamePattern).matches()) {
throw new IllegalArgumentException("hostnamePattern: " + hostnamePattern);
}
return Ascii.toLowerCase(hostnamePattern);
}
/**
* Attempts to match the given {@link SNIServerName}.
*
* @param serverName
* the {@link SNIServerName} instance on which this matcher
* performs match operations
*
* @return {@code true} if, and only if, the matcher matches the
* given {@code serverName}
*
* @throws NullPointerException if {@code serverName} is {@code null}
* @throws IllegalArgumentException if {@code serverName} is
* not of {@code StandardConstants#SNI_HOST_NAME} type
*
* @see SNIServerName
*/
@Override
public boolean matches(SNIServerName serverName) {
if (serverName == null) {
throw new NullPointerException(
"The SNIServerName argument cannot be null");
}
SNIHostName hostname;
if (!(serverName instanceof SNIHostName)) {
if (serverName.getType() != StandardConstants.SNI_HOST_NAME) {
throw new IllegalArgumentException(
"The server name type is not host_name");
}
try {
hostname = new SNIHostName(serverName.getEncoded());
} catch (NullPointerException | IllegalArgumentException e) {
return false;
}
} else {
hostname = (SNIHostName)serverName;
}
// Let's first try the ascii name matching
String asciiName = hostname.getAsciiName();
if (pattern.matcher(asciiName).matches()) {
return true;
}
// May be an internationalized domain name, check the Unicode
// representations.
return pattern.matcher(IDN.toUnicode(asciiName)).matches();
}