From a29a70d2f4178cd0896eb615c37a4ab2252b7a94 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Tue, 24 Apr 2018 09:29:59 +0100 Subject: [PATCH] Fix handling of static resource jar paths containing a + Closes gh-12942 --- .../embedded/IdeApplicationLauncher.java | 2 +- ...stractEmbeddedServletContainerFactory.java | 12 +++++- .../JettyEmbeddedServletContainerFactory.java | 4 +- .../embedded/tomcat/TomcatResources.java | 38 +++++++++---------- ...dertowEmbeddedServletContainerFactory.java | 16 ++++---- 5 files changed, 38 insertions(+), 34 deletions(-) diff --git a/spring-boot-integration-tests/spring-boot-integration-tests-embedded-servlet-container/src/test/java/org/springframework/boot/context/embedded/IdeApplicationLauncher.java b/spring-boot-integration-tests/spring-boot-integration-tests-embedded-servlet-container/src/test/java/org/springframework/boot/context/embedded/IdeApplicationLauncher.java index 5d41434b51..681c684b6f 100644 --- a/spring-boot-integration-tests/spring-boot-integration-tests-embedded-servlet-container/src/test/java/org/springframework/boot/context/embedded/IdeApplicationLauncher.java +++ b/spring-boot-integration-tests/spring-boot-integration-tests-embedded-servlet-container/src/test/java/org/springframework/boot/context/embedded/IdeApplicationLauncher.java @@ -40,7 +40,7 @@ import org.springframework.util.StringUtils; */ class IdeApplicationLauncher extends AbstractApplicationLauncher { - private final File exploded = new File("target/ide application"); + private final File exploded = new File("target/the+ide application"); IdeApplicationLauncher(ApplicationBuilder applicationBuilder) { super(applicationBuilder); diff --git a/spring-boot/src/main/java/org/springframework/boot/context/embedded/AbstractEmbeddedServletContainerFactory.java b/spring-boot/src/main/java/org/springframework/boot/context/embedded/AbstractEmbeddedServletContainerFactory.java index 3d00f2e7a0..64611d1223 100644 --- a/spring-boot/src/main/java/org/springframework/boot/context/embedded/AbstractEmbeddedServletContainerFactory.java +++ b/spring-boot/src/main/java/org/springframework/boot/context/embedded/AbstractEmbeddedServletContainerFactory.java @@ -109,7 +109,7 @@ public abstract class AbstractEmbeddedServletContainerFactory private boolean isStaticResourceJar(URL url) { try { if ("file".equals(url.getProtocol())) { - File file = new File(getDecodedFile(url)); + File file = new File(url.toURI()); return (file.isDirectory() && new File(file, "META-INF/resources").isDirectory()) || isResourcesJar(file); @@ -122,12 +122,20 @@ public abstract class AbstractEmbeddedServletContainerFactory } } } - catch (IOException ex) { + catch (Exception ex) { throw new IllegalStateException(ex); } return false; } + /** + * Converts the given {@code url} into a decoded file path. + * + * @param url the url to convert + * @return the file path + * @deprecated Since 1.5.13 in favor of {@link File#File(java.net.URI)} + */ + @Deprecated protected final String getDecodedFile(URL url) { try { return URLDecoder.decode(url.getFile(), "UTF-8"); diff --git a/spring-boot/src/main/java/org/springframework/boot/context/embedded/jetty/JettyEmbeddedServletContainerFactory.java b/spring-boot/src/main/java/org/springframework/boot/context/embedded/jetty/JettyEmbeddedServletContainerFactory.java index dac1fc034c..fe1a0f2e0a 100644 --- a/spring-boot/src/main/java/org/springframework/boot/context/embedded/jetty/JettyEmbeddedServletContainerFactory.java +++ b/spring-boot/src/main/java/org/springframework/boot/context/embedded/jetty/JettyEmbeddedServletContainerFactory.java @@ -431,9 +431,9 @@ public class JettyEmbeddedServletContainerFactory } } - private Resource createResource(URL url) throws IOException { + private Resource createResource(URL url) throws Exception { if ("file".equals(url.getProtocol())) { - File file = new File(getDecodedFile(url)); + File file = new File(url.toURI()); if (file.isFile()) { return Resource.newResource("jar:" + url + "!/META-INF/resources"); } diff --git a/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TomcatResources.java b/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TomcatResources.java index e9150258f6..98a23dbbbc 100644 --- a/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TomcatResources.java +++ b/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TomcatResources.java @@ -16,11 +16,11 @@ package org.springframework.boot.context.embedded.tomcat; -import java.io.UnsupportedEncodingException; +import java.io.File; import java.lang.reflect.Method; import java.net.MalformedURLException; +import java.net.URISyntaxException; import java.net.URL; -import java.net.URLDecoder; import java.util.List; import javax.naming.directory.DirContext; @@ -49,31 +49,27 @@ abstract class TomcatResources { void addResourceJars(List resourceJarUrls) { for (URL url : resourceJarUrls) { - String file = getDecodedFile(url); - if (file.endsWith(".jar") || file.endsWith(".jar!/")) { - String jar = url.toString(); - if (!jar.startsWith("jar:")) { - // A jar file in the file system. Convert to Jar URL. - jar = "jar:" + jar + "!/"; + try { + String path = url.getPath(); + if (path.endsWith(".jar") || path.endsWith(".jar!/")) { + String jar = url.toString(); + if (!jar.startsWith("jar:")) { + // A jar file in the file system. Convert to Jar URL. + jar = "jar:" + jar + "!/"; + } + addJar(jar); + } + else { + addDir(new File(url.toURI()).getAbsolutePath(), url); } - addJar(jar); } - else { - addDir(file, url); + catch (URISyntaxException ex) { + throw new IllegalStateException( + "Failed to create File from URL '" + url + "'"); } } } - private String getDecodedFile(URL url) { - try { - return URLDecoder.decode(url.getFile(), "UTF-8"); - } - catch (UnsupportedEncodingException ex) { - throw new IllegalStateException( - "Failed to decode '" + url.getFile() + "' using UTF-8"); - } - } - protected final Context getContext() { return this.context; } diff --git a/spring-boot/src/main/java/org/springframework/boot/context/embedded/undertow/UndertowEmbeddedServletContainerFactory.java b/spring-boot/src/main/java/org/springframework/boot/context/embedded/undertow/UndertowEmbeddedServletContainerFactory.java index a290a3216c..7d3fa84a3f 100644 --- a/spring-boot/src/main/java/org/springframework/boot/context/embedded/undertow/UndertowEmbeddedServletContainerFactory.java +++ b/spring-boot/src/main/java/org/springframework/boot/context/embedded/undertow/UndertowEmbeddedServletContainerFactory.java @@ -494,18 +494,18 @@ public class UndertowEmbeddedServletContainerFactory resourceManagers.add(rootResourceManager); for (URL url : metaInfResourceUrls) { if ("file".equals(url.getProtocol())) { - File file = new File(getDecodedFile(url)); - if (file.isFile()) { - try { + try { + File file = new File(url.toURI()); + if (file.isFile()) { resourceJarUrls.add(new URL("jar:" + url + "!/")); } - catch (MalformedURLException ex) { - throw new RuntimeException(ex); + else { + resourceManagers.add(new FileResourceManager( + new File(file, "META-INF/resources"), 0)); } } - else { - resourceManagers.add(new FileResourceManager( - new File(file, "META-INF/resources"), 0)); + catch (Exception ex) { + throw new RuntimeException(ex); } } else {