Java Code Examples for java.net.IDN#toASCII()

The following examples show how to use java.net.IDN#toASCII() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: SocksCmdRequest.java    From netty4.0.27Learn with Apache License 2.0 5 votes vote down vote up
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:
            if (IDN.toASCII(host).length() > 255) {
                throw new IllegalArgumentException(host + " IDN: " + IDN.toASCII(host) + " exceeds 255 char limit");
            }
            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 = IDN.toASCII(host);
    this.port = port;
}
 
Example 2
Source File: DisplayUtils.java    From Cirrus_depricated with GNU General Public License v2.0 5 votes vote down vote up
/**
 * 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;
    }
}
 
Example 3
Source File: IDNStringUtil.java    From cronet with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
/**
 * Attempts to convert a Unicode string to an ASCII string using IDN rules.
 * As of May 2014, the underlying Java function IDNA2003.
 * @param src String to convert.
 * @return: String containing only ASCII characters on success, null on
 *                 failure.
 */
@CalledByNative
private static String idnToASCII(String src) {
    try {
        return IDN.toASCII(src, IDN.USE_STD3_ASCII_RULES);
    } catch (Exception e) {
        return null;
    }
}
 
Example 4
Source File: VirtualHost.java    From armeria with Apache License 2.0 5 votes vote down vote up
/**
 * IDNA ASCII conversion, case normalization and validation.
 */
static String normalizeDefaultHostname(String defaultHostname) {
    requireNonNull(defaultHostname, "defaultHostname");
    if (needsNormalization(defaultHostname)) {
        defaultHostname = IDN.toASCII(defaultHostname, IDN.ALLOW_UNASSIGNED);
    }

    if (!HOSTNAME_PATTERN.matcher(defaultHostname).matches()) {
        throw new IllegalArgumentException("defaultHostname: " + defaultHostname);
    }

    return Ascii.toLowerCase(defaultHostname);
}
 
Example 5
Source File: IDNTest.java    From j2objc with Apache License 2.0 5 votes vote down vote up
/**
 * {@link java.net.IDN#toASCII(String)}
 * @since 1.6
 */
public void test_ToASCII_LString() {
    try {
        IDN.toASCII(null);
        fail("should throw NullPointerException");
    } catch (NullPointerException e) {
        // expected
    }

    assertEquals("www.xn--gwtq9nb2a.jp", IDN
            .toASCII("www.\u65E5\u672C\u5E73.jp"));
    assertEquals(
            "www.xn--vckk7bxa0eza9ezc9d.com",
            IDN
                    .toASCII("www.\u30CF\u30F3\u30C9\u30DC\u30FC\u30EB\u30B5\u30E0\u30BA.com"));
    assertEquals("www.xn--frgbolaget-q5a.nu", IDN
            .toASCII("www.f\u00E4rgbolaget.nu"));
    assertEquals("www.xn--bcher-kva.de", IDN.toASCII("www.b\u00FCcher.de"));
    assertEquals("www.xn--brndendekrlighed-vobh.com", IDN
            .toASCII("www.br\u00E6ndendek\u00E6rlighed.com"));
    assertEquals("www.xn--rksmrgs-5wao1o.se", IDN
            .toASCII("www.r\u00E4ksm\u00F6rg\u00E5s.se"));
    assertEquals("www.xn--9d0bm53a3xbzui.com", IDN
            .toASCII("www.\uC608\uBE44\uAD50\uC0AC.com"));
    assertEquals("xn--lck1c3crb1723bpq4a.com", IDN
            .toASCII("\u7406\u5BB9\u30CA\u30AB\u30E0\u30E9.com"));
    assertEquals("xn--l8je6s7a45b.org", IDN
            .toASCII("\u3042\u30FC\u308B\u3044\u3093.org"));
    assertEquals("www.xn--frjestadsbk-l8a.net", IDN
            .toASCII("www.f\u00E4rjestadsbk.net"));
    assertEquals("www.xn--mkitorppa-v2a.edu", IDN
            .toASCII("www.m\u00E4kitorppa.edu"));
}
 
