Class UrlUtil


  • public class UrlUtil
    extends Object
    FOR INTERNAL USE ONLY! This class is not considered a part of the public API.

    Internal utility class for URL handling.

    ---

    Notes about safe URL schemes:

    In regular applications and integration tests the default population logic of the cached set of safe URL schemes is triggered at launch (in VaadinService.init()), but for unit tests there is no built-in pre-population. If the cached set has not been populated, and there is no valid result from VaadinService.getCurrent(), isSafeUrl(String) will fall back to using the default wildcard, but also logs a warning. The fallback could theoretically also happen in a regular application, but only if some thread manages to call isSafeUrl(String) before the VaadinService.init() has been completed. If some application actually needs to create an ExternalResource in such a thread, it should use a constructor with the validation bypass, and the URL validation should be done via some custom means instead rather than relying on this class.

    Also, in regular applications the set of safe URL schemes cached within this class should stay stable once it's been populated. It is not recommended to update the set on the fly, and re-triggering VaadinService.init() or AbstractDeploymentConfiguration.getUrlSafeSchemes() will not update it. If a different set is needed for some specific purpose, that should again bypass the built-in validation and use some custom validation instead. If changes to the cached set are needed regardless (within the framework tests), they need to happen via setUrlSafeSchemes(Set), either by entering the new set directly, or entering an empty set or null for triggering a re-evaluation of the application property the next time isSafeUrl(String) is called.

    Note: If a test needs to modify the cached set, that can and will affect the other tests within the same run, particularly if they are run in parallel. Test classes like that should be annotated with net.jcip.annotations.NotThreadSafe, and they should clean after themselves.

    Since:
    See Also:
    AbstractDeploymentConfiguration.getUrlSafeSchemes()
    • Constructor Detail

      • UrlUtil

        public UrlUtil()
    • Method Detail

      • getUrlSafeSchemes

        public static Set<String> getUrlSafeSchemes()
        FOR INTERNAL USE ONLY!

        Returns the current set of safe URL schemes that is used by the isSafeUrl(String) check. The set is never null, but it can be empty, and it can be explicitly cleared via setUrlSafeSchemes(Set).

        Every call of this method returns the same Set instance, unless it gets replaced via another call of setUrlSafeSchemes(Set). The Set returned by this method is never the same instance as the Set given to the setter, but an unmodifiable copy with the same contents.

        The default population logic of this set (triggered in VaadinService.init()) is based on the "safeUrlSchemes" application property, and will fall back to wildcard if the property hasn't been set.

        Returns:
        unmodifiable set of current safe URL schemes
      • setUrlSafeSchemes

        public static void setUrlSafeSchemes​(Set<String> urlSafeSchemes)
        FOR INTERNAL USE ONLY! Populates the current set of safe URL schemes.

        If the given set is null or empty, getUrlSafeSchemes() will return a new empty set. Otherwise the previous set will be replaced with a new unmodifiable set which only contains the given schemes.

        The set received from getUrlSafeSchemes() will never be the same instance as the set given to this method.

        Parameters:
        urlSafeSchemes - a set of safe URL schemes
      • isSafeUrl

        public static boolean isSafeUrl​(String url)
        FOR INTERNAL USE ONLY!

        Checks whether the scheme of the given URL is considered safe by the current deployment configuration.

        The set of safe schemes is read from the current VaadinService's DeploymentConfiguration.getUrlSafeSchemes(), falling back to Constants.URL_SAFE_SCHEMES_WILDCARD when no VaadinService is available. A null URL is always considered unsafe, even if the rest of the validation can get bypassed via a wildcard. Relative URLs (without a scheme) are always considered safe, whereas URLs containing control characters are rejected (unless allowed via a wildcard) as they can be used to obfuscate the scheme.

        Parameters:
        url - the URL to check, may be null
        Returns:
        true if the URL is safe, false otherwise
      • getUnsafeUrlMessage

        public static String getUnsafeUrlMessage​(String type,
                                                 String url,
                                                 String unsafeMethod)
        FOR INTERNAL USE ONLY!

        Builds the message for the IllegalArgumentException that a validating URL setter throws when given a URL whose scheme is not considered safe. The message points to both the Constants.URL_SAFE_SCHEMES configuration property and the setter that bypasses validation.

        Parameters:
        type - the kind of URL being set, for example "src" or "path"
        url - the rejected URL
        unsafeMethod - the signature of the method that bypasses validation, for example "openUnsafe(String, String)" or "new ExternalResource(String, true)"
        Returns:
        the exception message
      • isSafeUrl

        public static boolean isSafeUrl​(String url,
                                        Set<String> safeSchemes)
        FOR INTERNAL USE ONLY!

        Checks whether the scheme of the given URL is part of the given set of safe schemes. See isSafeUrl(String) for the validation rules. A null URL is always considered unsafe.

        Parameters:
        url - the URL to check, may be null
        safeSchemes - the set of safe lower-case schemes, or a set containing Constants.URL_SAFE_SCHEMES_WILDCARD to treat any non-null scheme as safe
        Returns:
        true if the URL is safe, false otherwise