Method fromHttpUrl ends with IllegalArgumentException if parameter contain fragment

java.lang.IllegalArgumentException: [https://tools.ietf.org/html/rfc6749#section-4.1] is not a valid HTTP URL

Test case:

        String redirectUri = "https://tools.ietf.org/html/rfc6749#section-4.1";
        java.net.URL url1 = new URL(redirectUri);
        UriComponentsBuilder urlBuilder = UriComponentsBuilder.fromUriString(redirectUri);
        //UriComponentsBuilder urlBuilder = UriComponentsBuilder.fromHttpUrl(redirectUri);

From code (for URL '#' missing):

    // Regex patterns that matches URIs. See RFC 3986, appendix B
    private static final Pattern URI_PATTERN = Pattern.compile(
            "^(" + SCHEME_PATTERN + ")?" + "(//(" + USERINFO_PATTERN + "@)?" + HOST_PATTERN + "(:" + PORT_PATTERN +
                    ")?" + ")?" + PATH_PATTERN + "(\\?" + QUERY_PATTERN + ")?" + "(#" + LAST_PATTERN + ")?");

    private static final Pattern HTTP_URL_PATTERN = Pattern.compile(
            "^" + HTTP_PATTERN + "(//(" + USERINFO_PATTERN + "@)?" + HOST_PATTERN + "(:" + PORT_PATTERN + ")?" + ")?" +
                    PATH_PATTERN + "(\\?" + LAST_PATTERN + ")?");

Comment From: sbrannen

I've edited your comment to improve the formatting. You might want to check out this Mastering Markdown guide for future reference.

Comment From: sbrannen

Changing the RegEx pattern as follows would support fragments in the HTTP URL, but I'll hold off on implementing the change until I receive feedback from the team.

private static final Pattern HTTP_URL_PATTERN = Pattern.compile(
        "^" + HTTP_PATTERN + "(//(" + USERINFO_PATTERN + "@)?" + HOST_PATTERN + "(:" + PORT_PATTERN + ")?" + ")?" +
                PATH_PATTERN + "(\\?" + QUERY_PATTERN + ")?" + "(#" + LAST_PATTERN + ")?");

Comment From: rstoyanchev

@ljosefik what is the context in which you're using this? As you probably know a fragment is not sent with HTTP requests and is not available on the server side, so it is a client-side concept only, used in browsers.

If you need to parse with the complete URI syntax including fragments, you can use fromHttpUri.

Comment From: ljosefik

Yes, method fromHttpUri can be used and we solved our problem with this approach. Context - on backend we validate URL used in configuration. Generally, character '#' is valid as part of URL, so HTTP_URL_PATTERN should validate as valid also "https://tools.ietf.org/html/rfc6749#section-4.1". This example shows that fragment is not used only on frontend side but also as an reference. Also popular OAuth2 framework used fragment in response from server side , please see https://tools.ietf.org/html/rfc6749#section-4.2.2

Comment From: rstoyanchev

Yes fragment is definitely valid syntax. I wasn't making an argument the other way but simply guessing at this point as to the original intent which was quite a long time ago.

I think we can change it to parse fragments if present. It should be lenient on parsing and also the fragment method can be used thereafter which is a little inconsistent with the parsing then.

Comment From: sbrannen

Beginning with Spring Framework 5.2.8, UriComponentsBuilder.fromHttpUrl() will support fragments in URLs (see 9876ca003b996f51fcf567391fb135b58c936667).