Example 6
Source File: AlertsCreator.java    From Telegram-FOSS with GNU General Public License v2.0 5 votes vote down vote up
public static void showOpenUrlAlert(BaseFragment fragment, String url, boolean punycode, boolean tryTelegraph, boolean ask) {
    if (fragment == null || fragment.getParentActivity() == null) {
        return;
    }
    long inlineReturn = (fragment instanceof ChatActivity) ? ((ChatActivity) fragment).getInlineReturn() : 0;
    if (Browser.isInternalUrl(url, null) || !ask) {
        Browser.openUrl(fragment.getParentActivity(), url, inlineReturn == 0, tryTelegraph);
    } else {
        String urlFinal;
        if (punycode) {
            try {
                Uri uri = Uri.parse(url);
                String host = IDN.toASCII(uri.getHost(), IDN.ALLOW_UNASSIGNED);
                urlFinal = uri.getScheme() + "://" + host + uri.getPath();
            } catch (Exception e) {
                FileLog.e(e);
                urlFinal = url;
            }
        } else {
            urlFinal = url;
        }
        AlertDialog.Builder builder = new AlertDialog.Builder(fragment.getParentActivity());
        builder.setTitle(LocaleController.getString("OpenUrlTitle", R.string.OpenUrlTitle));
        String format = LocaleController.getString("OpenUrlAlert2", R.string.OpenUrlAlert2);
        int index = format.indexOf("%");
        SpannableStringBuilder stringBuilder = new SpannableStringBuilder(String.format(format, urlFinal));
        if (index >= 0) {
            stringBuilder.setSpan(new URLSpan(urlFinal), index, index + urlFinal.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        }
        builder.setMessage(stringBuilder);
        builder.setMessageTextViewClickable(false);
        builder.setPositiveButton(LocaleController.getString("Open", R.string.Open), (dialogInterface, i) -> Browser.openUrl(fragment.getParentActivity(), url, inlineReturn == 0, tryTelegraph));
        builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null);
        fragment.showDialog(builder.create());
    }
}
 
Example 7
Source File: SystemInfo.java    From armeria with Apache License 2.0 5 votes vote down vote up
@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);
}
 
Example 8
Source File: DomainNameMapping.java    From netty-4.1.22 with Apache License 2.0 5 votes vote down vote up
/**
 * 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);
}
 
Example 9
Source File: VirtualHost.java    From armeria with Apache License 2.0 5 votes vote down vote up
/**
 * 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);
}
 
Example 10
Source File: HomoglyphStrategy.java    From metron with Apache License 2.0 5 votes vote down vote up
@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;
}
 
Example 11
Source File: DefaultSocks5CommandResponse.java    From netty-4.1.22 with Apache License 2.0 5 votes vote down vote up
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;
}
 
Example 12
Source File: DefaultSocks5CommandRequest.java    From netty-4.1.22 with Apache License 2.0 5 votes vote down vote up
public DefaultSocks5CommandRequest(
        Socks5CommandType type, Socks5AddressType dstAddrType, String dstAddr, int dstPort) {

    if (type == null) {
        throw new NullPointerException("type");
    }
    if (dstAddrType == null) {
        throw new NullPointerException("dstAddrType");
    }
    if (dstAddr == null) {
        throw new NullPointerException("dstAddr");
    }

    if (dstAddrType == Socks5AddressType.IPv4) {
        if (!NetUtil.isValidIpV4Address(dstAddr)) {
            throw new IllegalArgumentException("dstAddr: " + dstAddr + " (expected: a valid IPv4 address)");
        }
    } else if (dstAddrType == Socks5AddressType.DOMAIN) {
        dstAddr = IDN.toASCII(dstAddr);
        if (dstAddr.length() > 255) {
            throw new IllegalArgumentException("dstAddr: " + dstAddr + " (expected: less than 256 chars)");
        }
    } else if (dstAddrType == Socks5AddressType.IPv6) {
        if (!NetUtil.isValidIpV6Address(dstAddr)) {
            throw new IllegalArgumentException("dstAddr: " + dstAddr + " (expected: a valid IPv6 address");
        }
    }

    if (dstPort < 0 || dstPort > 65535) {
        throw new IllegalArgumentException("dstPort: " + dstPort + " (expected: 0~65535)");
    }

    this.type = type;
    this.dstAddrType = dstAddrType;
    this.dstAddr = dstAddr;
    this.dstPort = dstPort;
}
 
Example 13
Source File: StringUtils.java    From Openfire with Apache License 2.0 5 votes vote down vote up
/**
 * Returns a valid domain name, possibly as an ACE-encoded IDN 
 * (per <a href="http://www.ietf.org/rfc/rfc3490.txt">RFC 3490</a>).
 * 
 * @param domain Proposed domain name
 * @return The validated domain name, possibly ACE-encoded
 * @throws IllegalArgumentException The given domain name is not valid
 */
