Improve jetty-util on Windows (#11440)
* Improve jetty-util on Windows * Enable ATOMIC_MOVE on Resource.copyTo() * Add reference to Resource impl in exception. * Attempting to address sneaky Windows path strings that look like URIs * Deprecate URIUtil.correctFileURI in favor of new URIUtil.correctURI method
This commit is contained in:
parent
866f44584c
commit
bb646ed085
|
@ -16,10 +16,12 @@ package org.eclipse.jetty.util;
|
|||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.InvalidPathException;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
|
@ -1640,7 +1642,7 @@ public final class URIUtil
|
|||
// Correct any bad `file:/path` usages, and
|
||||
// force encoding of characters that must be encoded (such as unicode)
|
||||
// for the base
|
||||
String base = correctFileURI(uri).toASCIIString();
|
||||
String base = correctURI(uri).toASCIIString();
|
||||
|
||||
// ensure that the base has a safe encoding suitable for both
|
||||
// URI and Paths.get(URI) later usage
|
||||
|
@ -1698,8 +1700,36 @@ public final class URIUtil
|
|||
*
|
||||
* @param uri the URI to (possibly) correct
|
||||
* @return the new URI with the {@code file:/} substring corrected, or the original URI.
|
||||
* @deprecated use {@link #correctURI(URI)} instead, will be removed in Jetty 12.1.0
|
||||
*/
|
||||
@Deprecated(since = "12.0.7", forRemoval = true)
|
||||
public static URI correctFileURI(URI uri)
|
||||
{
|
||||
return correctURI(uri);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Corrects any bad {@code file} based URIs (even within a {@code jar:file:} based URIs) from the bad out-of-spec
|
||||
* format that various older Java APIs creates (most notably: {@link java.io.File} creates with it's {@link File#toURL()}
|
||||
* and {@link File#toURI()}, along with the side effects of using {@link URL#toURI()})
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* This correction is currently limited to only the {@code file:/} substring in the URI.
|
||||
* If there is a {@code file:/<not-a-slash>} detected, that substring is corrected to
|
||||
* {@code file:///<not-a-slash>}, all other uses of {@code file:}, and URIs without a {@code file:}
|
||||
* substring are left alone.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* Note that Windows UNC based URIs are left alone, along with non-absolute URIs.
|
||||
* </p>
|
||||
*
|
||||
* @param uri the URI to (possibly) correct
|
||||
* @return the new URI with the {@code file:} scheme specific part corrected, or the original URI.
|
||||
*/
|
||||
public static URI correctURI(URI uri)
|
||||
{
|
||||
if ((uri == null) || (uri.getScheme() == null))
|
||||
return uri;
|
||||
|
@ -1845,10 +1875,60 @@ public final class URIUtil
|
|||
{
|
||||
Objects.requireNonNull(resource);
|
||||
|
||||
// Only try URI for string for known schemes, otherwise assume it is a Path
|
||||
return (ResourceFactory.isSupported(resource))
|
||||
? correctFileURI(URI.create(resource))
|
||||
: Paths.get(resource).toUri();
|
||||
if (URIUtil.hasScheme(resource))
|
||||
{
|
||||
try
|
||||
{
|
||||
URI uri = new URI(resource);
|
||||
|
||||
if (ResourceFactory.isSupported(uri))
|
||||
return correctURI(uri);
|
||||
|
||||
// We don't have a supported URI scheme
|
||||
if (uri.getScheme().length() == 1)
|
||||
{
|
||||
// Input is a possible Windows path disguised as a URI "D:/path/to/resource.txt".
|
||||
try
|
||||
{
|
||||
return toURI(Paths.get(resource).toUri().toASCIIString());
|
||||
}
|
||||
catch (InvalidPathException x)
|
||||
{
|
||||
LOG.trace("ignored", x);
|
||||
}
|
||||
}
|
||||
|
||||
// If we reached this point, that means the input String has a scheme,
|
||||
// and is not recognized as supported by the registered schemes in ResourceFactory.
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("URI scheme is not registered: {}", uri.toASCIIString());
|
||||
throw new IllegalArgumentException("URI scheme not registered: " + uri.getScheme());
|
||||
}
|
||||
catch (URISyntaxException x)
|
||||
{
|
||||
// We have an input string that has what looks like a scheme, but isn't a URI.
|
||||
// Eg: "C:\path\to\resource.txt"
|
||||
LOG.trace("ignored", x);
|
||||
}
|
||||
}
|
||||
|
||||
// If we reached this point, we have a String with no valid scheme.
|
||||
// Treat it as a Path, as that's all we have left to investigate.
|
||||
try
|
||||
{
|
||||
return toURI(Paths.get(resource).toUri().toASCIIString());
|
||||
}
|
||||
catch (InvalidPathException x)
|
||||
{
|
||||
LOG.trace("ignored", x);
|
||||
}
|
||||
|
||||
// If we reached this here, that means the input string cannot be used as
|
||||
// a URI or a File Path. The cause is usually due to bad input (eg:
|
||||
// characters that are not supported by file system)
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Input string cannot be converted to URI \"{}\"", resource);
|
||||
throw new IllegalArgumentException("Cannot be converted to URI");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1929,7 +2009,7 @@ public final class URIUtil
|
|||
.map(URL::toString)
|
||||
.map(URI::create)
|
||||
.map(URIUtil::unwrapContainer)
|
||||
.map(URIUtil::correctFileURI);
|
||||
.map(URIUtil::correctURI);
|
||||
}
|
||||
|
||||
private static final Index<Integer> DEFAULT_PORT_FOR_SCHEME = new Index.Builder<Integer>()
|
||||
|
|
|
@ -171,7 +171,7 @@ public class PathResource extends Resource
|
|||
{
|
||||
String uriString = uri.toASCIIString();
|
||||
if (!uriString.endsWith("/"))
|
||||
uri = URIUtil.correctFileURI(URI.create(uriString + "/"));
|
||||
uri = URIUtil.correctURI(URI.create(uriString + "/"));
|
||||
}
|
||||
|
||||
this.path = path;
|
||||
|
|
|
@ -109,8 +109,8 @@ public abstract class Resource implements Iterable<Resource>
|
|||
return false;
|
||||
|
||||
// Ensure that if `file` scheme is used, it's using a consistent convention to allow for startsWith check
|
||||
String thisURIString = URIUtil.correctFileURI(thisURI).toASCIIString();
|
||||
String otherURIString = URIUtil.correctFileURI(otherURI).toASCIIString();
|
||||
String thisURIString = URIUtil.correctURI(thisURI).toASCIIString();
|
||||
String otherURIString = URIUtil.correctURI(otherURI).toASCIIString();
|
||||
|
||||
return otherURIString.startsWith(thisURIString) &&
|
||||
(thisURIString.length() == otherURIString.length() || otherURIString.charAt(thisURIString.length()) == '/');
|
||||
|
@ -315,7 +315,7 @@ public abstract class Resource implements Iterable<Resource>
|
|||
}
|
||||
return;
|
||||
}
|
||||
throw new UnsupportedOperationException("Directory Resources without a Path must implement copyTo");
|
||||
throw new UnsupportedOperationException("Directory Resources without a Path must implement copyTo: " + this);
|
||||
}
|
||||
|
||||
// Do we have to copy a single file?
|
||||
|
@ -326,12 +326,18 @@ public abstract class Resource implements Iterable<Resource>
|
|||
{
|
||||
// to a directory, preserve the filename
|
||||
Path destPath = destination.resolve(src.getFileName().toString());
|
||||
Files.copy(src, destPath, StandardCopyOption.COPY_ATTRIBUTES, StandardCopyOption.REPLACE_EXISTING);
|
||||
Files.copy(src, destPath,
|
||||
StandardCopyOption.ATOMIC_MOVE,
|
||||
StandardCopyOption.COPY_ATTRIBUTES,
|
||||
StandardCopyOption.REPLACE_EXISTING);
|
||||
}
|
||||
else
|
||||
{
|
||||
// to a file, use destination as-is
|
||||
Files.copy(src, destination, StandardCopyOption.COPY_ATTRIBUTES, StandardCopyOption.REPLACE_EXISTING);
|
||||
Files.copy(src, destination,
|
||||
StandardCopyOption.ATOMIC_MOVE,
|
||||
StandardCopyOption.COPY_ATTRIBUTES,
|
||||
StandardCopyOption.REPLACE_EXISTING);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -213,13 +213,13 @@ class ResourceFactoryInternals
|
|||
// otherwise resolve against the current directory
|
||||
uri = CURRENT_WORKING_DIR.toUri().resolve(uri);
|
||||
|
||||
// Correct any `file:/path` to `file:///path` mistakes
|
||||
uri = URIUtil.correctFileURI(uri);
|
||||
// Correct any mistakes like `file:/path` (to `file:///path`)
|
||||
uri = URIUtil.correctURI(uri);
|
||||
}
|
||||
|
||||
ResourceFactory resourceFactory = RESOURCE_FACTORIES.get(uri.getScheme());
|
||||
if (resourceFactory == null)
|
||||
throw new IllegalArgumentException("URI scheme not supported: " + uri);
|
||||
throw new IllegalArgumentException("URI scheme not registered: " + uri.getScheme());
|
||||
if (resourceFactory instanceof MountedPathResourceFactory)
|
||||
{
|
||||
FileSystemPool.Mount mount = mountIfNeeded(uri);
|
||||
|
@ -233,7 +233,9 @@ class ResourceFactoryInternals
|
|||
}
|
||||
catch (URISyntaxException | ProviderNotFoundException ex)
|
||||
{
|
||||
throw new IllegalArgumentException("Unable to create resource from: " + uri, ex);
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Unable to create resource from: {}", uri, ex);
|
||||
throw new IllegalArgumentException("Unable to create resource", ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -176,7 +176,7 @@ public class URLResourceFactory implements ResourceFactory
|
|||
@Override
|
||||
public URI getURI()
|
||||
{
|
||||
return URIUtil.correctFileURI(uri);
|
||||
return URIUtil.correctURI(uri);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -57,7 +57,6 @@ import static org.junit.jupiter.api.Assumptions.assumeTrue;
|
|||
@ExtendWith(WorkDirExtension.class)
|
||||
public class URIUtilTest
|
||||
{
|
||||
|
||||
public WorkDir workDir;
|
||||
|
||||
public static Stream<Arguments> encodePathSource()
|
||||
|
@ -668,10 +667,10 @@ public class URIUtilTest
|
|||
|
||||
@ParameterizedTest
|
||||
@MethodSource("correctBadFileURICases")
|
||||
public void testCorrectFileURI(String input, String expected)
|
||||
public void testCorrectURI(String input, String expected)
|
||||
{
|
||||
URI inputUri = URI.create(input);
|
||||
URI actualUri = URIUtil.correctFileURI(inputUri);
|
||||
URI actualUri = URIUtil.correctURI(inputUri);
|
||||
URI expectedUri = URI.create(expected);
|
||||
assertThat(actualUri.toASCIIString(), is(expectedUri.toASCIIString()));
|
||||
}
|
||||
|
@ -695,8 +694,8 @@ public class URIUtilTest
|
|||
assertThat(fileUri.toASCIIString(), not(containsString("://")));
|
||||
assertThat(fileUrlUri.toASCIIString(), not(containsString("://")));
|
||||
|
||||
assertThat(URIUtil.correctFileURI(fileUri).toASCIIString(), is(expectedUri.toASCIIString()));
|
||||
assertThat(URIUtil.correctFileURI(fileUrlUri).toASCIIString(), is(expectedUri.toASCIIString()));
|
||||
assertThat(URIUtil.correctURI(fileUri).toASCIIString(), is(expectedUri.toASCIIString()));
|
||||
assertThat(URIUtil.correctURI(fileUrlUri).toASCIIString(), is(expectedUri.toASCIIString()));
|
||||
}
|
||||
|
||||
public static Stream<Arguments> encodeSpecific()
|
||||
|
@ -1063,6 +1062,49 @@ public class URIUtilTest
|
|||
assertThat(actual.toASCIIString(), is(expected));
|
||||
}
|
||||
|
||||
public static Stream<Arguments> toURICases()
|
||||
{
|
||||
List<Arguments> args = new ArrayList<>();
|
||||
|
||||
if (OS.WINDOWS.isCurrentOs())
|
||||
{
|
||||
// Windows format (absolute and relative)
|
||||
args.add(Arguments.of("C:\\path\\to\\foo.jar", "file:///C:/path/to/foo.jar"));
|
||||
args.add(Arguments.of("D:\\path\\to\\bogus.txt", "file:///D:/path/to/bogus.txt"));
|
||||
args.add(Arguments.of("\\path\\to\\foo.jar", "file:///C:/path/to/foo.jar"));
|
||||
args.add(Arguments.of("\\path\\to\\bogus.txt", "file:///C:/path/to/bogus.txt"));
|
||||
// unix format (relative)
|
||||
args.add(Arguments.of("C:/path/to/foo.jar", "file:///C:/path/to/foo.jar"));
|
||||
args.add(Arguments.of("D:/path/to/bogus.txt", "file:///D:/path/to/bogus.txt"));
|
||||
args.add(Arguments.of("/path/to/foo.jar", "file:///C:/path/to/foo.jar"));
|
||||
args.add(Arguments.of("/path/to/bogus.txt", "file:///C:/path/to/bogus.txt"));
|
||||
// URI format (absolute)
|
||||
args.add(Arguments.of("file:///D:/path/to/zed.jar", "file:///D:/path/to/zed.jar"));
|
||||
args.add(Arguments.of("file:/e:/zed/yotta.txt", "file:///e:/zed/yotta.txt"));
|
||||
args.add(Arguments.of("jar:file:///E:/path/to/bar.jar", "jar:file:///E:/path/to/bar.jar"));
|
||||
}
|
||||
else
|
||||
{
|
||||
// URI (and unix) format (relative)
|
||||
args.add(Arguments.of("/path/to/foo.jar", "file:///path/to/foo.jar"));
|
||||
args.add(Arguments.of("/path/to/bogus.txt", "file:///path/to/bogus.txt"));
|
||||
}
|
||||
// URI format (absolute)
|
||||
args.add(Arguments.of("file:///path/to/zed.jar", "file:///path/to/zed.jar"));
|
||||
args.add(Arguments.of("jar:file:///path/to/bar.jar", "jar:file:///path/to/bar.jar"));
|
||||
|
||||
return args.stream();
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("toURICases")
|
||||
public void testToURI(String inputRaw, String expectedUri)
|
||||
{
|
||||
URI actual = URIUtil.toURI(inputRaw);
|
||||
URI expected = URI.create(expectedUri);
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSplitSingleJar()
|
||||
{
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
package org.eclipse.jetty.util.resource;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.nio.file.Files;
|
||||
|
@ -335,13 +336,13 @@ public class AttributeNormalizerTest
|
|||
assertThat(normalizer.expand("${WAR.uri}/file1"), containsString("/dir1/file1"));
|
||||
assertThat(normalizer.expand("${WAR.uri}/file2"), containsString("/dir2/file2"));
|
||||
assertThat(normalizer.expand("${WAR.uri}/file3"), containsString("/dir3/file3"));
|
||||
assertThat(normalizer.expand("${WAR.path}/file1"), containsString("/dir1/file1"));
|
||||
assertThat(normalizer.expand("${WAR.path}/file2"), containsString("/dir2/file2"));
|
||||
assertThat(normalizer.expand("${WAR.path}/file3"), containsString("/dir3/file3"));
|
||||
assertThat(normalizer.expand("${WAR.path}/file1"), containsString(FS.separators("/dir1/file1")));
|
||||
assertThat(normalizer.expand("${WAR.path}/file2"), containsString(FS.separators("/dir2/file2")));
|
||||
assertThat(normalizer.expand("${WAR.path}/file3"), containsString(FS.separators("/dir3/file3")));
|
||||
|
||||
// If file cannot be found it just uses the first resource.
|
||||
assertThat(normalizer.expand("${WAR.uri}/file4"), containsString("/dir1/file4"));
|
||||
assertThat(normalizer.expand("${WAR.path}/file4"), containsString("/dir1/file4"));
|
||||
assertThat(normalizer.expand("${WAR.path}/file4"), containsString(File.separator + "dir1/file4"));
|
||||
}
|
||||
|
||||
public static class Scenario
|
||||
|
|
|
@ -110,9 +110,9 @@ public class CombinedResourceTest
|
|||
.toList();
|
||||
|
||||
expected = new String[] {
|
||||
"dir/1.txt",
|
||||
"dir/2.txt",
|
||||
"dir/3.txt"
|
||||
FS.separators("dir/1.txt"),
|
||||
FS.separators("dir/2.txt"),
|
||||
FS.separators("dir/3.txt")
|
||||
};
|
||||
|
||||
assertThat(relative, containsInAnyOrder(expected));
|
||||
|
@ -281,9 +281,9 @@ public class CombinedResourceTest
|
|||
"2.txt",
|
||||
"3.txt",
|
||||
"4.txt",
|
||||
"dir/1.txt",
|
||||
"dir/2.txt",
|
||||
"dir/3.txt"
|
||||
FS.separators("dir/1.txt"),
|
||||
FS.separators("dir/2.txt"),
|
||||
FS.separators("dir/3.txt")
|
||||
};
|
||||
|
||||
assertThat(actual, contains(expected));
|
||||
|
@ -804,9 +804,9 @@ public class CombinedResourceTest
|
|||
"2.txt",
|
||||
"3.txt",
|
||||
"dir",
|
||||
"dir/1.txt",
|
||||
"dir/2.txt",
|
||||
"dir/3.txt"
|
||||
FS.separators("dir/1.txt"),
|
||||
FS.separators("dir/2.txt"),
|
||||
FS.separators("dir/3.txt")
|
||||
));
|
||||
}
|
||||
|
||||
|
|
|
@ -172,14 +172,16 @@ public class FileSystemResourceTest
|
|||
Files.createDirectories(testdir);
|
||||
|
||||
Path pwd = Paths.get(System.getProperty("user.dir"));
|
||||
Path relativePath = pwd.relativize(testdir);
|
||||
|
||||
// Establish a relative path URI that uses uri "/" path separators (now windows "\")
|
||||
URI relativePath = pwd.toUri().relativize(testdir.toUri());
|
||||
|
||||
// Get a path relative name using unix/uri "/" (not windows "\")
|
||||
String relativeName = FS.separators(relativePath.toString());
|
||||
assertThat("Should not have path navigation entries", relativeName, not(containsString("..")));
|
||||
assertThat("Should not have path navigation entries", relativePath.toASCIIString(), not(containsString("..")));
|
||||
assertFalse(relativePath.isAbsolute());
|
||||
|
||||
resource = ResourceFactory.root().newResource(new URI(relativeName));
|
||||
assertThat("Relative newResource: " + relativeName, resource, notNullValue());
|
||||
resource = ResourceFactory.root().newResource(relativePath);
|
||||
assertThat("Relative newResource: " + relativePath, resource, notNullValue());
|
||||
assertThat(resource.getURI().toString(), startsWith("file:"));
|
||||
assertThat(resource.getURI().toString(), endsWith("/path/to/resource/"));
|
||||
}
|
||||
|
@ -1095,7 +1097,8 @@ public class FileSystemResourceTest
|
|||
|
||||
if (WINDOWS.isCurrentOs())
|
||||
{
|
||||
assertThat("getURI()", r.getPath().toString(), containsString("aa\\/foo.txt"));
|
||||
// On windows, the extra "\" is stripped when working with java.nio.Path objects
|
||||
assertThat("getURI()", r.getPath().toString(), containsString("aa\\foo.txt"));
|
||||
assertThat("getURI()", r.getURI().toASCIIString(), containsString("aa%5C/foo.txt"));
|
||||
assertThat("isAlias()", r.isAlias(), is(true));
|
||||
assertThat("getRealURI()", r.getRealURI(), notNullValue());
|
||||
|
@ -1279,7 +1282,16 @@ public class FileSystemResourceTest
|
|||
|
||||
Resource r = base.resolve("file.txt");
|
||||
assertThat("Exists: " + r, r.exists(), is(true));
|
||||
assertThat("Is Not Alias: " + r, r, isNotAlias());
|
||||
if (WINDOWS.isCurrentOs())
|
||||
{
|
||||
// On windows, the base.resolve results in a representation of ".../testUtf8Dir/b%C3%A3m/file.txt"
|
||||
// But that differs from the input URI of ".../testUtf8Dir/bãm/file.txt", so it is viewed as an alias.
|
||||
assertThat("Is Alias: " + r, r, isAlias());
|
||||
URI realURI = r.getRealURI();
|
||||
assertThat(realURI, is(file.toUri()));
|
||||
}
|
||||
else
|
||||
assertThat("Is Not Alias: " + r, r, isNotAlias());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -1287,6 +1299,7 @@ public class FileSystemResourceTest
|
|||
public void testUncPath()
|
||||
{
|
||||
Resource base = ResourceFactory.root().newResource(URI.create("file:////127.0.0.1/path"));
|
||||
assumeTrue(base != null);
|
||||
Resource resource = base.resolve("WEB-INF/");
|
||||
assertThat("getURI()", resource.getURI().toASCIIString(), containsString("path/WEB-INF/"));
|
||||
assertThat("isAlias()", resource.isAlias(), is(false));
|
||||
|
|
|
@ -38,6 +38,7 @@ import org.eclipse.jetty.util.URIUtil;
|
|||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.condition.OS;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -736,8 +737,21 @@ public class PathResourceTest
|
|||
{
|
||||
Path testDir = workDir.getEmptyPathDir();
|
||||
Path resourcePath = testDir.resolve("resource.txt");
|
||||
Path symlinkPath = null;
|
||||
IO.copy(MavenTestingUtils.getTestResourcePathFile("resource.txt").toFile(), resourcePath.toFile());
|
||||
Path symlinkPath = Files.createSymbolicLink(testDir.resolve("symlink.txt"), resourcePath);
|
||||
boolean symlinkSupported;
|
||||
try
|
||||
{
|
||||
symlinkPath = Files.createSymbolicLink(testDir.resolve("symlink.txt"), resourcePath);
|
||||
symlinkSupported = true;
|
||||
}
|
||||
catch (UnsupportedOperationException | FileSystemException e)
|
||||
{
|
||||
symlinkSupported = false;
|
||||
}
|
||||
|
||||
assumeTrue(symlinkSupported, "Symlink not supported");
|
||||
assertNotNull(symlinkPath);
|
||||
|
||||
PathResource fileResource = new PathResource(resourcePath);
|
||||
assertTrue(fileResource.exists());
|
||||
|
@ -786,7 +800,10 @@ public class PathResourceTest
|
|||
Resource rootRes = resourceFactory.newResource(docroot);
|
||||
// Test navigation through a directory that doesn't exist
|
||||
Resource fileResViaBar = rootRes.resolve("bar/../dir/test.txt");
|
||||
assertTrue(Resources.missing(fileResViaBar));
|
||||
if (OS.WINDOWS.isCurrentOs()) // windows allows navigation through a non-existent directory
|
||||
assertTrue(Resources.exists(fileResViaBar));
|
||||
else
|
||||
assertTrue(Resources.missing(fileResViaBar));
|
||||
|
||||
// Test navigation through a directory that does exist
|
||||
Resource fileResViaFoo = rootRes.resolve("foo/../dir/test.txt");
|
||||
|
|
|
@ -25,6 +25,7 @@ import org.eclipse.jetty.toolchain.test.jupiter.WorkDirExtension;
|
|||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.condition.OS;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -73,7 +74,10 @@ public class ResourceAliasTest
|
|||
Resource rootRes = resourceFactory.newResource(docroot);
|
||||
// Test navigation through a directory that doesn't exist
|
||||
Resource fileResViaBar = rootRes.resolve("bar/../dir/test.txt");
|
||||
assertTrue(Resources.missing(fileResViaBar), "File doesn't exist");
|
||||
if (OS.WINDOWS.isCurrentOs()) // windows allows navigation through a non-existent directory
|
||||
assertTrue(Resources.exists(fileResViaBar));
|
||||
else
|
||||
assertTrue(Resources.missing(fileResViaBar), "File doesn't exist");
|
||||
|
||||
// Test navigation through a directory that does exist
|
||||
Resource fileResViaFoo = rootRes.resolve("foo/../dir/test.txt");
|
||||
|
|
|
@ -135,16 +135,15 @@ public class ResourceFactoryTest
|
|||
// Try this as a normal String input first.
|
||||
// We are subject to the URIUtil.toURI(String) behaviors here.
|
||||
// Since the `ftp` scheme is not registered, it's not recognized as a supported URI.
|
||||
// This will be treated as a relative path instead. (and the '//' will be compacted)
|
||||
Resource resource = ResourceFactory.root().newResource("ftp://webtide.com/favicon.ico");
|
||||
// Should not find this, as it doesn't exist on the filesystem.
|
||||
assertNull(resource);
|
||||
IllegalArgumentException iae = assertThrows(IllegalArgumentException.class,
|
||||
() -> ResourceFactory.root().newResource("ftp://webtide.com/favicon.ico"));
|
||||
assertThat(iae.getMessage(), containsString("URI scheme not registered: ftp"));
|
||||
|
||||
// Now try it as a formal URI object as input.
|
||||
URI uri = URI.create("ftp://webtide.com/favicon.ico");
|
||||
// This is an unsupported URI scheme
|
||||
IllegalArgumentException iae = assertThrows(IllegalArgumentException.class, () -> ResourceFactory.root().newResource(uri));
|
||||
assertThat(iae.getMessage(), containsString("URI scheme not supported"));
|
||||
iae = assertThrows(IllegalArgumentException.class, () -> ResourceFactory.root().newResource(uri));
|
||||
assertThat(iae.getMessage(), containsString("URI scheme not registered: ftp"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -434,7 +434,17 @@ public class ResourceTest
|
|||
Resource resource = resourceFactory.newResource(file);
|
||||
// Requesting a resource that would point to a location called ".../testDotAliasFileExists/foo/bar.txt/."
|
||||
Resource dot = resource.resolve(".");
|
||||
assertTrue(Resources.missing(dot), "Cannot reference file as a directory");
|
||||
if (OS.WINDOWS.isCurrentOs())
|
||||
{
|
||||
// windows allows this reference, but it's an alias.
|
||||
assertTrue(Resources.exists(dot), "Reference to directory via dot allowed");
|
||||
assertTrue(dot.isAlias(), "Reference to dot is an alias to actual bar.txt");
|
||||
assertEquals(dot.getRealURI(), file.toUri());
|
||||
}
|
||||
else
|
||||
{
|
||||
assertTrue(Resources.missing(dot), "Cannot reference file as a directory");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -274,7 +274,7 @@ public class UrlResourceFactoryTest
|
|||
assertThat("resource /path/to/example.jar/WEB-INF/web.xml doesn't exist", webResource.exists(), is(false));
|
||||
assertThat(webResource.isDirectory(), is(false));
|
||||
|
||||
URI expectedURI = URIUtil.correctFileURI(URI.create("file:" + path.toUri().toASCIIString() + "/WEB-INF/web.xml"));
|
||||
URI expectedURI = URIUtil.correctURI(URI.create("file:" + path.toUri().toASCIIString() + "/WEB-INF/web.xml"));
|
||||
assertThat(webResource.getURI(), is(expectedURI));
|
||||
}
|
||||
|
||||
|
@ -296,7 +296,7 @@ public class UrlResourceFactoryTest
|
|||
assertThat("resource /path/to/example.jar/WEB-INF/web.xml doesn't exist", webResource.exists(), is(false));
|
||||
assertThat(webResource.isDirectory(), is(false));
|
||||
|
||||
URI expectedURI = URIUtil.correctFileURI(URI.create(path.toUri().toASCIIString() + "/WEB-INF/web.xml"));
|
||||
URI expectedURI = URIUtil.correctURI(URI.create(path.toUri().toASCIIString() + "/WEB-INF/web.xml"));
|
||||
assertThat(webResource.getURI(), is(expectedURI));
|
||||
}
|
||||
|
||||
|
|
|
@ -43,6 +43,8 @@ import org.eclipse.jetty.util.component.AbstractLifeCycle;
|
|||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.eclipse.jetty.util.resource.ResourceFactory;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.condition.DisabledOnOs;
|
||||
import org.junit.jupiter.api.condition.OS;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.containsInAnyOrder;
|
||||
|
@ -381,6 +383,7 @@ public class SslContextFactoryTest
|
|||
}
|
||||
|
||||
@Test
|
||||
@DisabledOnOs(value = OS.WINDOWS, disabledReason = "Will result in java.net.SocketException: An established connection was aborted by the software in your host machine during IO.readBytes(input)")
|
||||
public void testSNIWithPKIX() throws Exception
|
||||
{
|
||||
SslContextFactory.Server serverTLS = new SslContextFactory.Server()
|
||||
|
|
|
@ -562,8 +562,8 @@ public class MetaInfConfigurationTest
|
|||
// we "correct" the bad file URLs that come from the ClassLoader
|
||||
// to be the same as what comes from every non-classloader URL/URI.
|
||||
String[] expectedContainerResources = {
|
||||
URIUtil.correctFileURI(janbUri).toASCIIString(),
|
||||
URIUtil.correctFileURI(servletUri).toASCIIString()
|
||||
URIUtil.correctURI(janbUri).toASCIIString(),
|
||||
URIUtil.correctURI(servletUri).toASCIIString()
|
||||
};
|
||||
assertThat("Discovered Container resources", discoveredContainerResources, hasItems(expectedContainerResources));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue