Browse Source

Assert static resource location

Closes gh-33712
pull/33714/head
rstoyanchev 1 year ago
parent
commit
789d7effa9
  1. 3
      spring-webflux/src/main/java/org/springframework/web/reactive/function/server/PathResourceLookupFunction.java
  2. 38
      spring-webflux/src/main/java/org/springframework/web/reactive/resource/ResourceHandlerUtils.java
  3. 6
      spring-webflux/src/main/java/org/springframework/web/reactive/resource/ResourceWebHandler.java
  4. 2
      spring-webflux/src/test/java/org/springframework/web/reactive/config/DelegatingWebFluxConfigurationTests.java
  5. 2
      spring-webmvc/src/main/java/org/springframework/web/servlet/function/PathResourceLookupFunction.java
  6. 38
      spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHandlerUtils.java
  7. 6
      spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java
  8. 2
      spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/ResourceHandlerRegistryTests.java
  9. 2
      spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupportExtensionTests.java
  10. 2
      spring-webmvc/src/test/resources/org/springframework/web/servlet/config/mvc-config-resources-chain.xml

3
spring-webflux/src/main/java/org/springframework/web/reactive/function/server/PathResourceLookupFunction.java

@ -44,12 +44,11 @@ class PathResourceLookupFunction implements Function<ServerRequest, Mono<Resourc @@ -44,12 +44,11 @@ class PathResourceLookupFunction implements Function<ServerRequest, Mono<Resourc
public PathResourceLookupFunction(String pattern, Resource location) {
Assert.hasLength(pattern, "'pattern' must not be empty");
Assert.notNull(location, "'location' must not be null");
ResourceHandlerUtils.assertResourceLocation(location);
this.pattern = PathPatternParser.defaultInstance.parse(pattern);
this.location = location;
}
@Override
public Mono<Resource> apply(ServerRequest request) {
PathContainer pathContainer = request.requestPath().pathWithinApplication();

38
spring-webflux/src/main/java/org/springframework/web/reactive/resource/ResourceHandlerUtils.java

@ -27,6 +27,8 @@ import org.springframework.core.io.ClassPathResource; @@ -27,6 +27,8 @@ import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.core.log.LogFormatUtils;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ResourceUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.util.UriUtils;
@ -42,6 +44,42 @@ public abstract class ResourceHandlerUtils { @@ -42,6 +44,42 @@ public abstract class ResourceHandlerUtils {
private static final Log logger = LogFactory.getLog(ResourceHandlerUtils.class);
private static final String FOLDER_SEPARATOR = "/";
private static final String WINDOWS_FOLDER_SEPARATOR = "\\";
/**
* Assert the given location is not null, and its path ends on slash.
*/
public static void assertResourceLocation(@Nullable Resource location) {
Assert.notNull(location, "Resource location must not be null");
try {
String path;
if (location instanceof UrlResource) {
path = location.getURL().toExternalForm();
}
else if (location instanceof ClassPathResource classPathResource) {
path = classPathResource.getPath();
}
else {
path = location.getURL().getPath();
}
assertLocationPath(path);
}
catch (IOException ex) {
// ignore
}
}
/**
* Assert the given location path is a directory and ends on slash.
*/
public static void assertLocationPath(@Nullable String path) {
Assert.notNull(path, "Resource location path must not be null");
Assert.isTrue(path.endsWith(FOLDER_SEPARATOR) || path.endsWith(WINDOWS_FOLDER_SEPARATOR),
"Resource location does not end with slash: " + path);
}
/**
* Normalize the given resource path replacing the following:

6
spring-webflux/src/main/java/org/springframework/web/reactive/resource/ResourceWebHandler.java

@ -160,7 +160,10 @@ public class ResourceWebHandler implements WebHandler, InitializingBean { @@ -160,7 +160,10 @@ public class ResourceWebHandler implements WebHandler, InitializingBean {
public void setLocations(@Nullable List<Resource> locations) {
this.locationResources.clear();
if (locations != null) {
this.locationResources.addAll(locations);
for (Resource location : locations) {
ResourceHandlerUtils.assertResourceLocation(location);
this.locationResources.add(location);
}
}
}
@ -376,6 +379,7 @@ public class ResourceWebHandler implements WebHandler, InitializingBean { @@ -376,6 +379,7 @@ public class ResourceWebHandler implements WebHandler, InitializingBean {
Assert.isTrue(CollectionUtils.isEmpty(this.locationResources), "Please set " +
"either Resource-based \"locations\" or String-based \"locationValues\", but not both.");
for (String location : this.locationValues) {
ResourceHandlerUtils.assertLocationPath(location);
result.add(this.resourceLoader.getResource(location));
}
}

2
spring-webflux/src/test/java/org/springframework/web/reactive/config/DelegatingWebFluxConfigurationTests.java

@ -124,7 +124,7 @@ public class DelegatingWebFluxConfigurationTests { @@ -124,7 +124,7 @@ public class DelegatingWebFluxConfigurationTests {
delegatingConfig.setConfigurers(Collections.singletonList(webFluxConfigurer));
willAnswer(invocation -> {
ResourceHandlerRegistry registry = invocation.getArgument(0);
registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static");
registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
return null;
}).given(webFluxConfigurer).addResourceHandlers(any(ResourceHandlerRegistry.class));

2
spring-webmvc/src/main/java/org/springframework/web/servlet/function/PathResourceLookupFunction.java

@ -47,7 +47,7 @@ class PathResourceLookupFunction implements Function<ServerRequest, Optional<Res @@ -47,7 +47,7 @@ class PathResourceLookupFunction implements Function<ServerRequest, Optional<Res
public PathResourceLookupFunction(String pattern, Resource location) {
Assert.hasLength(pattern, "'pattern' must not be empty");
Assert.notNull(location, "'location' must not be null");
ResourceHandlerUtils.assertResourceLocation(location);
this.pattern = PathPatternParser.defaultInstance.parse(pattern);
this.location = location;
}

38
spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHandlerUtils.java

@ -27,6 +27,8 @@ import org.springframework.core.io.ClassPathResource; @@ -27,6 +27,8 @@ import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.core.log.LogFormatUtils;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ResourceUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.context.support.ServletContextResource;
@ -42,6 +44,42 @@ public abstract class ResourceHandlerUtils { @@ -42,6 +44,42 @@ public abstract class ResourceHandlerUtils {
private static final Log logger = LogFactory.getLog(ResourceHandlerUtils.class);
private static final String FOLDER_SEPARATOR = "/";
private static final String WINDOWS_FOLDER_SEPARATOR = "\\";
/**
* Assert the given location is not null, and its path ends on slash.
*/
public static void assertResourceLocation(@Nullable Resource location) {
Assert.notNull(location, "Resource location must not be null");
try {
String path;
if (location instanceof UrlResource) {
path = location.getURL().toExternalForm();
}
else if (location instanceof ClassPathResource classPathResource) {
path = classPathResource.getPath();
}
else {
path = location.getURL().getPath();
}
assertLocationPath(path);
}
catch (IOException ex) {
// ignore
}
}
/**
* Assert the given location path is a directory and ends on slash.
*/
public static void assertLocationPath(@Nullable String path) {
Assert.notNull(path, "Resource location path must not be null");
Assert.isTrue(path.endsWith(FOLDER_SEPARATOR) || path.endsWith(WINDOWS_FOLDER_SEPARATOR),
"Resource location does not end with slash: " + path);
}
/**
* Normalize the given resource path replacing the following:

6
spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java

@ -180,7 +180,10 @@ public class ResourceHttpRequestHandler extends WebContentGenerator @@ -180,7 +180,10 @@ public class ResourceHttpRequestHandler extends WebContentGenerator
public void setLocations(List<Resource> locations) {
Assert.notNull(locations, "Locations list must not be null");
this.locationResources.clear();
this.locationResources.addAll(locations);
for (Resource location : locations) {
ResourceHandlerUtils.assertResourceLocation(location);
this.locationResources.add(location);
}
}
/**
@ -493,6 +496,7 @@ public class ResourceHttpRequestHandler extends WebContentGenerator @@ -493,6 +496,7 @@ public class ResourceHttpRequestHandler extends WebContentGenerator
charset = Charset.forName(value);
location = location.substring(endIndex + 1);
}
ResourceHandlerUtils.assertLocationPath(location);
Resource resource = applicationContext.getResource(location);
if (location.equals("/") && !(resource instanceof ServletContextResource)) {
throw new IllegalStateException(

2
spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/ResourceHandlerRegistryTests.java

@ -204,7 +204,7 @@ class ResourceHandlerRegistryTests { @@ -204,7 +204,7 @@ class ResourceHandlerRegistryTests {
@Test
void urlResourceWithCharset() {
this.registration.addResourceLocations("[charset=ISO-8859-1]file:///tmp");
this.registration.addResourceLocations("[charset=ISO-8859-1]file:///tmp/");
this.registration.resourceChain(true);
ResourceHttpRequestHandler handler = getHandler("/resources/**");

2
spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupportExtensionTests.java

@ -457,7 +457,7 @@ class WebMvcConfigurationSupportExtensionTests { @@ -457,7 +457,7 @@ class WebMvcConfigurationSupportExtensionTests {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("src/test/java");
registry.addResourceHandler("/resources/**").addResourceLocations("src/test/java/");
}
@Override

2
spring-webmvc/src/test/resources/org/springframework/web/servlet/config/mvc-config-resources-chain.xml

@ -23,7 +23,7 @@ @@ -23,7 +23,7 @@
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="properties">
<value>location=file:///tmp</value>
<value>location=file:///tmp/</value>
</property>
</bean>

Loading…
Cancel
Save