From 5348750ece8ad0a800e3f0028dfff45bb0d21ff7 Mon Sep 17 00:00:00 2001 From: Thomas Segismont Date: Wed, 21 Jun 2023 08:54:25 +0200 Subject: [PATCH] Supported WAR files in FileResolver (#4747) See #4727 Signed-off-by: Thomas Segismont --- .../core/file/impl/FileResolverImpl.java | 26 ++++++---- .../vertx/core/file/WarFileResolverTest.java | 47 +++++++++++++++++++ 2 files changed, 63 insertions(+), 10 deletions(-) create mode 100644 src/test/java/io/vertx/core/file/WarFileResolverTest.java diff --git a/src/main/java/io/vertx/core/file/impl/FileResolverImpl.java b/src/main/java/io/vertx/core/file/impl/FileResolverImpl.java index 65d6e0b919e..9d2e8a45dcf 100644 --- a/src/main/java/io/vertx/core/file/impl/FileResolverImpl.java +++ b/src/main/java/io/vertx/core/file/impl/FileResolverImpl.java @@ -279,24 +279,30 @@ private File unpackFromJarURL(URL url, String fileName, ClassLoader cl) { ZipFile zip = null; try { String path = url.getPath(); - int idx1 = path.lastIndexOf(".jar!"); - if (idx1 == -1) { - idx1 = path.lastIndexOf(".zip!"); - } - int idx2 = path.lastIndexOf(".jar!", idx1 - 1); - if (idx2 == -1) { - idx2 = path.lastIndexOf(".zip!", idx1 - 1); + int idx1 = -1, idx2 = -1; + for (int i = path.length() - 1; i > 4; ) { + if (path.charAt(i) == '!' && (path.startsWith(".jar", i - 4) || path.startsWith(".zip", i - 4) || path.startsWith(".war", i - 4))) { + if (idx1 == -1) { + idx1 = i; + i -= 4; + continue; + } else { + idx2 = i; + break; + } + } + i--; } if (idx2 == -1) { - File file = new File(decodeURIComponent(path.substring(5, idx1 + 4), false)); + File file = new File(decodeURIComponent(path.substring(5, idx1), false)); zip = new ZipFile(file); } else { - String s = path.substring(idx2 + 6, idx1 + 4); + String s = path.substring(idx2 + 2, idx1); File file = resolveFile(s); zip = new ZipFile(file); } - String inJarPath = path.substring(idx1 + 6); + String inJarPath = path.substring(idx1 + 2); StringBuilder prefixBuilder = new StringBuilder(); int first = 0; int second; diff --git a/src/test/java/io/vertx/core/file/WarFileResolverTest.java b/src/test/java/io/vertx/core/file/WarFileResolverTest.java new file mode 100644 index 00000000000..26e006845ef --- /dev/null +++ b/src/test/java/io/vertx/core/file/WarFileResolverTest.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2011-2023 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 + * which is available at https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 + */ + +package io.vertx.core.file; + +import io.vertx.test.core.TestUtils; +import org.junit.Assert; + +import java.io.File; +import java.io.IOException; +import java.net.URL; +import java.net.URLClassLoader; +import java.nio.file.Files; +import java.util.jar.JarEntry; +import java.util.jar.JarOutputStream; + +public class WarFileResolverTest extends FileResolverTestBase { + + static File getFiles(File baseDir) throws Exception { + File file = Files.createTempFile(TestUtils.MAVEN_TARGET_DIR.toPath(), "", "files.war").toFile(); + Assert.assertTrue(file.delete()); + return ZipFileResolverTest.getFiles( + baseDir, + file, + out -> { + try { + return new JarOutputStream(out); + } catch (IOException e) { + throw new AssertionError(e); + } + }, JarEntry::new); + } + + @Override + protected ClassLoader resourcesLoader(File baseDir) throws Exception { + File files = getFiles(baseDir); + return new URLClassLoader(new URL[]{files.toURI().toURL()}, Thread.currentThread().getContextClassLoader()); + } +}