diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebInfConfiguration.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebInfConfiguration.java index b8efd3fdfd9..08fcccbe4dc 100644 --- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebInfConfiguration.java +++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebInfConfiguration.java @@ -785,8 +785,11 @@ public class WebInfConfiguration extends AbstractConfiguration } catch (Exception e) { - LOG.warn("Can't get resource for resourceBase", e); - LOG.debug(e); + if (LOG.isDebugEnabled()) + { + LOG.debug("Can't get resource base name", e); + } + canonicalName.append("-"); // empty resourceBaseName segment } //Context name @@ -818,60 +821,50 @@ public class WebInfConfiguration extends AbstractConfiguration } catch (IOException e) { - LOG.ignore(e); + if (LOG.isDebugEnabled()) + { + LOG.debug("Resource has no File reference: {}", resource); + } } // Use URI itself. URI uri = resource.getURI(); if (uri == null) { - throw new RuntimeException("Unable to produce URI from resource: " + resource); + if (LOG.isDebugEnabled()) + { + LOG.debug("Resource has no URI reference: {}", resource); + } + return ""; } + return getUriLastPathSegment(uri); } protected static String getUriLastPathSegment(URI uri) { - String path = uri.getPath(); - - if ("jar".equalsIgnoreCase(uri.getScheme())) + String ssp = uri.getSchemeSpecificPart(); + // strip off deep jar:file: reference information + int idx = ssp.indexOf("!/"); + if (idx != -1) { - String schemeSpecificPart = uri.getRawSchemeSpecificPart(); - URI inner = URI.create(schemeSpecificPart); - if ("file".equalsIgnoreCase(inner.getScheme())) - { - path = inner.getRawPath(); - int idx = path.lastIndexOf("!/"); - if (idx >= 0) - { - String pathInJar = path.substring(idx + 2); - if (StringUtil.isNotBlank(pathInJar)) - { - URI pathInJarUri = URI.create(pathInJar); - return getUriLastPathSegment(pathInJarUri); - } - else - { - // Strip empty "!/" - path = path.substring(0, idx); - } - } - // if we reached here, we have "jar:file:" but no - // internal jar reference with "!/" present - } - else - { - // inner URI is not "file" - return getUriLastPathSegment(inner); - } + ssp = ssp.substring(0, idx); } - if (path.endsWith("/")) - path = path.substring(0, path.length() - 1); - // get just the last part which is the filename - int i = path.lastIndexOf("/"); + // Strip off trailing '/' if present + if (ssp.endsWith("/")) + { + ssp = ssp.substring(0, ssp.length() - 1); + } - return path.substring(i + 1); + // Only interested in last segment + idx = ssp.lastIndexOf('/'); + if (idx != -1) + { + ssp = ssp.substring(idx + 1); + } + + return ssp; } protected List findClassDirs(WebAppContext context) diff --git a/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/WebInfConfigurationTest.java b/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/WebInfConfigurationTest.java index 130de381851..28c1f5a0aa7 100644 --- a/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/WebInfConfigurationTest.java +++ b/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/WebInfConfigurationTest.java @@ -158,7 +158,7 @@ public class WebInfConfigurationTest assertThat(WebInfConfiguration.getResourceBaseName(resource), is(expectedName)); } - public static Stream baseResourceNames() + public static Stream fileBaseResourceNames() { return Stream.of( Arguments.of("test.war", "test.war"), @@ -178,7 +178,7 @@ public class WebInfConfigurationTest } @ParameterizedTest - @MethodSource("baseResourceNames") + @MethodSource("fileBaseResourceNames") public void testPathGetResourceBaseName(String basePath, String expectedName) throws IOException { Path root = workDir.getPath(); @@ -198,15 +198,43 @@ public class WebInfConfigurationTest assertThat(WebInfConfiguration.getResourceBaseName(resource), is(expectedName)); } + public static Stream fileUriBaseResourceNames() + { + return Stream.of( + Arguments.of("test.war", "test.war"), + Arguments.of("a/b/c/test.war", "test.war"), + Arguments.of("bar%2Fbaz/test.war", "test.war"), + Arguments.of("fizz buzz/test.war", "test.war"), + Arguments.of("another one/bites the dust/", "bites the dust"), + Arguments.of("another+one/bites+the+dust/", "bites+the+dust"), + Arguments.of("another%20one/bites%20the%20dust/", "bites%20the%20dust"), + Arguments.of("spanish/n\u00FAmero.war", "n\u00FAmero.war"), + Arguments.of("spanish/n%C3%BAmero.war", "n%C3%BAmero.war"), + Arguments.of("a/b!/", "b"), + Arguments.of("a/b!/c/", "b"), + Arguments.of("a/b!/c/d/", "b"), + Arguments.of("a/b%21/", "b%21") + ); + } + /** * Similar to testPathGetResourceBaseName, but with "file:" URIs */ @ParameterizedTest - @MethodSource("baseResourceNames") + @MethodSource("fileUriBaseResourceNames") public void testFileUriGetUriLastPathSegment(String basePath, String expectedName) throws IOException { Path root = workDir.getPath(); Path base = root.resolve(basePath); + if (basePath.endsWith("/")) + { + FS.ensureDirExists(base); + } + else + { + FS.ensureDirExists(base.getParent()); + FS.touch(base); + } URI uri = base.toUri(); if (OS.MAC.isCurrentOs()) { @@ -216,7 +244,7 @@ public class WebInfConfigurationTest assertThat(WebInfConfiguration.getUriLastPathSegment(uri), is(expectedName)); } - public static Stream jarFileBaseResourceNames() throws URISyntaxException, IOException + public static Stream uriLastSegmentSource() throws URISyntaxException, IOException { Path testJar = MavenTestingUtils.getTestResourcePathFile(TEST_RESOURCE_JAR); URI uri = new URI("jar", testJar.toUri().toASCIIString(), null); @@ -243,17 +271,7 @@ public class WebInfConfigurationTest } else { - String lastPathSegment = TEST_RESOURCE_JAR; - if (path.getFileName() != null) - { - lastPathSegment = path.getFileName().toString(); - } - // Strip last '/' from directory entries - if (Files.isDirectory(path) && lastPathSegment.endsWith("/")) - { - lastPathSegment = lastPathSegment.substring(0, lastPathSegment.length() - 1); - } - arguments.add(Arguments.of(path.toUri(), lastPathSegment)); + arguments.add(Arguments.of(path.toUri(), TEST_RESOURCE_JAR)); } }); } @@ -263,11 +281,11 @@ public class WebInfConfigurationTest } /** - * Tests of "jar:file:" based URIs + * Tests of URIs last segment, including "jar:file:" based URIs. */ @ParameterizedTest - @MethodSource("jarFileBaseResourceNames") - public void testJarFileUriGetUriLastPathSegment(URI uri, String expectedName) throws IOException + @MethodSource("uriLastSegmentSource") + public void testGetUriLastPathSegment(URI uri, String expectedName) throws IOException { assertThat(WebInfConfiguration.getUriLastPathSegment(uri), is(expectedName)); }