diff --git a/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/AsyncMiddleManServletTest.java b/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/AsyncMiddleManServletTest.java index 0a0057a9f8c..a40071dd3e3 100644 --- a/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/AsyncMiddleManServletTest.java +++ b/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/AsyncMiddleManServletTest.java @@ -70,6 +70,7 @@ import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; import org.eclipse.jetty.toolchain.test.MavenTestingUtils; +import org.eclipse.jetty.toolchain.test.OS; import org.eclipse.jetty.toolchain.test.TestTracker; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.IO; @@ -1065,9 +1066,14 @@ public class AsyncMiddleManServletTest { Assert.assertFalse(paths.iterator().hasNext()); } - try (DirectoryStream paths = Files.newDirectoryStream(targetTestsDir, outputPrefix + "*.*")) + + // File deletion is delayed on windows, testing for deletion is not going to work + if(!OS.IS_WINDOWS) { - Assert.assertFalse(paths.iterator().hasNext()); + try (DirectoryStream paths = Files.newDirectoryStream(targetTestsDir, outputPrefix + "*.*")) + { + Assert.assertFalse(paths.iterator().hasNext()); + } } } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/AllowSymLinkAliasChecker.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/AllowSymLinkAliasChecker.java index 43b8bc16342..c5d5f69da4a 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/AllowSymLinkAliasChecker.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/AllowSymLinkAliasChecker.java @@ -52,7 +52,10 @@ public class AllowSymLinkAliasChecker implements AliasCheck { Path path = pathResource.getPath(); Path alias = pathResource.getAliasPath(); - + + if (path.equals(alias)) + return false; // Unknown why this is an alias + // is the file itself a symlink? if (Files.isSymbolicLink(path)) { diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/GracefulStopTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/GracefulStopTest.java index c5f2ae7990c..082314baf51 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/GracefulStopTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/GracefulStopTest.java @@ -23,6 +23,7 @@ import static org.hamcrest.Matchers.greaterThan; import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.lessThan; import static org.junit.Assert.assertThat; +import static org.junit.Assume.assumeTrue; import java.io.EOFException; import java.io.IOException; @@ -43,6 +44,7 @@ import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.io.EofException; import org.eclipse.jetty.server.handler.AbstractHandler; import org.eclipse.jetty.server.handler.StatisticsHandler; +import org.eclipse.jetty.toolchain.test.OS; import org.eclipse.jetty.util.IO; import org.hamcrest.Matchers; import org.junit.Assert; @@ -167,6 +169,7 @@ public class GracefulStopTest @Test public void testGracefulComplete() throws Exception { + assumeTrue(!OS.IS_WINDOWS); Server server= new Server(); server.setStopTimeout(10000); diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/handler/ContextHandlerGetResourceTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/handler/ContextHandlerGetResourceTest.java index 8a60de049b4..1ae3063b17d 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/handler/ContextHandlerGetResourceTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/handler/ContextHandlerGetResourceTest.java @@ -18,7 +18,7 @@ package org.eclipse.jetty.server.handler; -import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.nullValue; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; @@ -321,15 +321,15 @@ public class ContextHandlerGetResourceTest String path="//subdir/data.txt"; Resource resource=context.getResource(path); - assertThat("Resource: " + resource, resource.getFile(), is(expected)); + assertThat("Resource: " + resource, resource, nullValue()); URL url=context.getServletContext().getResource(path); - assertThat("Resource: " + url, url, is(expectedUrl)); - + assertThat("Resource: " + url, url, nullValue()); + path="/subdir//data.txt"; resource=context.getResource(path); - assertThat("Resource: " + resource, resource.getFile(), is(expected)); + assertThat("Resource: " + resource, resource, nullValue()); url=context.getServletContext().getResource(path); - assertThat("Resource: " + url, url, is(expectedUrl)); + assertThat("Resource: " + url, url, nullValue()); } @Test @@ -416,7 +416,7 @@ public class ContextHandlerGetResourceTest { allowSymlinks.set(false); } - + } @Test diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/URIUtil.java b/jetty-util/src/main/java/org/eclipse/jetty/util/URIUtil.java index 8c0340a1ffa..a6909b01008 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/URIUtil.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/URIUtil.java @@ -854,6 +854,3 @@ public class URIUtil return URI.create(buf.toString()); } } - - - diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/resource/FileResource.java b/jetty-util/src/main/java/org/eclipse/jetty/util/resource/FileResource.java index d4942eec15e..9e9f193d0aa 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/resource/FileResource.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/resource/FileResource.java @@ -47,7 +47,7 @@ import org.eclipse.jetty.util.log.Logger; * This class can check for aliasing in the filesystem (eg case * insensitivity). By default this is turned on, or it can be controlled * by calling the static method @see FileResource#setCheckAliases(boolean) - * + * * @deprecated Use {@link PathResource} */ @Deprecated @@ -57,12 +57,12 @@ public class FileResource extends Resource /* ------------------------------------------------------------ */ private final File _file; - private final String _uri; + private final URI _uri; private final URI _alias; /* -------------------------------------------------------- */ public FileResource(URL url) - throws IOException, URISyntaxException + throws IOException, URISyntaxException { File file; try @@ -71,7 +71,7 @@ public class FileResource extends Resource file =new File(url.toURI()); assertValidPath(file.toString()); } - catch (URISyntaxException e) + catch (URISyntaxException e) { throw e; } @@ -84,9 +84,9 @@ public class FileResource extends Resource try { // Assume that File.toURL produced unencoded chars. So try encoding them. - String file_url="file:"+URIUtil.encodePath(url.toString().substring(5)); + String file_url="file:"+URIUtil.encodePath(url.toString().substring(5)); URI uri = new URI(file_url); - if (uri.getAuthority()==null) + if (uri.getAuthority()==null) file = new File(uri); else file = new File("//"+uri.getAuthority()+URIUtil.decodePath(url.getFile())); @@ -103,7 +103,7 @@ public class FileResource extends Resource _file=file; _uri=normalizeURI(_file,url.toURI()); - _alias=checkFileAlias(_file); + _alias=checkFileAlias(_uri,_file); } /* -------------------------------------------------------- */ @@ -111,15 +111,27 @@ public class FileResource extends Resource { File file=new File(uri); _file=file; - URI file_uri=_file.toURI(); - _uri=normalizeURI(_file,uri); - assertValidPath(file.toString()); + try + { + URI file_uri = _file.toURI(); + _uri = normalizeURI(_file, uri); + assertValidPath(file.toString()); - // Is it a URI alias? - if (!URIUtil.equalsIgnoreEncodings(_uri,file_uri.toString())) - _alias=_file.toURI(); - else - _alias=checkFileAlias(_file); + // Is it a URI alias? + if (!URIUtil.equalsIgnoreEncodings(_uri.toASCIIString(), file_uri.toString())) + _alias = _file.toURI(); + else + _alias = checkFileAlias(_uri, _file); + } + catch (URISyntaxException e) + { + throw new InvalidPathException(_file.toString(), e.getMessage()) + { + { + initCause(e); + } + }; + } } /* -------------------------------------------------------- */ @@ -127,29 +139,81 @@ public class FileResource extends Resource { assertValidPath(file.toString()); _file=file; - _uri=normalizeURI(_file,_file.toURI()); - _alias=checkFileAlias(_file); + try + { + _uri = normalizeURI(_file, _file.toURI()); + } + catch (URISyntaxException e) + { + throw new InvalidPathException(_file.toString(), e.getMessage()) + { + { + initCause(e); + } + }; + } + _alias=checkFileAlias(_uri,_file); } /* -------------------------------------------------------- */ - private static String normalizeURI(File file, URI uri) + public FileResource(File base, String childPath) { + String encoded = URIUtil.encodePath(childPath); + + _file = new File(base, childPath); + + // The encoded path should be a suffix of the resource (give or take a directory / ) + URI uri; + try + { + if (base.isDirectory()) + { + // treat all paths being added as relative + uri=new URI(URIUtil.addPaths(base.toURI().toASCIIString(),encoded)); + } + else + { + uri=new URI(base.toURI().toASCIIString()+encoded); + } + } + catch (final URISyntaxException e) + { + throw new InvalidPathException(base.toString() + childPath, e.getMessage()) + { + { + initCause(e); + } + }; + } + + _uri=uri; + _alias=checkFileAlias(_uri,_file); + } + + /* -------------------------------------------------------- */ + private static URI normalizeURI(File file, URI uri) throws URISyntaxException { String u =uri.toASCIIString(); if (file.isDirectory()) { if(!u.endsWith("/")) u+="/"; - } + } else if (file.exists() && u.endsWith("/")) u=u.substring(0,u.length()-1); - return u; + return new URI(u); } /* -------------------------------------------------------- */ - private static URI checkFileAlias(File file) + private static URI checkFileAlias(final URI uri, final File file) { try { + if (!URIUtil.equalsIgnoreEncodings(uri,file.toURI())) + { + // Return alias pointing to Java File normalized URI + return new File(uri).getAbsoluteFile().toURI(); + } + String abs=file.getAbsolutePath(); String can=file.getCanonicalPath(); @@ -160,8 +224,7 @@ public class FileResource extends Resource URI alias=new File(can).toURI(); // Have to encode the path as File.toURI does not! - String uri="file://"+URIUtil.encodePath(alias.getPath()); - return new URI(uri); + return new URI("file://"+URIUtil.encodePath(alias.getPath())); } } catch(Exception e) @@ -185,43 +248,18 @@ public class FileResource extends Resource /* -------------------------------------------------------- */ @Override public Resource addPath(String path) - throws IOException, MalformedURLException + throws IOException, MalformedURLException { assertValidPath(path); path = org.eclipse.jetty.util.URIUtil.canonicalPath(path); if (path==null) - throw new MalformedURLException(); + throw new MalformedURLException(); if ("/".equals(path)) return this; - - path=URIUtil.encodePath(path); - // The encoded path should be a suffix of the resource (give or take a directory / ) - URI uri; - try - { - if (_file.isDirectory()) - { - // treat all paths being added as relative - uri=new URI(URIUtil.addPaths(_uri,path)); - } - else - { - uri=new URI(_uri+path); - } - } - catch (final URISyntaxException e) - { - throw new InvalidPathException(path, e.getMessage()) - { - { - initCause(e); - } - }; - } - return new FileResource(uri); + return new FileResource(_file, path); } private void assertValidPath(String path) @@ -267,7 +305,7 @@ public class FileResource extends Resource @Override public boolean isDirectory() { - return _file.exists() && _file.isDirectory() || _uri.endsWith("/"); + return _file.exists() && _file.isDirectory() || _uri.toASCIIString().endsWith("/"); } /* --------------------------------------------------------- */ @@ -325,7 +363,7 @@ public class FileResource extends Resource */ @Override public boolean delete() - throws SecurityException + throws SecurityException { return _file.delete(); } @@ -336,7 +374,7 @@ public class FileResource extends Resource */ @Override public boolean renameTo( Resource dest) - throws SecurityException + throws SecurityException { if( dest instanceof FileResource) return _file.renameTo( ((FileResource)dest)._file); @@ -357,14 +395,14 @@ public class FileResource extends Resource for (int i=list.length;i-->0;) { if (new File(_file,list[i]).isDirectory() && - !list[i].endsWith("/")) + !list[i].endsWith("/")) list[i]+="/"; } return list; } /* ------------------------------------------------------------ */ - /** + /** * @param o the object to compare against this instance * @return true of the object o is a {@link FileResource} pointing to the same file as this resource. */ @@ -388,13 +426,13 @@ public class FileResource extends Resource @Override public int hashCode() { - return null == _file ? super.hashCode() : _file.hashCode(); + return null == _file ? super.hashCode() : _file.hashCode(); } /* ------------------------------------------------------------ */ @Override public void copyTo(File destination) - throws IOException + throws IOException { if (isDirectory()) { @@ -424,7 +462,7 @@ public class FileResource extends Resource { try { - return new URL(_uri); + return _uri.toURL(); } catch (MalformedURLException e) { @@ -435,13 +473,12 @@ public class FileResource extends Resource @Override public URI getURI() { - return _file.toURI(); + return _uri; } @Override public String toString() { - return _uri; + return _uri.toString(); } - -} +} \ No newline at end of file diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/resource/PathResource.java b/jetty-util/src/main/java/org/eclipse/jetty/util/resource/PathResource.java index 892e34140c7..f24c22ea13e 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/resource/PathResource.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/resource/PathResource.java @@ -57,9 +57,24 @@ public class PathResource extends Resource private final Path alias; private final URI uri; - private static final Path checkAliasPath(final Path path) + private final Path checkAliasPath() { Path abs = path; + + /* Catch situation where the Path class has already normalized + * the URI eg. input path "aa./foo.txt" + * from an #addPath(String) is normalized away during + * the creation of a Path object reference. + * If the URI is different then the Path.toUri() then + * we will just use the original URI to construct the + * alias reference Path. + */ + + if(!URIUtil.equalsIgnoreEncodings(uri,path.toUri())) + { + return new File(uri).toPath().toAbsolutePath(); + } + if (!abs.isAbsolute()) { abs = path.toAbsolutePath(); @@ -160,7 +175,7 @@ public class PathResource extends Resource /** * Construct a new PathResource from a Path object. - * + * * @param path the path to use */ public PathResource(Path path) @@ -168,14 +183,34 @@ public class PathResource extends Resource this.path = path.toAbsolutePath(); assertValidPath(path); this.uri = this.path.toUri(); - this.alias = checkAliasPath(path); + this.alias = checkAliasPath(); + } + + /** + * Construct a new PathResource from a parent PathResource + * and child sub path + * + * @param parent the parent path resource + * @param childPath the child sub path + */ + private PathResource(PathResource parent, String childPath) throws MalformedURLException + { + // Calculate the URI and the path separately, so that any aliasing done by + // FileSystem.getPath(path,childPath) is visiable as a difference to the URI + // obtained via URIUtil.addDecodedPath(uri,childPath) + + this.path = parent.path.getFileSystem().getPath(parent.path.toString(), childPath); + if (isDirectory() &&!childPath.endsWith("/")) + childPath+="/"; + this.uri = URIUtil.addDecodedPath(parent.uri,childPath); + this.alias = checkAliasPath(); } /** * Construct a new PathResource from a URI object. *

