|
|
|
|
@ -57,6 +57,7 @@ import org.springframework.util.Assert;
@@ -57,6 +57,7 @@ import org.springframework.util.Assert;
|
|
|
|
|
* @author Arjen Poutsma |
|
|
|
|
* @since 6.2 |
|
|
|
|
*/ |
|
|
|
|
@SuppressWarnings({"SameParameterValue", "BooleanMethodIsAlwaysInverted"}) |
|
|
|
|
final class WhatWgUrlParser { |
|
|
|
|
|
|
|
|
|
public static final UrlRecord EMPTY_RECORD = new UrlRecord(); |
|
|
|
|
@ -140,7 +141,7 @@ final class WhatWgUrlParser {
@@ -140,7 +141,7 @@ final class WhatWgUrlParser {
|
|
|
|
|
/** |
|
|
|
|
* The basic URL parser takes a scalar value string input, with an optional |
|
|
|
|
* null or base URL base (default null), an optional encoding (default UTF-8), |
|
|
|
|
* an optional UrlRecord, and an optional state override. |
|
|
|
|
* and optionally, a UrlRecord and/or State overrides to start from. |
|
|
|
|
*/ |
|
|
|
|
private UrlRecord basicUrlParser(@Nullable UrlRecord url, @Nullable State stateOverride) { |
|
|
|
|
// If url is not given:
|
|
|
|
|
@ -471,6 +472,7 @@ final class WhatWgUrlParser {
@@ -471,6 +472,7 @@ final class WhatWgUrlParser {
|
|
|
|
|
ch == 0xEFFFE || ch == 0xEFFFF || ch == 0xFFFFE || ch == 0xFFFFF || ch == 0x10FFFE || ch == 0x10FFFF); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@SuppressWarnings("BooleanMethodIsAlwaysInverted") |
|
|
|
|
private static boolean isUrlCodePoint(int ch) { |
|
|
|
|
return (isAsciiAlphaNumeric(ch) || |
|
|
|
|
ch == '!' || ch == '$' || ch == '&' || ch == '\'' || ch == '(' || ch == ')' || |
|
|
|
|
@ -490,10 +492,8 @@ final class WhatWgUrlParser {
@@ -490,10 +492,8 @@ final class WhatWgUrlParser {
|
|
|
|
|
if (scheme != null) { |
|
|
|
|
return switch (scheme) { |
|
|
|
|
case "ftp" -> 21; |
|
|
|
|
case "http" -> 80; |
|
|
|
|
case "https" -> 443; |
|
|
|
|
case "ws" -> 80; |
|
|
|
|
case "wss" -> 443; |
|
|
|
|
case "http", "ws" -> 80; |
|
|
|
|
case "https", "wss" -> 443; |
|
|
|
|
default -> -1; |
|
|
|
|
}; |
|
|
|
|
} |
|
|
|
|
@ -686,10 +686,9 @@ final class WhatWgUrlParser {
@@ -686,10 +686,9 @@ final class WhatWgUrlParser {
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* A Windows drive letter is two code points, of which the first is an ASCII alpha |
|
|
|
|
* and the second is either U+003A (:) or U+007C (|). |
|
|
|
|
* |
|
|
|
|
* and the second is either U+003A {@code (:)} or U+007C {@code (|)}. |
|
|
|
|
* A normalized Windows drive letter is a Windows drive letter of which |
|
|
|
|
* the second code point is U+003A (:). |
|
|
|
|
* the second code point is U+003A {@code (:)}. |
|
|
|
|
*/ |
|
|
|
|
private static boolean isWindowsDriveLetter(CharSequence input, boolean normalized) { |
|
|
|
|
if (input.length() != 2) { |
|
|
|
|
@ -699,8 +698,7 @@ final class WhatWgUrlParser {
@@ -699,8 +698,7 @@ final class WhatWgUrlParser {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* A string starts with a Windows drive letter if all of the following are true: |
|
|
|
|
* |
|
|
|
|
* A string starts with a Windows drive letter if all the following are true: |
|
|
|
|
* its length is greater than or equal to 2 |
|
|
|
|
* its first two code points are a Windows drive letter |
|
|
|
|
* its length is 2 or its third code point is U+002F (/), U+005C (\), U+003F (?), or U+0023 (#). |
|
|
|
|
@ -1204,7 +1202,6 @@ final class WhatWgUrlParser {
@@ -1204,7 +1202,6 @@ final class WhatWgUrlParser {
|
|
|
|
|
// If state override is given, then return.
|
|
|
|
|
if (p.stateOverride != null) { |
|
|
|
|
p.stopMainLoop = true; |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
// Otherwise:
|
|
|
|
|
@ -1656,7 +1653,7 @@ final class WhatWgUrlParser {
@@ -1656,7 +1653,7 @@ final class WhatWgUrlParser {
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
// Otherwise, if c is not the EOF code point:
|
|
|
|
|
else if (c != EOF) { |
|
|
|
|
else { |
|
|
|
|
if (p.validate()) { |
|
|
|
|
// If c is not a URL code point and not U+0025 (%), invalid-URL-unit validation error.
|
|
|
|
|
if (!isUrlCodePoint(c) && c != '%') { |
|
|
|
|
@ -1769,39 +1766,6 @@ final class WhatWgUrlParser {
@@ -1769,39 +1766,6 @@ final class WhatWgUrlParser {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* The serialization of an origin is the string obtained by applying |
|
|
|
|
* the following algorithm to the given origin: |
|
|
|
|
* <ol> |
|
|
|
|
* <li>If origin is an opaque origin, then return "null". |
|
|
|
|
* <li>Otherwise, let result be origin's scheme. |
|
|
|
|
* <li>Append "://" to result. |
|
|
|
|
* Append origin's host, serialized, to result. |
|
|
|
|
* <li>If origin's port is non-null, append a U+003A COLON character (:), |
|
|
|
|
* and origin's port, serialized, to result. |
|
|
|
|
* <li>Return result. |
|
|
|
|
* </ol> |
|
|
|
|
*/ |
|
|
|
|
public String origin() { |
|
|
|
|
String scheme = scheme(); |
|
|
|
|
if (scheme.equals("ftp") || |
|
|
|
|
scheme.equals("http") || scheme.equals("https") || |
|
|
|
|
scheme.equals("ws") || scheme.equals("wss")) { |
|
|
|
|
StringBuilder builder = new StringBuilder(scheme); |
|
|
|
|
builder.append("://"); |
|
|
|
|
builder.append(host()); |
|
|
|
|
Port port = port(); |
|
|
|
|
if (port != null) { |
|
|
|
|
builder.append(':'); |
|
|
|
|
builder.append(port); |
|
|
|
|
} |
|
|
|
|
return builder.toString(); |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
return "null"; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* A URL’s scheme is an ASCII string that identifies the type of URL and |
|
|
|
|
* can be used to dispatch a URL for further processing after parsing. |
|
|
|
|
@ -1814,6 +1778,7 @@ final class WhatWgUrlParser {
@@ -1814,6 +1778,7 @@ final class WhatWgUrlParser {
|
|
|
|
|
/** |
|
|
|
|
* The protocol getter steps are to return this’s URL’s scheme, followed by U+003A (:). |
|
|
|
|
*/ |
|
|
|
|
@SuppressWarnings("unused") |
|
|
|
|
public String protocol() { |
|
|
|
|
return scheme() + ":"; |
|
|
|
|
} |
|
|
|
|
@ -1899,6 +1864,7 @@ final class WhatWgUrlParser {
@@ -1899,6 +1864,7 @@ final class WhatWgUrlParser {
|
|
|
|
|
* <li>Return url’s host, serialized, followed by U+003A (:) and url’s port, serialized. |
|
|
|
|
* </ol> |
|
|
|
|
*/ |
|
|
|
|
@SuppressWarnings("unused") |
|
|
|
|
public String hostString() { |
|
|
|
|
if (host() == null) { |
|
|
|
|
return ""; |
|
|
|
|
@ -2001,6 +1967,7 @@ final class WhatWgUrlParser {
@@ -2001,6 +1967,7 @@ final class WhatWgUrlParser {
|
|
|
|
|
* <li>Return U+0023 (#), followed by this’s URL’s fragment. |
|
|
|
|
* </ol> |
|
|
|
|
*/ |
|
|
|
|
@SuppressWarnings("unused") |
|
|
|
|
public String hash() { |
|
|
|
|
String fragment = fragment(); |
|
|
|
|
return (fragment != null && !fragment.isEmpty() ? "#" + fragment : ""); |
|
|
|
|
@ -2248,6 +2215,7 @@ final class WhatWgUrlParser {
@@ -2248,6 +2215,7 @@ final class WhatWgUrlParser {
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@SuppressWarnings("unused") |
|
|
|
|
public IpAddress address() { |
|
|
|
|
return this.address; |
|
|
|
|
} |
|
|
|
|
@ -2776,7 +2744,7 @@ final class WhatWgUrlParser {
@@ -2776,7 +2744,7 @@ final class WhatWgUrlParser {
|
|
|
|
|
} |
|
|
|
|
// Otherwise, if compress is null and pieceIndex is not 8,
|
|
|
|
|
// IPv6-too-few-pieces validation error, return failure.
|
|
|
|
|
else if (compress == null && pieceIndex != 8) { |
|
|
|
|
else if (pieceIndex != 8) { |
|
|
|
|
throw new InvalidUrlException("An uncompressed IPv6 address contains fewer than 8 pieces."); |
|
|
|
|
} |
|
|
|
|
// Return address.
|
|
|
|
|
@ -3019,6 +2987,7 @@ final class WhatWgUrlParser {
@@ -3019,6 +2987,7 @@ final class WhatWgUrlParser {
|
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@SuppressWarnings("MethodDoesntCallSuperMethod") |
|
|
|
|
@Override |
|
|
|
|
public Path clone() { |
|
|
|
|
return new PathSegment(segment()); |
|
|
|
|
@ -3103,6 +3072,7 @@ final class WhatWgUrlParser {
@@ -3103,6 +3072,7 @@ final class WhatWgUrlParser {
|
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@SuppressWarnings("MethodDoesntCallSuperMethod") |
|
|
|
|
@Override |
|
|
|
|
public Path clone() { |
|
|
|
|
return new PathSegments(this.segments); |
|
|
|
|
|