6 changed files with 226 additions and 8 deletions
@ -0,0 +1 @@ |
|||||||
|
h1 { color:red; } |
||||||
@ -0,0 +1,183 @@ |
|||||||
|
/* |
||||||
|
* 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. |
||||||
|
* You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
*/ |
||||||
|
package org.springframework.web.servlet.resource; |
||||||
|
|
||||||
|
import java.io.IOException; |
||||||
|
import java.net.MalformedURLException; |
||||||
|
import java.net.URI; |
||||||
|
import java.net.URL; |
||||||
|
import java.nio.charset.StandardCharsets; |
||||||
|
import java.util.stream.Stream; |
||||||
|
|
||||||
|
import javax.servlet.ServletException; |
||||||
|
|
||||||
|
import org.junit.jupiter.params.ParameterizedTest; |
||||||
|
import org.junit.jupiter.params.provider.Arguments; |
||||||
|
import org.junit.jupiter.params.provider.MethodSource; |
||||||
|
|
||||||
|
import org.springframework.core.io.ClassPathResource; |
||||||
|
import org.springframework.core.io.FileSystemResource; |
||||||
|
import org.springframework.core.io.UrlResource; |
||||||
|
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; |
||||||
|
import org.springframework.web.servlet.DispatcherServlet; |
||||||
|
import org.springframework.web.servlet.config.annotation.EnableWebMvc; |
||||||
|
import org.springframework.web.servlet.config.annotation.PathMatchConfigurer; |
||||||
|
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; |
||||||
|
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; |
||||||
|
import org.springframework.web.testfixture.servlet.MockHttpServletRequest; |
||||||
|
import org.springframework.web.testfixture.servlet.MockHttpServletResponse; |
||||||
|
import org.springframework.web.testfixture.servlet.MockServletConfig; |
||||||
|
import org.springframework.web.testfixture.servlet.MockServletContext; |
||||||
|
import org.springframework.web.util.UriUtils; |
||||||
|
import org.springframework.web.util.pattern.PathPatternParser; |
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat; |
||||||
|
import static org.junit.jupiter.params.provider.Arguments.arguments; |
||||||
|
|
||||||
|
/** |
||||||
|
* Integration tests for static resource handling. |
||||||
|
* @author Rossen Stoyanchev |
||||||
|
*/ |
||||||
|
public class ResourceHttpRequestHandlerIntegrationTests { |
||||||
|
|
||||||
|
private final MockServletContext servletContext = new MockServletContext(); |
||||||
|
|
||||||
|
private final MockServletConfig servletConfig = new MockServletConfig(this.servletContext); |
||||||
|
|
||||||
|
|
||||||
|
public static Stream<Arguments> argumentSource() { |
||||||
|
return Stream.of( |
||||||
|
arguments(true, "/cp"), |
||||||
|
arguments(true, "/fs"), |
||||||
|
arguments(true, "/url"), |
||||||
|
arguments(false, "/cp"), |
||||||
|
arguments(false, "/fs"), |
||||||
|
arguments(false, "/url") |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@ParameterizedTest |
||||||
|
@MethodSource("argumentSource") |
||||||
|
void cssFile(boolean usePathPatterns, String pathPrefix) throws Exception { |
||||||
|
MockHttpServletRequest request = initRequest(pathPrefix + "/test/foo.css"); |
||||||
|
MockHttpServletResponse response = new MockHttpServletResponse(); |
||||||
|
|
||||||
|
DispatcherServlet servlet = initDispatcherServlet(usePathPatterns, WebConfig.class); |
||||||
|
servlet.service(request, response); |
||||||
|
|
||||||
|
String description = "usePathPattern=" + usePathPatterns + ", prefix=" + pathPrefix; |
||||||
|
assertThat(response.getStatus()).as(description).isEqualTo(200); |
||||||
|
assertThat(response.getContentType()).as(description).isEqualTo("text/css"); |
||||||
|
assertThat(response.getContentAsString()).as(description).isEqualTo("h1 { color:red; }"); |
||||||
|
} |
||||||
|
|
||||||
|
@ParameterizedTest |
||||||
|
@MethodSource("argumentSource") |
||||||
|
void classpathLocationWithEncodedPath(boolean usePathPatterns, String pathPrefix) throws Exception { |
||||||
|
MockHttpServletRequest request = initRequest(pathPrefix + "/test/фоо.css"); |
||||||
|
MockHttpServletResponse response = new MockHttpServletResponse(); |
||||||
|
|
||||||
|
DispatcherServlet servlet = initDispatcherServlet(usePathPatterns, WebConfig.class); |
||||||
|
servlet.service(request, response); |
||||||
|
|
||||||
|
String description = "usePathPattern=" + usePathPatterns + ", prefix=" + pathPrefix; |
||||||
|
assertThat(response.getStatus()).as(description).isEqualTo(200); |
||||||
|
assertThat(response.getContentType()).as(description).isEqualTo("text/css"); |
||||||
|
assertThat(response.getContentAsString()).as(description).isEqualTo("h1 { color:red; }"); |
||||||
|
} |
||||||
|
|
||||||
|
private DispatcherServlet initDispatcherServlet(boolean usePathPatterns, Class<?>... configClasses) |
||||||
|
throws ServletException { |
||||||
|
|
||||||
|
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext(); |
||||||
|
context.register(configClasses); |
||||||
|
if (usePathPatterns) { |
||||||
|
context.register(PathPatternParserConfig.class); |
||||||
|
} |
||||||
|
context.setServletConfig(this.servletConfig); |
||||||
|
context.refresh(); |
||||||
|
|
||||||
|
DispatcherServlet servlet = new DispatcherServlet(); |
||||||
|
servlet.setApplicationContext(context); |
||||||
|
servlet.init(this.servletConfig); |
||||||
|
return servlet; |
||||||
|
} |
||||||
|
|
||||||
|
private MockHttpServletRequest initRequest(String path) { |
||||||
|
path = UriUtils.encodePath(path, StandardCharsets.UTF_8); |
||||||
|
MockHttpServletRequest request = new MockHttpServletRequest("GET", path); |
||||||
|
request.setCharacterEncoding(StandardCharsets.UTF_8.name()); |
||||||
|
return request; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@EnableWebMvc |
||||||
|
static class WebConfig implements WebMvcConfigurer { |
||||||
|
|
||||||
|
@Override |
||||||
|
public void addResourceHandlers(ResourceHandlerRegistry registry) { |
||||||
|
ClassPathResource classPathLocation = new ClassPathResource("", getClass()); |
||||||
|
String path = getPath(classPathLocation); |
||||||
|
|
||||||
|
registerClasspathLocation("/cp/**", classPathLocation, registry); |
||||||
|
registerFileSystemLocation("/fs/**", path, registry); |
||||||
|
registerUrlLocation("/url/**", "file://" + path, registry); |
||||||
|
} |
||||||
|
|
||||||
|
protected void registerClasspathLocation(String pattern, ClassPathResource resource, ResourceHandlerRegistry registry) { |
||||||
|
registry.addResourceHandler(pattern).addResourceLocations(resource); |
||||||
|
} |
||||||
|
|
||||||
|
protected void registerFileSystemLocation(String pattern, String path, ResourceHandlerRegistry registry) { |
||||||
|
FileSystemResource fileSystemLocation = new FileSystemResource(path); |
||||||
|
registry.addResourceHandler(pattern).addResourceLocations(fileSystemLocation); |
||||||
|
} |
||||||
|
|
||||||
|
protected void registerUrlLocation(String pattern, String path, ResourceHandlerRegistry registry) { |
||||||
|
UrlResource urlLocation = new UrlResource(toURL(path)); |
||||||
|
registry.addResourceHandler(pattern).addResourceLocations(urlLocation); |
||||||
|
} |
||||||
|
|
||||||
|
private String getPath(ClassPathResource resource) { |
||||||
|
try { |
||||||
|
return resource.getFile().getCanonicalPath().replace("classes/java", "resources") + "/"; |
||||||
|
} |
||||||
|
catch (IOException ex) { |
||||||
|
throw new IllegalStateException(ex); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private URL toURL(String path) { |
||||||
|
try { |
||||||
|
return URI.create(path).toURL(); |
||||||
|
} |
||||||
|
catch (MalformedURLException ex) { |
||||||
|
throw new IllegalStateException(ex); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
static class PathPatternParserConfig implements WebMvcConfigurer { |
||||||
|
|
||||||
|
@Override |
||||||
|
public void configurePathMatch(PathMatchConfigurer configurer) { |
||||||
|
configurer.setPatternParser(new PathPatternParser()); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
Loading…
Reference in new issue