* Must be an absolute URI using the file scheme. - * + * * @param uri the URI to build this PathResource from. * @throws IOException if unable to construct the PathResource from the URI. */ @@ -212,7 +247,7 @@ public class PathResource extends Resource this.path = path.toAbsolutePath(); this.uri = path.toUri(); - this.alias = checkAliasPath(path); + this.alias = checkAliasPath(); } /** @@ -229,7 +264,7 @@ public class PathResource extends Resource *

      * new PathResource(url.toURI());
      * 
- * + * * @param url the url to attempt to create PathResource from * @throws IOException if URL doesn't point to a location that can be transformed to a PathResource * @throws URISyntaxException if the provided URL was malformed @@ -245,7 +280,7 @@ public class PathResource extends Resource String cpath = URIUtil.canonicalPath(subpath); if ((cpath == null) || (cpath.length() == 0)) - throw new MalformedURLException(); + throw new MalformedURLException(subpath); if ("/".equals(cpath)) return this; @@ -254,7 +289,8 @@ public class PathResource extends Resource // compensate for input subpaths like "/subdir" // where default resolve behavior would be // to treat that like an absolute path - return new PathResource(this.path.getFileSystem().getPath(path.toString(), subpath)); + + return new PathResource(this, subpath); } private void assertValidPath(Path path) @@ -267,7 +303,7 @@ public class PathResource extends Resource throw new InvalidPathException(str, "Invalid Character at index " + idx); } } - + @Override public void close() { @@ -431,17 +467,21 @@ public class PathResource extends Resource { return this.alias!=null; } - + /** * The Alias as a Path. - * + *

+ * Note: this cannot return the alias as a DIFFERENT path in 100% of situations, + * due to Java's internal Path/File normalization. + *

+ * * @return the alias as a path. */ public Path getAliasPath() { return this.alias; } - + @Override public URI getAlias() { @@ -520,4 +560,4 @@ public class PathResource extends Resource { return this.uri.toASCIIString(); } -} +} \ No newline at end of file diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/resource/FileSystemResourceTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/resource/FileSystemResourceTest.java index 392524c9628..caa5c66da6f 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/resource/FileSystemResourceTest.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/resource/FileSystemResourceTest.java @@ -18,9 +18,17 @@ package org.eclipse.jetty.util.resource; -import static org.hamcrest.Matchers.*; -import static org.junit.Assert.*; -import static org.junit.Assume.*; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.lessThanOrEqualTo; +import static org.hamcrest.Matchers.notNullValue; +import static org.hamcrest.Matchers.nullValue; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertThat; +import static org.junit.Assume.assumeFalse; +import static org.junit.Assume.assumeNoException; +import static org.junit.Assume.assumeThat; import java.io.BufferedWriter; import java.io.File; @@ -54,7 +62,6 @@ import org.eclipse.jetty.util.BufferUtil; import org.hamcrest.BaseMatcher; import org.hamcrest.Description; import org.hamcrest.Matcher; -import org.hamcrest.Matchers; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @@ -71,7 +78,7 @@ public class FileSystemResourceTest @SuppressWarnings("deprecation") @Parameters(name="{0}") - public static Collection data() + public static Collection data() { List data = new ArrayList<>(); data.add(new Class[]{FileResource.class}); @@ -111,7 +118,7 @@ public class FileSystemResourceTest { try { - return _class.getConstructor(File.class).newInstance(file); + return _class.getConstructor(File.class).newInstance(file); } catch(InvocationTargetException e) { @@ -216,7 +223,7 @@ public class FileSystemResourceTest else { assumeFalse("Unknown OS type",false); - } + } } @Test @@ -274,12 +281,15 @@ public class FileSystemResourceTest { for (Path entry : dir) { - if (Files.isDirectory(entry) && !Files.isHidden(entry)) + if (Files.isDirectory(entry) && !Files.isHidden(entry) && !entry.getFileName().toString().contains("$")) { return entry.toAbsolutePath().toString(); } } } + catch(Exception e) + { + } } return null; @@ -653,7 +663,7 @@ public class FileSystemResourceTest { // Reference to actual resource that exists Resource resource = base.addPath("file"); - + assertThat("resource.alias", resource, hasNoAlias()); assertThat("resource.uri.alias", newResource(resource.getURI()), hasNoAlias()); assertThat("resource.file.alias", newResource(resource.getFile()), hasNoAlias()); @@ -691,7 +701,7 @@ public class FileSystemResourceTest { // Long filename Resource resource = base.addPath("TextFile.Long.txt"); - + assertThat("resource.alias", resource, hasNoAlias()); assertThat("resource.uri.alias", newResource(resource.getURI()), hasNoAlias()); assertThat("resource.file.alias", newResource(resource.getFile()), hasNoAlias()); @@ -727,7 +737,7 @@ public class FileSystemResourceTest try (Resource base = newResource(dir.toFile())) { Resource resource = base.addPath("testfile"); - + assertThat("resource.alias", resource, hasNoAlias()); assertThat("resource.uri.alias", newResource(resource.getURI()), hasNoAlias()); assertThat("resource.file.alias", newResource(resource.getFile()), hasNoAlias()); @@ -770,7 +780,7 @@ public class FileSystemResourceTest try (Resource base = newResource(dir.toFile())) { Resource resource = base.addPath("testfile"); - + assertThat("resource.alias", resource, hasNoAlias()); assertThat("resource.uri.alias", newResource(resource.getURI()), hasNoAlias()); assertThat("resource.file.alias", newResource(resource.getFile()), hasNoAlias()); @@ -815,7 +825,7 @@ public class FileSystemResourceTest try (Resource base = newResource(dir.toFile())) { Resource resource = base.addPath("testfile"); - + assertThat("resource.alias", resource, hasNoAlias()); assertThat("resource.uri.alias", newResource(resource.getURI()), hasNoAlias()); assertThat("resource.file.alias", newResource(resource.getFile()), hasNoAlias()); @@ -1169,7 +1179,180 @@ public class FileSystemResourceTest // Exception is acceptable } } - + + @Test + public void testAddPath_WindowsSlash() throws Exception + { + Path dir = testdir.getPath().normalize().toRealPath(); + Files.createDirectories(dir); + + Path basePath = dir.resolve("base"); + FS.ensureDirExists(basePath); + Path dirPath = basePath.resolve("aa"); + FS.ensureDirExists(dirPath); + Path filePath = dirPath.resolve("foo.txt"); + Files.createFile(filePath); + + try (Resource base = newResource(basePath.toFile())) + { + assertThat("Exists: " + basePath,base.exists(),is(true)); + assertThat("Alias: " + basePath,base,hasNoAlias()); + + Resource r = base.addPath("aa\\/foo.txt"); + assertThat("getURI()", r.getURI().toASCIIString(), containsString("aa%5C/foo.txt")); + + if(OS.IS_WINDOWS) + { + assertThat("isAlias()", r.isAlias(), is(true)); + assertThat("getAlias()", r.getAlias(), notNullValue()); + assertThat("getAlias()", r.getAlias().toASCIIString(), containsString("aa/foo.txt")); + assertThat("Exists: " + r, r.exists(), is(true)); + } + else + { + assertThat("isAlias()", r.isAlias(), is(false)); + assertThat("Exists: " + r, r.exists(), is(false)); + } + } + catch (InvalidPathException e) + { + // Exception is acceptable + } + } + + @Test + public void testAddPath_WindowsExtensionLess() throws Exception + { + Path dir = testdir.getPath().normalize().toRealPath(); + Files.createDirectories(dir); + + Path basePath = dir.resolve("base"); + FS.ensureDirExists(basePath); + Path dirPath = basePath.resolve("aa"); + FS.ensureDirExists(dirPath); + Path filePath = dirPath.resolve("foo.txt"); + Files.createFile(filePath); + + try (Resource base = newResource(basePath.toFile())) + { + assertThat("Exists: " + basePath,base.exists(),is(true)); + assertThat("Alias: " + basePath,base,hasNoAlias()); + + Resource r = base.addPath("aa./foo.txt"); + assertThat("getURI()", r.getURI().toASCIIString(), containsString("aa./foo.txt")); + + if(OS.IS_WINDOWS) + { + assertThat("isAlias()", r.isAlias(), is(true)); + assertThat("getAlias()", r.getAlias(), notNullValue()); + assertThat("getAlias()", r.getAlias().toASCIIString(), containsString("aa/foo.txt")); + assertThat("Exists: " + r, r.exists(), is(true)); + } + else + { + assertThat("isAlias()", r.isAlias(), is(false)); + assertThat("Exists: " + r, r.exists(), is(false)); + } + } + catch (InvalidPathException e) + { + // Exception is acceptable + } + } + + + @Test + public void testAddInitialSlash() throws Exception + { + Path dir = testdir.getPath().normalize().toRealPath(); + Files.createDirectories(dir); + + Path basePath = dir.resolve("base"); + FS.ensureDirExists(basePath); + Path filePath = basePath.resolve("foo.txt"); + Files.createFile(filePath); + + try (Resource base = newResource(basePath.toFile())) + { + assertThat("Exists: " + basePath,base.exists(),is(true)); + assertThat("Alias: " + basePath,base,hasNoAlias()); + + Resource r = base.addPath("/foo.txt"); + assertThat("getURI()", r.getURI().toASCIIString(), containsString("/foo.txt")); + + assertThat("isAlias()", r.isAlias(), is(false)); + assertThat("Exists: " + r, r.exists(), is(true)); + } + catch (InvalidPathException e) + { + // Exception is acceptable + } + } + + @Test + public void testAddInitialDoubleSlash() throws Exception + { + Path dir = testdir.getPath().normalize().toRealPath(); + Files.createDirectories(dir); + + Path basePath = dir.resolve("base"); + FS.ensureDirExists(basePath); + Path filePath = basePath.resolve("foo.txt"); + Files.createFile(filePath); + + try (Resource base = newResource(basePath.toFile())) + { + assertThat("Exists: " + basePath,base.exists(),is(true)); + assertThat("Alias: " + basePath,base,hasNoAlias()); + + Resource r = base.addPath("//foo.txt"); + assertThat("getURI()", r.getURI().toASCIIString(), containsString("//foo.txt")); + + assertThat("isAlias()", r.isAlias(), is(true)); + assertThat("getAlias()", r.getAlias(), notNullValue()); + assertThat("getAlias()", r.getAlias().toASCIIString(), containsString("/foo.txt")); + assertThat("Exists: " + r, r.exists(), is(true)); + + } + catch (InvalidPathException e) + { + // Exception is acceptable + } + } + @Test + public void testAddDoubleSlash() throws Exception + { + Path dir = testdir.getPath().normalize().toRealPath(); + Files.createDirectories(dir); + + Path basePath = dir.resolve("base"); + FS.ensureDirExists(basePath); + Path dirPath = basePath.resolve("aa"); + FS.ensureDirExists(dirPath); + Path filePath = dirPath.resolve("foo.txt"); + Files.createFile(filePath); + + try (Resource base = newResource(basePath.toFile())) + { + assertThat("Exists: " + basePath,base.exists(),is(true)); + assertThat("Alias: " + basePath,base,hasNoAlias()); + + Resource r = base.addPath("aa//foo.txt"); + assertThat("getURI()", r.getURI().toASCIIString(), containsString("aa//foo.txt")); + + assertThat("isAlias()", r.isAlias(), is(true)); + assertThat("getAlias()", r.getAlias(), notNullValue()); + assertThat("getAlias()", r.getAlias().toASCIIString(), containsString("aa/foo.txt")); + assertThat("Exists: " + r, r.exists(), is(true)); + + } + catch (InvalidPathException e) + { + // Exception is acceptable + } + } + + @Test public void testEncoding() throws Exception { @@ -1211,4 +1394,4 @@ public class FileSystemResourceTest } -} +} \ No newline at end of file