/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.wildfly.security.util; import static org.wildfly.security._private.ElytronMessages.log; import java.net.Inet6Address; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.SocketAddress; import java.net.URI; import java.net.URISyntaxException; import java.net.UnknownHostException; /** * Utilities for URI manipulation and canonicalization. * * @author <a href="mailto:david.lloyd@redhat.com">David M. Lloyd</a> */ public final class URIUtil { private URIUtil() {} /** * Get the URI-friendly host name for the given socket address, without doing a reverse lookup under any circumstances. * * @param socketAddress the destination socket address * @return the URI host string */ public static String getHostForURI(SocketAddress socketAddress) { if (socketAddress instanceof InetSocketAddress) { final InetSocketAddress inetSocketAddress = (InetSocketAddress) socketAddress; final String hostString = inetSocketAddress.getHostString(); final InetAddress address = inetSocketAddress.getAddress(); if (address instanceof Inet6Address && hostString != null && address != null && hostString.equals(address.getHostAddress())) { return "[" + address.getHostAddress() + "]"; } else { return hostString; } } throw log.invalidSocketAddressTypeForUri(); } /** * Get the port number for the given socket address. If the port number matches the given default port, then -1 * is returned to allow the URI to use the default value. * * @param socketAddress the destination socket address * @param defaultPort the default port number for the URI scheme, or -1 if there is none or it is unknown * @return the URI port number */ public static int getPortForURI(SocketAddress socketAddress, int defaultPort) { if (socketAddress instanceof InetSocketAddress) { final InetSocketAddress inetSocketAddress = (InetSocketAddress) socketAddress; final int port = inetSocketAddress.getPort(); if (port == defaultPort) { return -1; } else { return port; } } throw log.invalidSocketAddressTypeForUri(); } /** * Create a URI from a socket address and additional information. * * @param scheme the URI scheme * @param socketAddress the destination socket address * @param defaultPort the scheme default port, or -1 if there is no standard default port * @return the URI * @throws URISyntaxException if the URI construction failed for some reason */ public static URI createURI(String scheme, SocketAddress socketAddress, int defaultPort) throws URISyntaxException { return new URI(scheme, null, getHostForURI(socketAddress), getPortForURI(socketAddress, defaultPort), null, null, null); } /** * Create a URI from a socket address and additional information. * * @param scheme the URI scheme * @param socketAddress the destination socket address * @return the URI * @throws URISyntaxException if the URI construction failed for some reason */ public static URI createURI(String scheme, SocketAddress socketAddress) throws URISyntaxException { return createURI(scheme, socketAddress, -1); } /** * Get the user name information from a URI, if any. * * @param uri the URI * @return the user name, or {@code null} if the URI did not contain a recoverable user name */ public static String getUserFromURI(URI uri) { final String userInfo = uri.getUserInfo(); if (userInfo != null) { return userInfo; } if ("domain".equals(uri.getScheme())) { final String ssp = uri.getSchemeSpecificPart(); final int at = ssp.lastIndexOf('@'); if (at == -1) { return null; } return ssp.substring(0, at); } return null; } /** * Get an Internet address for a URI destination, resolving the host name if necessary. * * @param uri the destination URI * @return the socket address, or {@code null} if no authority is present in the URI * @throws UnknownHostException if the URI host was existent but could not be resolved to a valid address */ public static InetAddress getDestinationInetAddress(URI uri) throws UnknownHostException { final String host = uri.getHost(); if (host == null) { return null; } final int length = host.length(); if (length == 0) { return null; } return InetAddress.getByName(host); } /** * Get a socket address for a URI destination, resolving the host name if necessary. If the host name could not * be resolved, an {@linkplain InetSocketAddress#isUnresolved() unresolved} address is returned. * * @param uri the destination URI * @param defaultPort the default port number for the URI scheme, or -1 if there is none or it is unknown * @return the socket address, or {@code null} if no authority is present in the URI or no port number could be determined */ public static InetSocketAddress getDestinationInetSocketAddress(URI uri, int defaultPort) { final String host = uri.getHost(); if (host == null) { return null; } final int length = host.length(); if (length == 0) { return null; } int port = uri.getPort(); if (port == -1) port = defaultPort; if (port == -1) { return null; } return new InetSocketAddress(host, port); } }