Fix ResourceUrlProvider handler auto-detection
Prior to this commit, `ResourceUrlProvider` would listen and consider all `ContextRefreshedEvent` and use the given context to detect `SimpleUrlHandlerMapping`. This could lead to situations where a `ResourceUrlProvider` uses another application context than its own (in a parent/child context setup) and detect the wrong set of handlers. Because `ResourceUrlProvider` locks itself once the auto-detection is done, we need to ensure that it considers only events sent by its application context. Fixes gh-26561
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -44,6 +44,7 @@ import static org.mockito.Mockito.mock;
|
||||
*
|
||||
* @author Jeremy Grelle
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Brian Clozel
|
||||
*/
|
||||
public class ResourceUrlProviderTests {
|
||||
|
||||
@@ -57,7 +58,7 @@ public class ResourceUrlProviderTests {
|
||||
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() throws Exception {
|
||||
void setUp() throws Exception {
|
||||
this.locations.add(new ClassPathResource("test/", getClass()));
|
||||
this.locations.add(new ClassPathResource("testalternatepath/", getClass()));
|
||||
this.handler.setServletContext(new MockServletContext());
|
||||
@@ -69,13 +70,13 @@ public class ResourceUrlProviderTests {
|
||||
|
||||
|
||||
@Test
|
||||
public void getStaticResourceUrl() {
|
||||
void getStaticResourceUrl() {
|
||||
String url = this.urlProvider.getForLookupPath("/resources/foo.css");
|
||||
assertThat(url).isEqualTo("/resources/foo.css");
|
||||
}
|
||||
|
||||
@Test // SPR-13374
|
||||
public void getStaticResourceUrlRequestWithQueryOrHash() {
|
||||
void getStaticResourceUrlRequestWithQueryOrHash() {
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
request.setContextPath("/");
|
||||
request.setRequestURI("/");
|
||||
@@ -90,7 +91,7 @@ public class ResourceUrlProviderTests {
|
||||
}
|
||||
|
||||
@Test // SPR-16526
|
||||
public void getStaticResourceWithMissingContextPath() {
|
||||
void getStaticResourceWithMissingContextPath() {
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
request.setContextPath("/contextpath-longer-than-request-path");
|
||||
request.setRequestURI("/contextpath-longer-than-request-path/style.css");
|
||||
@@ -100,7 +101,7 @@ public class ResourceUrlProviderTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getFingerprintedResourceUrl() {
|
||||
void getFingerprintedResourceUrl() {
|
||||
Map<String, VersionStrategy> versionStrategyMap = new HashMap<>();
|
||||
versionStrategyMap.put("/**", new ContentVersionStrategy());
|
||||
VersionResourceResolver versionResolver = new VersionResourceResolver();
|
||||
@@ -116,7 +117,7 @@ public class ResourceUrlProviderTests {
|
||||
}
|
||||
|
||||
@Test // SPR-12647
|
||||
public void bestPatternMatch() throws Exception {
|
||||
void bestPatternMatch() throws Exception {
|
||||
ResourceHttpRequestHandler otherHandler = new ResourceHttpRequestHandler();
|
||||
otherHandler.setLocations(this.locations);
|
||||
Map<String, VersionStrategy> versionStrategyMap = new HashMap<>();
|
||||
@@ -138,7 +139,7 @@ public class ResourceUrlProviderTests {
|
||||
|
||||
@Test // SPR-12592
|
||||
@SuppressWarnings("resource")
|
||||
public void initializeOnce() throws Exception {
|
||||
void initializeOnce() throws Exception {
|
||||
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
|
||||
context.setServletContext(new MockServletContext());
|
||||
context.register(HandlerMappingConfiguration.class);
|
||||
@@ -149,8 +150,30 @@ public class ResourceUrlProviderTests {
|
||||
assertThat(urlProviderBean.isAutodetect()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void initializeOnCurrentContext() {
|
||||
AnnotationConfigWebApplicationContext parentContext = new AnnotationConfigWebApplicationContext();
|
||||
parentContext.setServletContext(new MockServletContext());
|
||||
parentContext.register(ParentHandlerMappingConfiguration.class);
|
||||
|
||||
AnnotationConfigWebApplicationContext childContext = new AnnotationConfigWebApplicationContext();
|
||||
childContext.setParent(parentContext);
|
||||
childContext.setServletContext(new MockServletContext());
|
||||
childContext.register(HandlerMappingConfiguration.class);
|
||||
|
||||
parentContext.refresh();
|
||||
childContext.refresh();
|
||||
|
||||
ResourceUrlProvider parentUrlProvider = parentContext.getBean(ResourceUrlProvider.class);
|
||||
assertThat(parentUrlProvider.getHandlerMap()).isEmpty();
|
||||
assertThat(parentUrlProvider.isAutodetect()).isTrue();
|
||||
ResourceUrlProvider childUrlProvider = childContext.getBean(ResourceUrlProvider.class);
|
||||
assertThat(childUrlProvider.getHandlerMap()).containsOnlyKeys("/resources/**");
|
||||
assertThat(childUrlProvider.isAutodetect()).isFalse();
|
||||
}
|
||||
|
||||
@Test // SPR-16296
|
||||
public void getForLookupPathShouldNotFailIfPathContainsDoubleSlashes() {
|
||||
void getForLookupPathShouldNotFailIfPathContainsDoubleSlashes() {
|
||||
// given
|
||||
ResourceResolver mockResourceResolver = mock(ResourceResolver.class);
|
||||
given(mockResourceResolver.resolveUrlPath(any(), any(), any())).willReturn("some-path");
|
||||
@@ -185,4 +208,14 @@ public class ResourceUrlProviderTests {
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@SuppressWarnings({"unused", "WeakerAccess"})
|
||||
static class ParentHandlerMappingConfiguration {
|
||||
|
||||
@Bean
|
||||
public ResourceUrlProvider resourceUrlProvider() {
|
||||
return new ResourceUrlProvider();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user