Skip to content

Commit 88423c5

Browse files
committed
Polish "Fix handling of static resource jars with spaces in their paths"
Closes gh-11991
1 parent 9cd1a4b commit 88423c5

File tree

6 files changed

+44
-75
lines changed

6 files changed

+44
-75
lines changed

spring-boot-integration-tests/spring-boot-integration-tests-embedded-servlet-container/src/test/java/org/springframework/boot/context/embedded/IdeApplicationLauncher.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2017 the original author or authors.
2+
* Copyright 2012-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -40,7 +40,7 @@
4040
*/
4141
class IdeApplicationLauncher extends AbstractApplicationLauncher {
4242

43-
private final File exploded = new File("target/ide");
43+
private final File exploded = new File("target/ide application");
4444

4545
IdeApplicationLauncher(ApplicationBuilder applicationBuilder) {
4646
super(applicationBuilder);

spring-boot/src/main/java/org/springframework/boot/context/embedded/AbstractEmbeddedServletContainerFactory.java

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import java.io.File;
2020
import java.io.IOException;
21+
import java.io.UnsupportedEncodingException;
2122
import java.net.JarURLConnection;
2223
import java.net.URL;
2324
import java.net.URLClassLoader;
@@ -97,32 +98,27 @@ protected List<URL> getUrlsOfJarsWithMetaInfResources() {
9798
List<URL> staticResourceUrls = new ArrayList<URL>();
9899
if (classLoader instanceof URLClassLoader) {
99100
for (URL url : ((URLClassLoader) classLoader).getURLs()) {
100-
if (isStaticResource(url)) {
101+
if (isStaticResourceJar(url)) {
101102
staticResourceUrls.add(url);
102103
}
103104
}
104105
}
105106
return staticResourceUrls;
106107
}
107108

108-
protected boolean isStaticResource(URL url) {
109+
private boolean isStaticResourceJar(URL url) {
109110
try {
110111
if ("file".equals(url.getProtocol())) {
111-
File file = new File(URLDecoder.decode(url.getFile(), "UTF-8"));
112-
if (file.isDirectory()
113-
&& new File(file, "META-INF/resources").isDirectory()) {
114-
return true;
115-
}
116-
else if (isResourcesJar(file)) {
117-
return true;
118-
}
112+
File file = new File(getDecodedFile(url), "UTF-8");
113+
return (file.isDirectory()
114+
&& new File(file, "META-INF/resources").isDirectory())
115+
|| isResourcesJar(file);
119116
}
120117
else {
121118
URLConnection connection = url.openConnection();
122-
if (connection instanceof JarURLConnection) {
123-
if (isResourcesJar((JarURLConnection) connection)) {
124-
return true;
125-
}
119+
if (connection instanceof JarURLConnection
120+
&& isResourcesJar((JarURLConnection) connection)) {
121+
return true;
126122
}
127123
}
128124
}
@@ -132,12 +128,23 @@ else if (isResourcesJar(file)) {
132128
return false;
133129
}
134130

131+
protected final String getDecodedFile(URL url) {
132+
try {
133+
return URLDecoder.decode(url.getFile(), "UTF-8");
134+
}
135+
catch (UnsupportedEncodingException ex) {
136+
throw new IllegalStateException(
137+
"Failed to decode '" + url.getFile() + "' using UTF-8");
138+
}
139+
}
140+
135141
private boolean isResourcesJar(JarURLConnection connection) {
136142
try {
137143
return isResourcesJar(connection.getJarFile());
138144
}
139145
catch (IOException ex) {
140-
logger.warn("Unable to open jar to determine if it contains static resources", ex);
146+
this.logger.warn("Unable to open jar from connection '" + connection
147+
+ "' to determine if it contains static resources", ex);
141148
return false;
142149
}
143150
}
@@ -147,7 +154,8 @@ private boolean isResourcesJar(File file) {
147154
return file.getName().endsWith(".jar") && isResourcesJar(new JarFile(file));
148155
}
149156
catch (IOException ex) {
150-
logger.warn("Unable to open jar to determine if it contains static resources", ex);
157+
this.logger.warn("Unable to open jar '" + file
158+
+ "' to determine if it contains static resources", ex);
151159
return false;
152160
}
153161
}

spring-boot/src/main/java/org/springframework/boot/context/embedded/jetty/JettyEmbeddedServletContainerFactory.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -433,7 +433,7 @@ private void configureDocumentRoot(WebAppContext handler) {
433433

434434
private Resource createResource(URL url) throws IOException {
435435
if ("file".equals(url.getProtocol())) {
436-
File file = new File(url.getFile());
436+
File file = new File(getDecodedFile(url));
437437
if (file.isFile()) {
438438
return Resource.newResource("jar:" + url + "!/META-INF/resources");
439439
}

spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TomcatResources.java

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2017 the original author or authors.
2+
* Copyright 2012-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,9 +16,11 @@
1616

1717
package org.springframework.boot.context.embedded.tomcat;
1818

19+
import java.io.UnsupportedEncodingException;
1920
import java.lang.reflect.Method;
2021
import java.net.MalformedURLException;
2122
import java.net.URL;
23+
import java.net.URLDecoder;
2224
import java.util.List;
2325

2426
import javax.naming.directory.DirContext;
@@ -47,7 +49,7 @@ abstract class TomcatResources {
4749

4850
void addResourceJars(List<URL> resourceJarUrls) {
4951
for (URL url : resourceJarUrls) {
50-
String file = url.getFile();
52+
String file = getDecodedFile(url);
5153
if (file.endsWith(".jar") || file.endsWith(".jar!/")) {
5254
String jar = url.toString();
5355
if (!jar.startsWith("jar:")) {
@@ -62,6 +64,16 @@ void addResourceJars(List<URL> resourceJarUrls) {
6264
}
6365
}
6466

67+
private String getDecodedFile(URL url) {
68+
try {
69+
return URLDecoder.decode(url.getFile(), "UTF-8");
70+
}
71+
catch (UnsupportedEncodingException ex) {
72+
throw new IllegalStateException(
73+
"Failed to decode '" + url.getFile() + "' using UTF-8");
74+
}
75+
}
76+
6577
protected final Context getContext() {
6678
return this.context;
6779
}

spring-boot/src/main/java/org/springframework/boot/context/embedded/undertow/UndertowEmbeddedServletContainerFactory.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2017 the original author or authors.
2+
* Copyright 2012-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -494,7 +494,7 @@ private ResourceManager getDocumentRootResourceManager() {
494494
resourceManagers.add(rootResourceManager);
495495
for (URL url : metaInfResourceUrls) {
496496
if ("file".equals(url.getProtocol())) {
497-
File file = new File(url.getFile());
497+
File file = new File(getDecodedFile(url));
498498
if (file.isFile()) {
499499
try {
500500
resourceJarUrls.add(new URL("jar:" + url + "!/"));

spring-boot/src/test/java/org/springframework/boot/context/embedded/AbstractEmbeddedServletContainerFactoryTests.java

Lines changed: 1 addition & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2017 the original author or authors.
2+
* Copyright 2012-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -18,7 +18,6 @@
1818

1919
import java.io.File;
2020
import java.io.FileInputStream;
21-
import java.io.FileOutputStream;
2221
import java.io.FileWriter;
2322
import java.io.FilenameFilter;
2423
import java.io.IOException;
@@ -50,8 +49,6 @@
5049
import java.util.concurrent.TimeUnit;
5150
import java.util.concurrent.atomic.AtomicBoolean;
5251
import java.util.concurrent.atomic.AtomicReference;
53-
import java.util.jar.JarEntry;
54-
import java.util.jar.JarOutputStream;
5552
import java.util.zip.GZIPInputStream;
5653

5754
import javax.net.ssl.SSLContext;
@@ -1038,54 +1035,6 @@ public void explodedWarFileDocumentRootWhenRunningFromPackagedWar() throws Excep
10381035
assertThat(documentRoot).isNull();
10391036
}
10401037

1041-
@Test
1042-
public void includeJarWithStaticResources() throws Exception {
1043-
AbstractEmbeddedServletContainerFactory factory = getFactory();
1044-
File jarFile = this.temporaryFolder.newFile("test.jar");
1045-
JarOutputStream jarOutputStream = new JarOutputStream(new FileOutputStream(jarFile));
1046-
JarEntry jarEntry = new JarEntry("META-INF/resources");
1047-
jarOutputStream.putNextEntry(jarEntry);
1048-
jarOutputStream.closeEntry();
1049-
jarOutputStream.close();
1050-
String path = "file:" + jarFile.getAbsolutePath();
1051-
1052-
boolean isStaticResource = factory.isStaticResource(new URL(path));
1053-
1054-
assertThat(isStaticResource).isTrue();
1055-
}
1056-
1057-
@Test
1058-
public void includeJarWithStaticResourcesWithUrlEncodedSpaces() throws Exception {
1059-
AbstractEmbeddedServletContainerFactory factory = getFactory();
1060-
this.temporaryFolder.newFolder("test parent");
1061-
File jarFile = this.temporaryFolder.newFile("test parent/test.jar");
1062-
JarOutputStream jarOutputStream = new JarOutputStream(new FileOutputStream(jarFile));
1063-
JarEntry jarEntry = new JarEntry("META-INF/resources");
1064-
jarOutputStream.putNextEntry(jarEntry);
1065-
jarOutputStream.closeEntry();
1066-
jarOutputStream.close();
1067-
String path = "file:" + jarFile.getAbsolutePath().replaceAll(" ", "%20");
1068-
1069-
boolean isStaticResource = factory.isStaticResource(new URL(path));
1070-
1071-
assertThat(isStaticResource).isTrue();
1072-
}
1073-
1074-
@Test
1075-
public void excludeJarWithoutStaticResources() throws Exception {
1076-
AbstractEmbeddedServletContainerFactory factory = getFactory();
1077-
File jarFile = this.temporaryFolder.newFile("test.jar");
1078-
JarOutputStream jarOutputStream = new JarOutputStream(
1079-
new FileOutputStream(jarFile));
1080-
jarOutputStream.closeEntry();
1081-
jarOutputStream.close();
1082-
String path = "file:" + jarFile.getAbsolutePath();
1083-
1084-
boolean isStaticResource = factory.isStaticResource(new URL(path));
1085-
1086-
assertThat(isStaticResource).isFalse();
1087-
}
1088-
10891038
protected abstract void addConnector(int port,
10901039
AbstractEmbeddedServletContainerFactory factory);
10911040

0 commit comments

Comments
 (0)