public static String validateDomainName(String domain) {
    if (domain == null || domain.trim().length() == 0) {
        throw new IllegalArgumentException("Domain name cannot be null or empty");
    }
    String result = IDN.toASCII(domain);
    if (result.equals(domain)) {
        // no conversion; validate again via USE_STD3_ASCII_RULES
        IDN.toASCII(domain, IDN.USE_STD3_ASCII_RULES);
    } else {
        Log.info(MessageFormat.format("Converted domain name: from '{0}' to '{1}'",  domain, result));
    }
    return result;
}
 
Example 14
Source File: Hosts.java    From urllib with Apache License 2.0 5 votes vote down vote up
private static String validateAndConvertToAscii(String hostname) {
  String ascii;
  try {
    ascii = IDN.toASCII(PercentDecoder.decodeUnreserved(hostname), IDN.ALLOW_UNASSIGNED);
  } catch (IllegalArgumentException e) {
    throw new IllegalArgumentException("Invalid hostname: " + hostname);
  }

  if (ascii.isEmpty() || ".".equals(ascii)) {
    throw new IllegalArgumentException("Invalid hostname: cannot be null or empty.");
  }

  return ascii;
}
 
Example 15
Source File: PunycodeCodec.java    From openemm with GNU Affero General Public License v3.0 5 votes vote down vote up
public static String encodeDomainName(String domainName) throws Exception {
	if (domainName == null) {
		return null;
	} else {
		return IDN.toASCII(domainName);
	}
}
 
