diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/resource/CachingResourceResolver.java b/spring-webflux/src/main/java/org/springframework/web/reactive/resource/CachingResourceResolver.java index 93383608d51..87532cf32c4 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/resource/CachingResourceResolver.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/resource/CachingResourceResolver.java @@ -17,10 +17,8 @@ package org.springframework.web.reactive.resource; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.List; -import java.util.Locale; import java.util.stream.Collectors; import reactor.core.publisher.Mono; @@ -134,15 +132,12 @@ public class CachingResourceResolver extends AbstractResourceResolver { @Nullable private String getContentCodingKey(ServerWebExchange exchange) { - String header = exchange.getRequest().getHeaders().getFirst("Accept-Encoding"); - if (!StringUtils.hasText(header)) { + List acceptedCodings = EncodedResourceResolver.parseAcceptEncoding(exchange); + if (acceptedCodings.isEmpty()) { return null; } - return Arrays.stream(StringUtils.tokenizeToStringArray(header, ",")) - .map(token -> { - int index = token.indexOf(';'); - return (index >= 0 ? token.substring(0, index) : token).trim().toLowerCase(Locale.ROOT); - }) + return acceptedCodings + .stream() .filter(this.contentCodings::contains) .sorted() .collect(Collectors.joining(",")); diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/resource/EncodedResourceResolver.java b/spring-webflux/src/main/java/org/springframework/web/reactive/resource/EncodedResourceResolver.java index a0080f17c55..69e3b385b05 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/resource/EncodedResourceResolver.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/resource/EncodedResourceResolver.java @@ -36,9 +36,9 @@ import reactor.core.publisher.Mono; import org.springframework.core.io.AbstractResource; import org.springframework.core.io.Resource; import org.springframework.http.HttpHeaders; -import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.lang.Nullable; import org.springframework.util.Assert; +import org.springframework.util.StringUtils; import org.springframework.web.server.ServerWebExchange; /** @@ -141,23 +141,23 @@ public class EncodedResourceResolver extends AbstractResourceResolver { return resource; } - String acceptEncoding = getAcceptEncoding(exchange); - if (acceptEncoding == null) { + List acceptedCodings = parseAcceptEncoding(exchange); + if (acceptedCodings.isEmpty()) { return resource; } - for (String coding : this.contentCodings) { - if (acceptEncoding.contains(coding)) { + for (String acceptedCoding : acceptedCodings) { + if (this.contentCodings.contains(acceptedCoding)) { try { - String extension = getExtension(coding); - Resource encoded = new EncodedResource(resource, coding, extension); + String extension = getExtension(acceptedCoding); + Resource encoded = new EncodedResource(resource, acceptedCoding, extension); if (encoded.exists()) { return encoded; } } catch (IOException ex) { logger.trace(exchange.getLogPrefix() + - "No " + coding + " resource for [" + resource.getFilename() + "]", ex); + "No " + acceptedCoding + " resource for [" + resource.getFilename() + "]", ex); } } } @@ -166,13 +166,6 @@ public class EncodedResourceResolver extends AbstractResourceResolver { }); } - @Nullable - private String getAcceptEncoding(ServerWebExchange exchange) { - ServerHttpRequest request = exchange.getRequest(); - String header = request.getHeaders().getFirst(HttpHeaders.ACCEPT_ENCODING); - return (header != null ? header.toLowerCase(Locale.ROOT) : null); - } - private String getExtension(String coding) { String extension = this.extensions.get(coding); if (extension == null) { @@ -188,6 +181,23 @@ public class EncodedResourceResolver extends AbstractResourceResolver { return chain.resolveUrlPath(resourceUrlPath, locations); } + /** + * Parse the accepted encodings from the given HTTP exchange request. + */ + static List parseAcceptEncoding(ServerWebExchange exchange) { + String header = exchange.getRequest().getHeaders().getFirst("Accept-Encoding"); + if (!StringUtils.hasText(header)) { + return Collections.emptyList(); + } + header = header.toLowerCase(Locale.ROOT); + return Arrays.stream(StringUtils.tokenizeToStringArray(header, ",")) + .map(token -> { + int index = token.indexOf(';'); + return (index >= 0 ? token.substring(0, index) : token).trim(); + }) + .toList(); + } + /** * An encoded {@link HttpResource}. diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/CachingResourceResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/CachingResourceResolver.java index fb953dbdd99..a550fe585ef 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/CachingResourceResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/CachingResourceResolver.java @@ -17,10 +17,8 @@ package org.springframework.web.servlet.resource; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.List; -import java.util.Locale; import java.util.stream.Collectors; import jakarta.servlet.http.HttpServletRequest; @@ -28,7 +26,6 @@ import jakarta.servlet.http.HttpServletRequest; import org.springframework.cache.Cache; import org.springframework.cache.CacheManager; import org.springframework.core.io.Resource; -import org.springframework.http.HttpHeaders; import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.StringUtils; @@ -141,15 +138,12 @@ public class CachingResourceResolver extends AbstractResourceResolver { @Nullable private String getContentCodingKey(HttpServletRequest request) { - String header = request.getHeader(HttpHeaders.ACCEPT_ENCODING); - if (!StringUtils.hasText(header)) { + List acceptedCodings = EncodedResourceResolver.parseAcceptEncoding(request); + if (acceptedCodings.isEmpty()) { return null; } - return Arrays.stream(StringUtils.tokenizeToStringArray(header, ",")) - .map(token -> { - int index = token.indexOf(';'); - return (index >= 0 ? token.substring(0, index) : token).trim().toLowerCase(Locale.ROOT); - }) + return acceptedCodings + .stream() .filter(this.contentCodings::contains) .sorted() .collect(Collectors.joining(",")); diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/EncodedResourceResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/EncodedResourceResolver.java index ecc3ca8db61..167b1e2f8f3 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/EncodedResourceResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/EncodedResourceResolver.java @@ -38,6 +38,7 @@ import org.springframework.core.io.Resource; import org.springframework.http.HttpHeaders; import org.springframework.lang.Nullable; import org.springframework.util.Assert; +import org.springframework.util.StringUtils; /** * Resolver that delegates to the chain, and if a resource is found, it then @@ -139,23 +140,23 @@ public class EncodedResourceResolver extends AbstractResourceResolver { return resource; } - String acceptEncoding = getAcceptEncoding(request); - if (acceptEncoding == null) { + List acceptedCodings = parseAcceptEncoding(request); + if (acceptedCodings.isEmpty()) { return resource; } - for (String coding : this.contentCodings) { - if (acceptEncoding.contains(coding)) { + for (String acceptedCoding : acceptedCodings) { + if (this.contentCodings.contains(acceptedCoding)) { try { - String extension = getExtension(coding); - Resource encoded = new EncodedResource(resource, coding, extension); + String extension = getExtension(acceptedCoding); + Resource encoded = new EncodedResource(resource, acceptedCoding, extension); if (encoded.exists()) { return encoded; } } catch (IOException ex) { if (logger.isTraceEnabled()) { - logger.trace("No " + coding + " resource for [" + resource.getFilename() + "]", ex); + logger.trace("No " + acceptedCoding + " resource for [" + resource.getFilename() + "]", ex); } } } @@ -164,12 +165,6 @@ public class EncodedResourceResolver extends AbstractResourceResolver { return resource; } - @Nullable - private String getAcceptEncoding(HttpServletRequest request) { - String header = request.getHeader(HttpHeaders.ACCEPT_ENCODING); - return (header != null ? header.toLowerCase(Locale.ROOT) : null); - } - private String getExtension(String coding) { String extension = this.extensions.get(coding); if (extension == null) { @@ -186,6 +181,23 @@ public class EncodedResourceResolver extends AbstractResourceResolver { return chain.resolveUrlPath(resourceUrlPath, locations); } + /** + * Parse the accepted encodings from the given HTTP request. + */ + static List parseAcceptEncoding(HttpServletRequest request) { + String header = request.getHeader("Accept-Encoding"); + if (!StringUtils.hasText(header)) { + return Collections.emptyList(); + } + header = header.toLowerCase(Locale.ROOT); + return Arrays.stream(StringUtils.tokenizeToStringArray(header, ",")) + .map(token -> { + int index = token.indexOf(';'); + return (index >= 0 ? token.substring(0, index) : token).trim(); + }) + .toList(); + } + /** * An encoded {@link HttpResource}.