This is an automated email from the ASF dual-hosted git repository. reta pushed a commit to branch 4.1.x-fixes in repository https://gitbox.apache.org/repos/asf/cxf.git
commit 6ab2cd28a6f4c136c1c84bae4b1724e6c3b4fbae Author: Adam Anderson <[email protected]> AuthorDate: Wed Mar 11 10:12:33 2026 -0500 [CXF-8947] - Avoid expensive regex operations in Rfc3986UriValidator (#1483) * [CXF-8947] - Avoid expensive regex operations in Rfc3986UriValidator if URI.getHost() returns a host name Signed-off-by: Adam Anderson <[email protected]> * Address review feedback: drop Rfc3986UriValidator shortcut, simplify isHttpScheme() - Remove the URI.getHost() shortcut in Rfc3986UriValidator since Java's URI.getHost() is not RFC-3986 compliant (per reviewer feedback) - Replace HashSet-based HTTP scheme check with simple String.equalsIgnoreCase() comparisons using constants Co-Authored-By: Claude Opus 4.6 <[email protected]> --------- Signed-off-by: Adam Anderson <[email protected]> Co-authored-by: Guillaume Nodet <[email protected]> Co-authored-by: Claude Opus 4.6 <[email protected]> (cherry picked from commit 3046ddafd56dedc02d0bc5419f061d2be32f8b0f) --- .../apache/cxf/jaxrs/impl/Rfc3986UriValidator.java | 6 ++--- .../java/org/apache/cxf/jaxrs/utils/HttpUtils.java | 26 +++++++++++----------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/Rfc3986UriValidator.java b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/Rfc3986UriValidator.java index a7b27ffb43..a3e0393a15 100644 --- a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/Rfc3986UriValidator.java +++ b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/Rfc3986UriValidator.java @@ -39,7 +39,7 @@ final class Rfc3986UriValidator { private static final String LAST = "#(.*)"; - private static final Pattern HTTP_URL = Pattern.compile("^" + SCHEME + private static final Pattern HTTP_URL = Pattern.compile("^" + SCHEME + "(//(" + USERINFO + "@)?" + HOST + ")?" + PATH + "(\\?" + QUERY + ")?" + "(" + LAST + ")?"); @@ -47,13 +47,13 @@ final class Rfc3986UriValidator { } /** - * Validate the HTTP URL according to https://datatracker.ietf.org/doc/html/rfc3986#appendix-B + * Validate the HTTP URL according to https://datatracker.ietf.org/doc/html/rfc3986#appendix-B * @param uri HTTP schemed URI to validate * @return "true" if URI matches RFC-3986 validation rules, "false" otherwise */ public static boolean validate(final URI uri) { // Only validate the HTTP(s) URIs - if (HttpUtils.isHttpScheme(uri.getScheme())) { + if (HttpUtils.isHttpScheme(uri.getScheme())) { final Matcher matcher = HTTP_URL.matcher(uri.toString()); if (matcher.matches()) { final String host = matcher.group(5); diff --git a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/HttpUtils.java b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/HttpUtils.java index 58bbf306fc..964e15580e 100644 --- a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/HttpUtils.java +++ b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/HttpUtils.java @@ -96,13 +96,13 @@ public final class HttpUtils { // there are more of such characters, ex, '*' but '*' is not affected by UrlEncode private static final String PATH_RESERVED_CHARACTERS = "=@/:!$&\'(),;~"; private static final String QUERY_RESERVED_CHARACTERS = "?/,"; - + private static final Set<String> KNOWN_HTTP_VERBS_WITH_NO_REQUEST_CONTENT = new HashSet<>(Arrays.asList(new String[]{"GET", "HEAD", "OPTIONS", "TRACE"})); private static final Set<String> KNOWN_HTTP_VERBS_WITH_NO_RESPONSE_CONTENT = new HashSet<>(Arrays.asList(new String[]{"HEAD", "OPTIONS"})); - - private static final Pattern HTTP_SCHEME_PATTERN = Pattern.compile("^(?i)(http|https)$"); + + private static final String HTTPS_SCHEME = "https"; private HttpUtils() { } @@ -375,7 +375,7 @@ public final class HttpUtils { (HttpServletRequest)message.get(AbstractHTTPDestination.HTTP_REQUEST)); return URI.create(base + relativePath); } - + public static void setHttpRequestURI(Message message, String uriTemplate) { HttpServletRequest request = (HttpServletRequest)message.get(AbstractHTTPDestination.HTTP_REQUEST); @@ -481,8 +481,8 @@ public final class HttpUtils { URI uri = new URI(endpointAddress); String path = uri.getRawPath(); String scheme = uri.getScheme(); - // RFC-3986: the scheme and host are case-insensitive and therefore should - // be normalized to lowercase. + // RFC-3986: the scheme and host are case-insensitive and therefore should + // be normalized to lowercase. if (scheme != null && !scheme.toLowerCase().startsWith(HttpUtils.HTTP_SCHEME) && !scheme.toLowerCase().startsWith(HttpUtils.WS_SCHEME) && !scheme.toLowerCase().startsWith(HttpUtils.WSS_SCHEME) @@ -497,7 +497,7 @@ public final class HttpUtils { public static String getEndpointUri(Message m) { final Object servletRequest = m.get(AbstractHTTPDestination.HTTP_REQUEST); - + if (servletRequest != null) { final Object property = ((jakarta.servlet.http.HttpServletRequest)servletRequest) .getAttribute("org.apache.cxf.transport.endpoint.uri"); @@ -505,7 +505,7 @@ public final class HttpUtils { return property.toString(); } } - + return getEndpointAddress(m); } @@ -623,7 +623,7 @@ public final class HttpUtils { public static String getMediaTypeCharsetParameter(MediaType mt) { String charset = mt.getParameters().get(CHARSET_PARAMETER); - if (charset != null && charset.startsWith(DOUBLE_QUOTE) + if (charset != null && charset.startsWith(DOUBLE_QUOTE) && charset.endsWith(DOUBLE_QUOTE) && charset.length() > 1) { charset = charset.substring(1, charset.length() - 1); } @@ -704,7 +704,7 @@ public final class HttpUtils { return false; } - + public static <T> T createServletResourceValue(Message m, Class<T> clazz) { Object value = null; @@ -726,12 +726,12 @@ public final class HttpUtils { public static boolean isMethodWithNoRequestContent(String method) { return KNOWN_HTTP_VERBS_WITH_NO_REQUEST_CONTENT.contains(method); } - + public static boolean isMethodWithNoResponseContent(String method) { return KNOWN_HTTP_VERBS_WITH_NO_RESPONSE_CONTENT.contains(method); } - + public static boolean isHttpScheme(final String scheme) { - return scheme != null && HTTP_SCHEME_PATTERN.matcher(scheme).matches(); + return HTTP_SCHEME.equalsIgnoreCase(scheme) || HTTPS_SCHEME.equalsIgnoreCase(scheme); } }
