From a2c52a97babdb927d809ad55c696c42d160d4fff Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Tue, 12 Oct 2021 11:59:39 +0100 Subject: [PATCH] Filter non-existing static resource locations See gh-27538 --- .../resource/ResourceHttpRequestHandler.java | 10 ++++++++-- .../ResourceHttpRequestHandlerTests.java | 20 ++++++++++++++++++- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java index ed49cf3cd2..0831a2a2f2 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java @@ -25,6 +25,7 @@ import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.stream.Collectors; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; @@ -424,6 +425,7 @@ public class ResourceHttpRequestHandler extends WebContentGenerator } private void resolveResourceLocations() { + List result = new ArrayList<>(); if (!this.locationValues.isEmpty()) { ApplicationContext applicationContext = obtainApplicationContext(); for (String location : this.locationValues) { @@ -452,7 +454,7 @@ public class ResourceHttpRequestHandler extends WebContentGenerator "but resolved to a Resource of type: " + resource.getClass() + ". " + "If this is intentional, please pass it as a pre-configured Resource via setLocations."); } - this.locationsToUse.add(resource); + result.add(resource); if (charset != null) { if (!(resource instanceof UrlResource)) { throw new IllegalArgumentException("Unexpected charset for non-UrlResource: " + resource); @@ -461,7 +463,11 @@ public class ResourceHttpRequestHandler extends WebContentGenerator } } } - this.locationsToUse.addAll(this.locationResources); + + result.addAll(this.locationResources); + result = result.stream().filter(Resource::exists).collect(Collectors.toList()); + + this.locationsToUse.addAll(result); } /** diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandlerTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandlerTests.java index 6ced3a30d3..2d3ce43956 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandlerTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandlerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 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. @@ -312,6 +312,24 @@ public class ResourceHttpRequestHandlerTests { assertThat(this.response.getContentAsString()).isEqualTo("h1 { color:red; }"); } + @Test // gh-27538 + public void filterNonExistingLocations() throws Exception { + List inputLocations = Arrays.asList( + new ClassPathResource("test/", getClass()), + new ClassPathResource("testalternatepath/", getClass()), + new ClassPathResource("nosuchpath/", getClass())); + + ResourceHttpRequestHandler handler = new ResourceHttpRequestHandler(); + handler.setServletContext(new MockServletContext()); + handler.setLocations(inputLocations); + handler.afterPropertiesSet(); + + List actual = handler.getLocations(); + assertThat(actual).hasSize(2); + assertThat(actual.get(0).getURL().toString()).endsWith("test/"); + assertThat(actual.get(1).getURL().toString()).endsWith("testalternatepath/"); + } + @Test public void testInvalidPath() throws Exception {