Example 16
Source File: SNIHostName.java    From TencentKona-8 with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Creates an {@code SNIHostName} using the specified encoded value.
 * <P>
 * This method is normally used to parse the encoded name value in a
 * requested SNI extension.
 * <P>
 * Per <A HREF="http://www.ietf.org/rfc/rfc6066.txt">RFC 6066</A>,
 * the encoded name value of a hostname is
 * {@link StandardCharsets#US_ASCII}-compliant.  However, in the previous
 * version of the SNI extension (
 * <A HREF="http://www.ietf.org/rfc/rfc4366.txt">RFC 4366</A>),
 * the encoded hostname is represented as a byte string using UTF-8
 * encoding.  For the purpose of version tolerance, this method allows
 * that the charset of {@code encoded} argument can be
 * {@link StandardCharsets#UTF_8}, as well as
 * {@link StandardCharsets#US_ASCII}.  {@link IDN#toASCII(String)} is used
 * to translate the {@code encoded} argument into ASCII Compatible
 * Encoding (ACE) hostname.
 * <P>
 * It is strongly recommended that this constructor is only used to parse
 * the encoded name value in a requested SNI extension.  Otherwise, to
 * comply with <A HREF="http://www.ietf.org/rfc/rfc6066.txt">RFC 6066</A>,
 * please always use {@link StandardCharsets#US_ASCII}-compliant charset
 * and enforce the restrictions on ASCII characters in hostnames (see
 * <A HREF="http://www.ietf.org/rfc/rfc3490.txt">RFC 3490</A>,
 * <A HREF="http://www.ietf.org/rfc/rfc1122.txt">RFC 1122</A>,
 * <A HREF="http://www.ietf.org/rfc/rfc1123.txt">RFC 1123</A>)
 * for {@code encoded} argument, or use
 * {@link SNIHostName#SNIHostName(String)} instead.
 * <P>
 * The {@code encoded} argument is illegal if it:
 * <ul>
 * <li> {@code encoded} is empty,</li>
 * <li> {@code encoded} ends with a trailing dot,</li>
 * <li> {@code encoded} is not encoded in
 *      {@link StandardCharsets#US_ASCII} or
 *      {@link StandardCharsets#UTF_8}-compliant charset,</li>
 * <li> {@code encoded} is not a valid Internationalized
 *      Domain Name (IDN) compliant with the RFC 3490 specification.</li>
 * </ul>
 *
 * <P>
 * Note that the {@code encoded} byte array is cloned
 * to protect against subsequent modification.
 *
 * @param  encoded
 *         the encoded hostname of this server name
 *
 * @throws NullPointerException if {@code encoded} is {@code null}
 * @throws IllegalArgumentException if {@code encoded} is illegal
 */
public SNIHostName(byte[] encoded) {
    // NullPointerException will be thrown if {@code encoded} is null
    super(StandardConstants.SNI_HOST_NAME, encoded);

    // Compliance: RFC 4366 requires that the hostname is represented
    // as a byte string using UTF_8 encoding [UTF8]
    try {
        // Please don't use {@link String} constructors because they
        // do not report coding errors.
        CharsetDecoder decoder = StandardCharsets.UTF_8.newDecoder()
                .onMalformedInput(CodingErrorAction.REPORT)
                .onUnmappableCharacter(CodingErrorAction.REPORT);

        this.hostname = IDN.toASCII(
                decoder.decode(ByteBuffer.wrap(encoded)).toString());
    } catch (RuntimeException | CharacterCodingException e) {
        throw new IllegalArgumentException(
                    "The encoded server name value is invalid", e);
    }

    // check the validity of the string hostname
    checkHostName();
}
 
Example 17
Source File: SNIHostName.java    From openjdk-8-source with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Creates an {@code SNIHostName} using the specified encoded value.
 * <P>
 * This method is normally used to parse the encoded name value in a
 * requested SNI extension.
 * <P>
 * Per <A HREF="http://www.ietf.org/rfc/rfc6066.txt">RFC 6066</A>,
 * the encoded name value of a hostname is
 * {@link StandardCharsets#US_ASCII}-compliant.  However, in the previous
 * version of the SNI extension (
 * <A HREF="http://www.ietf.org/rfc/rfc4366.txt">RFC 4366</A>),
 * the encoded hostname is represented as a byte string using UTF-8
 * encoding.  For the purpose of version tolerance, this method allows
 * that the charset of {@code encoded} argument can be
 * {@link StandardCharsets#UTF_8}, as well as
 * {@link StandardCharsets#US_ASCII}.  {@link IDN#toASCII(String)} is used
 * to translate the {@code encoded} argument into ASCII Compatible
 * Encoding (ACE) hostname.
 * <P>
 * It is strongly recommended that this constructor is only used to parse
 * the encoded name value in a requested SNI extension.  Otherwise, to
 * comply with <A HREF="http://www.ietf.org/rfc/rfc6066.txt">RFC 6066</A>,
 * please always use {@link StandardCharsets#US_ASCII}-compliant charset
 * and enforce the restrictions on ASCII characters in hostnames (see
 * <A HREF="http://www.ietf.org/rfc/rfc3490.txt">RFC 3490</A>,
 * <A HREF="http://www.ietf.org/rfc/rfc1122.txt">RFC 1122</A>,
 * <A HREF="http://www.ietf.org/rfc/rfc1123.txt">RFC 1123</A>)
 * for {@code encoded} argument, or use
 * {@link SNIHostName#SNIHostName(String)} instead.
 * <P>
 * The {@code encoded} argument is illegal if it:
 * <ul>
 * <li> {@code encoded} is empty,</li>
 * <li> {@code encoded} ends with a trailing dot,</li>
 * <li> {@code encoded} is not encoded in
 *      {@link StandardCharsets#US_ASCII} or
 *      {@link StandardCharsets#UTF_8}-compliant charset,</li>
 * <li> {@code encoded} is not a valid Internationalized
 *      Domain Name (IDN) compliant with the RFC 3490 specification.</li>
 * </ul>
 *
 * <P>
 * Note that the {@code encoded} byte array is cloned
 * to protect against subsequent modification.
 *
 * @param  encoded
 *         the encoded hostname of this server name
 *
 * @throws NullPointerException if {@code encoded} is {@code null}
 * @throws IllegalArgumentException if {@code encoded} is illegal
 */
public SNIHostName(byte[] encoded) {
    // NullPointerException will be thrown if {@code encoded} is null
    super(StandardConstants.SNI_HOST_NAME, encoded);

    // Compliance: RFC 4366 requires that the hostname is represented
    // as a byte string using UTF_8 encoding [UTF8]
    try {
        // Please don't use {@link String} constructors because they
        // do not report coding errors.
        CharsetDecoder decoder = StandardCharsets.UTF_8.newDecoder()
                .onMalformedInput(CodingErrorAction.REPORT)
                .onUnmappableCharacter(CodingErrorAction.REPORT);

        this.hostname = IDN.toASCII(
                decoder.decode(ByteBuffer.wrap(encoded)).toString());
    } catch (RuntimeException | CharacterCodingException e) {
        throw new IllegalArgumentException(
                    "The encoded server name value is invalid", e);
    }

    // check the validity of the string hostname
    checkHostName();
}
 
Example 18
Source File: DnsQuestionWithoutTrailingDot.java    From armeria with Apache License 2.0 4 votes vote down vote up
private DnsQuestionWithoutTrailingDot(String name, DnsRecordType type) {
    this.name = IDN.toASCII(requireNonNull(name, "name"));
    this.type = requireNonNull(type, "type");
}
 
Example 19
Source File: SNIHostName.java    From jdk8u_jdk with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Creates an {@code SNIHostName} using the specified encoded value.
 * <P>
 * This method is normally used to parse the encoded name value in a
 * requested SNI extension.
 * <P>
 * Per <A HREF="http://www.ietf.org/rfc/rfc6066.txt">RFC 6066</A>,
 * the encoded name value of a hostname is
 * {@link StandardCharsets#US_ASCII}-compliant.  However, in the previous
 * version of the SNI extension (
 * <A HREF="http://www.ietf.org/rfc/rfc4366.txt">RFC 4366</A>),
 * the encoded hostname is represented as a byte string using UTF-8
 * encoding.  For the purpose of version tolerance, this method allows
 * that the charset of {@code encoded} argument can be
 * {@link StandardCharsets#UTF_8}, as well as
 * {@link StandardCharsets#US_ASCII}.  {@link IDN#toASCII(String)} is used
 * to translate the {@code encoded} argument into ASCII Compatible
 * Encoding (ACE) hostname.
 * <P>
 * It is strongly recommended that this constructor is only used to parse
 * the encoded name value in a requested SNI extension.  Otherwise, to
 * comply with <A HREF="http://www.ietf.org/rfc/rfc6066.txt">RFC 6066</A>,
 * please always use {@link StandardCharsets#US_ASCII}-compliant charset
 * and enforce the restrictions on ASCII characters in hostnames (see
 * <A HREF="http://www.ietf.org/rfc/rfc3490.txt">RFC 3490</A>,
 * <A HREF="http://www.ietf.org/rfc/rfc1122.txt">RFC 1122</A>,
 * <A HREF="http://www.ietf.org/rfc/rfc1123.txt">RFC 1123</A>)
 * for {@code encoded} argument, or use
 * {@link SNIHostName#SNIHostName(String)} instead.
 * <P>
 * The {@code encoded} argument is illegal if it:
 * <ul>
 * <li> {@code encoded} is empty,</li>
 * <li> {@code encoded} ends with a trailing dot,</li>
 * <li> {@code encoded} is not encoded in
 *      {@link StandardCharsets#US_ASCII} or
 *      {@link StandardCharsets#UTF_8}-compliant charset,</li>
 * <li> {@code encoded} is not a valid Internationalized
 *      Domain Name (IDN) compliant with the RFC 3490 specification.</li>
 * </ul>
 *
 * <P>
 * Note that the {@code encoded} byte array is cloned
 * to protect against subsequent modification.
 *
 * @param  encoded
 *         the encoded hostname of this server name
 *
 * @throws NullPointerException if {@code encoded} is {@code null}
 * @throws IllegalArgumentException if {@code encoded} is illegal
 */
public SNIHostName(byte[] encoded) {
    // NullPointerException will be thrown if {@code encoded} is null
    super(StandardConstants.SNI_HOST_NAME, encoded);

    // Compliance: RFC 4366 requires that the hostname is represented
    // as a byte string using UTF_8 encoding [UTF8]
    try {
        // Please don't use {@link String} constructors because they
        // do not report coding errors.
        CharsetDecoder decoder = StandardCharsets.UTF_8.newDecoder()
                .onMalformedInput(CodingErrorAction.REPORT)
                .onUnmappableCharacter(CodingErrorAction.REPORT);

        this.hostname = IDN.toASCII(
                decoder.decode(ByteBuffer.wrap(encoded)).toString());
    } catch (RuntimeException | CharacterCodingException e) {
        throw new IllegalArgumentException(
                    "The encoded server name value is invalid", e);
    }

    // check the validity of the string hostname
    checkHostName();
}
 
Example 20
Source File: SNIHostName.java    From openjdk-jdk8u-backup with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Creates an {@code SNIHostName} using the specified encoded value.
 * <P>
 * This method is normally used to parse the encoded name value in a
 * requested SNI extension.
 * <P>
 * Per <A HREF="http://www.ietf.org/rfc/rfc6066.txt">RFC 6066</A>,
 * the encoded name value of a hostname is
 * {@link StandardCharsets#US_ASCII}-compliant.  However, in the previous
 * version of the SNI extension (
 * <A HREF="http://www.ietf.org/rfc/rfc4366.txt">RFC 4366</A>),
 * the encoded hostname is represented as a byte string using UTF-8
 * encoding.  For the purpose of version tolerance, this method allows
 * that the charset of {@code encoded} argument can be
 * {@link StandardCharsets#UTF_8}, as well as
 * {@link StandardCharsets#US_ASCII}.  {@link IDN#toASCII(String)} is used
 * to translate the {@code encoded} argument into ASCII Compatible
 * Encoding (ACE) hostname.
 * <P>
 * It is strongly recommended that this constructor is only used to parse
 * the encoded name value in a requested SNI extension.  Otherwise, to
 * comply with <A HREF="http://www.ietf.org/rfc/rfc6066.txt">RFC 6066</A>,
 * please always use {@link StandardCharsets#US_ASCII}-compliant charset
 * and enforce the restrictions on ASCII characters in hostnames (see
 * <A HREF="http://www.ietf.org/rfc/rfc3490.txt">RFC 3490</A>,
 * <A HREF="http://www.ietf.org/rfc/rfc1122.txt">RFC 1122</A>,
 * <A HREF="http://www.ietf.org/rfc/rfc1123.txt">RFC 1123</A>)
 * for {@code encoded} argument, or use
 * {@link SNIHostName#SNIHostName(String)} instead.
 * <P>
 * The {@code encoded} argument is illegal if it:
 * <ul>
 * <li> {@code encoded} is empty,</li>
 * <li> {@code encoded} ends with a trailing dot,</li>
 * <li> {@code encoded} is not encoded in
 *      {@link StandardCharsets#US_ASCII} or
 *      {@link StandardCharsets#UTF_8}-compliant charset,</li>
 * <li> {@code encoded} is not a valid Internationalized
 *      Domain Name (IDN) compliant with the RFC 3490 specification.</li>
 * </ul>
 *
 * <P>
 * Note that the {@code encoded} byte array is cloned
 * to protect against subsequent modification.
 *
 * @param  encoded
 *         the encoded hostname of this server name
 *
 * @throws NullPointerException if {@code encoded} is {@code null}
 * @throws IllegalArgumentException if {@code encoded} is illegal
 */
public SNIHostName(byte[] encoded) {
    // NullPointerException will be thrown if {@code encoded} is null
    super(StandardConstants.SNI_HOST_NAME, encoded);

    // Compliance: RFC 4366 requires that the hostname is represented
    // as a byte string using UTF_8 encoding [UTF8]
    try {
        // Please don't use {@link String} constructors because they
        // do not report coding errors.
        CharsetDecoder decoder = StandardCharsets.UTF_8.newDecoder()
                .onMalformedInput(CodingErrorAction.REPORT)
                .onUnmappableCharacter(CodingErrorAction.REPORT);

        this.hostname = IDN.toASCII(
                decoder.decode(ByteBuffer.wrap(encoded)).toString());
    } catch (RuntimeException | CharacterCodingException e) {
        throw new IllegalArgumentException(
                    "The encoded server name value is invalid", e);
    }

    // check the validity of the string hostname
    checkHostName();
}