This is an automated email from the ASF dual-hosted git repository. reta pushed a commit to branch 3.6.x-fixes in repository https://gitbox.apache.org/repos/asf/cxf.git
commit 27f4f4c66d3033687dde242b52a5e319623df01a 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 c57dc6f1a3..39a6e5f5e7 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 @@ -94,13 +94,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() { } @@ -373,7 +373,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); @@ -480,8 +480,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) && HttpUtils.isHttpRequest(m)) { path = HttpUtils.toAbsoluteUri(path, m).getRawPath(); @@ -494,7 +494,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 = ((javax.servlet.http.HttpServletRequest)servletRequest) .getAttribute("org.apache.cxf.transport.endpoint.uri"); @@ -502,7 +502,7 @@ public final class HttpUtils { return property.toString(); } } - + return getEndpointAddress(m); } @@ -619,7 +619,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); } @@ -700,7 +700,7 @@ public final class HttpUtils { return false; } - + public static <T> T createServletResourceValue(Message m, Class<T> clazz) { Object value = null; @@ -722,12 +722,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); } }
