blob: b0de5789d0404acde6b47f49dc13feb2b9ccd0fe [file] [log] [blame]
//
// ========================================================================
// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.util.resource;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import static org.junit.Assume.*;
import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.io.StringWriter;
import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.nio.ByteBuffer;
import java.nio.channels.ReadableByteChannel;
import java.nio.file.DirectoryStream;
import java.nio.file.FileSystem;
import java.nio.file.FileSystemException;
import java.nio.file.Files;
import java.nio.file.InvalidPathException;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import org.eclipse.jetty.toolchain.test.FS;
import org.eclipse.jetty.toolchain.test.IO;
import org.eclipse.jetty.toolchain.test.OS;
import org.eclipse.jetty.toolchain.test.TestingDir;
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;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
@RunWith(Parameterized.class)
public class FileSystemResourceTest
{
@Rule
public TestingDir testdir = new TestingDir();
private final Class<? extends Resource> _class;
@SuppressWarnings("deprecation")
@Parameters(name="{0}")
public static Collection<Object[]> data()
{
List<Object[]> data = new ArrayList<>();
data.add(new Class<?>[]{FileResource.class});
data.add(new Class<?>[]{PathResource.class});
return data;
}
public FileSystemResourceTest(Class<? extends Resource> test)
{
_class=test;
}
public Resource newResource(URI uri) throws Exception
{
try
{
return _class.getConstructor(URI.class).newInstance(uri);
}
catch(InvocationTargetException e)
{
try
{
throw e.getTargetException();
}
catch(Exception|Error ex)
{
throw ex;
}
catch(Throwable th)
{
throw new Error(th);
}
}
}
public Resource newResource(File file) throws Exception
{
try
{
return _class.getConstructor(File.class).newInstance(file);
}
catch(InvocationTargetException e)
{
try
{
throw e.getTargetException();
}
catch(Exception|Error ex)
{
throw ex;
}
catch(Throwable th)
{
throw new Error(th);
}
}
}
private Matcher<Resource> hasNoAlias()
{
return new BaseMatcher<Resource>()
{
@Override
public boolean matches(Object item)
{
final Resource res = (Resource)item;
return !res.isAlias();
}
@Override
public void describeTo(Description description)
{
description.appendText("getAlias should return null");
}
@Override
public void describeMismatch(Object item, Description description)
{
description.appendText("was ").appendValue(((Resource)item).getAlias());
}
};
}
private Matcher<Resource> isAliasFor(final Resource resource)
{
return new BaseMatcher<Resource>()
{
@Override
public boolean matches(Object item)
{
final Resource ritem = (Resource)item;
final URI alias = ritem.getAlias();
if (alias == null)
{
return ritem == null;
}
else
{
return alias.equals(resource.getURI());
}
}
@Override
public void describeTo(Description description)
{
description.appendText("getAlias should return ").appendValue(resource.getURI());
}
@Override
public void describeMismatch(Object item, Description description)
{
description.appendText("was ").appendValue(((Resource)item).getAlias());
}
};
}
@Test(expected = IllegalArgumentException.class)
public void testNonAbsoluteURI() throws Exception
{
newResource(new URI("path/to/resource"));
}
@Test(expected = IllegalArgumentException.class)
public void testNotFileURI() throws Exception
{
newResource(new URI("http://www.eclipse.org/jetty/"));
}
@Test(expected = IllegalArgumentException.class)
public void testBogusFilename() throws Exception
{
if (OS.IS_UNIX)
{
// A windows path is invalid under unix
newResource(new URI("file://Z:/:"));
}
else if (OS.IS_WINDOWS)
{
// "CON" is a reserved name under windows
newResource(new URI("file://CON"));
}
else
{
assumeFalse("Unknown OS type",false);
}
}
@Test
public void testAddPath() throws Exception
{
Path dir = testdir.getDir().toPath().normalize().toRealPath();
Path subdir = dir.resolve("sub");
FS.ensureDirExists(subdir.toFile());
try (Resource base = newResource(dir.toFile()))
{
Resource sub = base.addPath("sub");
assertThat("sub/.isDirectory",sub.isDirectory(),is(true));
Resource tmp = sub.addPath("/tmp");
assertThat("No root",tmp.exists(),is(false));
}
}
@Test
public void testAddRootPath() throws Exception
{
Path dir = testdir.getDir().toPath().normalize().toRealPath();
Path subdir = dir.resolve("sub");
Files.createDirectories(subdir);
String readableRootDir = findRootDir(dir.getFileSystem());
assumeThat("Readable Root Dir found",readableRootDir,notNullValue());
try (Resource base = newResource(dir.toFile()))
{
Resource sub = base.addPath("sub");
assertThat("sub",sub.isDirectory(),is(true));
try
{
Resource rrd = sub.addPath(readableRootDir);
// valid path for unix and OSX
assertThat("Readable Root Dir",rrd.exists(),is(false));
}
catch (MalformedURLException | InvalidPathException e)
{
// valid path on Windows
}
}
}
private String findRootDir(FileSystem fs) throws IOException
{
// look for a directory off of a root path
for (Path rootDir : fs.getRootDirectories())
{
try (DirectoryStream<Path> dir = Files.newDirectoryStream(rootDir))
{
for (Path entry : dir)
{
if (Files.isDirectory(entry) && !Files.isHidden(entry))
{
return entry.toAbsolutePath().toString();
}
}
}
}
return null;
}
@Test
public void testIsContainedIn() throws Exception
{
Path dir = testdir.getDir().toPath().normalize().toRealPath();
Files.createDirectories(dir);
Path foo = dir.resolve("foo");
Files.createFile(foo);
try (Resource base = newResource(dir.toFile()))
{
Resource res = base.addPath("foo");
assertThat("is contained in",res.isContainedIn(base),is(false));
}
}
@Test
public void testIsDirectory() throws Exception
{
Path dir = testdir.getDir().toPath().normalize().toRealPath();
Files.createDirectories(dir);
Path foo = dir.resolve("foo");
Files.createFile(foo);
Path subdir = dir.resolve("sub");
Files.createDirectories(subdir);
try (Resource base = newResource(dir.toFile()))
{
Resource res = base.addPath("foo");
assertThat("foo.isDirectory",res.isDirectory(),is(false));
Resource sub = base.addPath("sub");
assertThat("sub/.isDirectory",sub.isDirectory(),is(true));
}
}
@Test
public void testLastModified() throws Exception
{
Path dir = testdir.getDir().toPath().normalize().toRealPath();
File file = testdir.getFile("foo");
file.createNewFile();
long expected = file.lastModified();
try (Resource base = newResource(dir.toFile()))
{
Resource res = base.addPath("foo");
assertThat("foo.lastModified",res.lastModified()/1000*1000, lessThanOrEqualTo(expected));
}
}
@Test
public void testLastModified_NotExists() throws Exception
{
Path dir = testdir.getDir().toPath().normalize().toRealPath();
try (Resource base = newResource(dir.toFile()))
{
Resource res = base.addPath("foo");
assertThat("foo.lastModified",res.lastModified(),is(0L));
}
}
@Test
public void testLength() throws Exception
{
Path dir = testdir.getDir().toPath().normalize().toRealPath();
Files.createDirectories(dir);
Path file = dir.resolve("foo");
try (StringReader reader = new StringReader("foo");
BufferedWriter writer = Files.newBufferedWriter(file))
{
IO.copy(reader,writer);
}
long expected = Files.size(file);
try (Resource base = newResource(dir.toFile()))
{
Resource res = base.addPath("foo");
assertThat("foo.length",res.length(),is(expected));
}
}
@Test
public void testLength_NotExists() throws Exception
{
Path dir = testdir.getDir().toPath().normalize().toRealPath();
Files.createDirectories(dir);
try (Resource base = newResource(dir.toFile()))
{
Resource res = base.addPath("foo");
assertThat("foo.length",res.length(),is(0L));
}
}
@Test
public void testDelete() throws Exception
{
Path dir = testdir.getDir().toPath().normalize().toRealPath();
Files.createDirectories(dir);
Path file = dir.resolve("foo");
Files.createFile(file);
try (Resource base = newResource(dir.toFile()))
{
// Is it there?
Resource res = base.addPath("foo");
assertThat("foo.exists",res.exists(),is(true));
// delete it
assertThat("foo.delete",res.delete(),is(true));
// is it there?
assertThat("foo.exists",res.exists(),is(false));
}
}
@Test
public void testDelete_NotExists() throws Exception
{
Path dir = testdir.getDir().toPath().normalize().toRealPath();
Files.createDirectories(dir);
try (Resource base = newResource(dir.toFile()))
{
// Is it there?
Resource res = base.addPath("foo");
assertThat("foo.exists",res.exists(),is(false));
// delete it
assertThat("foo.delete",res.delete(),is(false));
// is it there?
assertThat("foo.exists",res.exists(),is(false));
}
}
@Test
public void testName() throws Exception
{
Path dir = testdir.getDir().toPath().normalize().toRealPath();
Files.createDirectories(dir);
String expected = dir.toAbsolutePath().toString();
try (Resource base = newResource(dir.toFile()))
{
assertThat("base.name",base.getName(),is(expected));
}
}
@Test
public void testInputStream() throws Exception
{
Path dir = testdir.getDir().toPath().normalize().toRealPath();
Files.createDirectories(dir);
Path file = dir.resolve("foo");
String content = "Foo is here";
try (StringReader reader = new StringReader(content);
BufferedWriter writer = Files.newBufferedWriter(file))
{
IO.copy(reader,writer);
}
try (Resource base = newResource(dir.toFile()))
{
Resource foo = base.addPath("foo");
try (InputStream stream = foo.getInputStream(); InputStreamReader reader = new InputStreamReader(stream); StringWriter writer = new StringWriter())
{
IO.copy(reader,writer);
assertThat("Stream",writer.toString(),is(content));
}
}
}
@Test
public void testReadableByteChannel() throws Exception
{
Path dir = testdir.getDir().toPath().normalize().toRealPath();
Files.createDirectories(dir);
Path file = dir.resolve("foo");
String content = "Foo is here";
try (StringReader reader = new StringReader(content);
BufferedWriter writer = Files.newBufferedWriter(file))
{
IO.copy(reader,writer);
}
try (Resource base = newResource(dir.toFile()))
{
Resource foo = base.addPath("foo");
try (ReadableByteChannel channel = foo.getReadableByteChannel())
{
ByteBuffer buf = ByteBuffer.allocate(256);
channel.read(buf);
buf.flip();
String actual = BufferUtil.toUTF8String(buf);
assertThat("ReadableByteChannel content",actual,is(content));
}
}
}
@Test
public void testGetURI() throws Exception
{
Path dir = testdir.getDir().toPath().normalize().toRealPath();
Files.createDirectories(dir);
Path file = dir.resolve("foo");
Files.createFile(file);
URI expected = file.toUri();
try (Resource base = newResource(dir.toFile()))
{
Resource foo = base.addPath("foo");
assertThat("getURI",foo.getURI(),is(expected));
}
}
@SuppressWarnings("deprecation")
@Test
public void testGetURL() throws Exception
{
Path dir = testdir.getDir().toPath().normalize().toRealPath();
Files.createDirectories(dir);
Path file = dir.resolve("foo");
Files.createFile(file);
URL expected = file.toUri().toURL();
try (Resource base = newResource(dir.toFile()))
{
Resource foo = base.addPath("foo");
assertThat("getURL",foo.getURL(),is(expected));
}
}
@Test
public void testList() throws Exception
{
Path dir = testdir.getDir().toPath().normalize().toRealPath();
Files.createDirectories(dir);
Files.createFile(dir.resolve("foo"));
Files.createFile(dir.resolve("bar"));
Files.createDirectories(dir.resolve("tick"));
Files.createDirectories(dir.resolve("tock"));
List<String> expected = new ArrayList<>();
expected.add("foo");
expected.add("bar");
expected.add("tick/");
expected.add("tock/");
try (Resource base = newResource(dir.toFile()))
{
String list[] = base.list();
List<String> actual = Arrays.asList(list);
assertEquals(expected.size(),actual.size());
for (String s : expected)
assertEquals(true,actual.contains(s));
}
}
@Test
public void testSymlink() throws Exception
{
Path dir = testdir.getDir().toPath().normalize().toRealPath();
Path foo = dir.resolve("foo");
Path bar = dir.resolve("bar");
try
{
Files.createFile(foo);
Files.createSymbolicLink(bar,foo);
}
catch (UnsupportedOperationException | FileSystemException e)
{
// if unable to create symlink, no point testing the rest
// this is the path that Microsoft Windows takes.
assumeNoException(e);
}
try (Resource base = newResource(dir.toFile()))
{
Resource resFoo = base.addPath("foo");
Resource resBar = base.addPath("bar");
assertThat("resFoo.uri", resFoo.getURI(), is(foo.toUri()));
// Access to the same resource, but via a symlink means that they are not equivalent
assertThat("foo.equals(bar)", resFoo.equals(resBar), is(false));
assertThat("resource.alias", resFoo, hasNoAlias());
assertThat("resource.uri.alias", newResource(resFoo.getURI()), hasNoAlias());
assertThat("resource.file.alias", newResource(resFoo.getFile()), hasNoAlias());
assertThat("alias", resBar, isAliasFor(resFoo));
assertThat("uri.alias", newResource(resBar.getURI()), isAliasFor(resFoo));
assertThat("file.alias", newResource(resBar.getFile()), isAliasFor(resFoo));
}
}
@Test
public void testNonExistantSymlink() throws Exception
{
Path dir = testdir.getDir().toPath().normalize().toRealPath();
Files.createDirectories(dir);
Path foo = dir.resolve("foo");
Path bar = dir.resolve("bar");
try
{
Files.createSymbolicLink(bar,foo);
}
catch (UnsupportedOperationException | FileSystemException e)
{
// if unable to create symlink, no point testing the rest
// this is the path that Microsoft Windows takes.
assumeNoException(e);
}
try (Resource base = newResource(dir.toFile()))
{
// FileResource does not pass this test!
assumeFalse(base instanceof FileResource);
Resource resFoo = base.addPath("foo");
Resource resBar = base.addPath("bar");
assertThat("resFoo.uri", resFoo.getURI(), is(foo.toUri()));
// Access to the same resource, but via a symlink means that they are not equivalent
assertThat("foo.equals(bar)", resFoo.equals(resBar), is(false));
assertThat("resource.alias", resFoo, hasNoAlias());
assertThat("resource.uri.alias", newResource(resFoo.getURI()), hasNoAlias());
assertThat("resource.file.alias", newResource(resFoo.getFile()), hasNoAlias());
assertThat("alias", resBar, isAliasFor(resFoo));
assertThat("uri.alias", newResource(resBar.getURI()), isAliasFor(resFoo));
assertThat("file.alias", newResource(resBar.getFile()), isAliasFor(resFoo));
}
}
@Test
public void testCaseInsensitiveAlias() throws Exception
{
Path dir = testdir.getDir().toPath().normalize().toRealPath();
Files.createDirectories(dir);
Path path = dir.resolve("file");
Files.createFile(path);
try (Resource base = newResource(dir.toFile()))
{
// 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());
// On some case insensitive file systems, lets see if an alternate
// case for the filename results in an alias reference
Resource alias = base.addPath("FILE");
if (alias.exists())
{
// If it exists, it must be an alias
assertThat("alias", alias, isAliasFor(resource));
assertThat("alias.uri", newResource(alias.getURI()), isAliasFor(resource));
assertThat("alias.file", newResource(alias.getFile()), isAliasFor(resource));
}
}
}
/**
* Test for Windows feature that exposes 8.3 filename references
* for long filenames.
* <p>
* See: http://support.microsoft.com/kb/142982
* @throws Exception failed test
*/
@Test
public void testCase8dot3Alias() throws Exception
{
Path dir = testdir.getDir().toPath().normalize().toRealPath();
Files.createDirectories(dir);
Path path = dir.resolve("TextFile.Long.txt");
Files.createFile(path);
try (Resource base = newResource(dir.toFile()))
{
// 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());
// On some versions of Windows, the long filename can be referenced
// via a short 8.3 equivalent filename.
Resource alias = base.addPath("TEXTFI~1.TXT");
if (alias.exists())
{
// If it exists, it must be an alias
assertThat("alias", alias, isAliasFor(resource));
assertThat("alias.uri", newResource(alias.getURI()), isAliasFor(resource));
assertThat("alias.file", newResource(alias.getFile()), isAliasFor(resource));
}
}
}
/**
* NTFS Alternative Data / File Streams.
* <p>
* See: http://msdn.microsoft.com/en-us/library/windows/desktop/aa364404(v=vs.85).aspx
* @throws Exception failed test
*/
@Test
public void testNTFSFileStreamAlias() throws Exception
{
Path dir = testdir.getDir().toPath().normalize().toRealPath();
Files.createDirectories(dir);
Path path = dir.resolve("testfile");
Files.createFile(path);
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());
try
{
// Attempt to reference same file, but via NTFS simple stream
Resource alias = base.addPath("testfile:stream");
if (alias.exists())
{
// If it exists, it must be an alias
assertThat("resource.alias",alias,isAliasFor(resource));
assertThat("resource.uri.alias",newResource(alias.getURI()),isAliasFor(resource));
assertThat("resource.file.alias",newResource(alias.getFile()),isAliasFor(resource));
}
}
catch (InvalidPathException e)
{
// NTFS filesystem streams are unsupported on some platforms.
assumeNoException(e);
}
}
}
/**
* NTFS Alternative Data / File Streams.
* <p>
* See: http://msdn.microsoft.com/en-us/library/windows/desktop/aa364404(v=vs.85).aspx
* @throws Exception failed test
*/
@Test
public void testNTFSFileDataStreamAlias() throws Exception
{
Path dir = testdir.getDir().toPath().normalize().toRealPath();
Files.createDirectories(dir);
Path path = dir.resolve("testfile");
Files.createFile(path);
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());
try
{
// Attempt to reference same file, but via NTFS DATA stream
Resource alias = base.addPath("testfile::$DATA");
if (alias.exists())
{
assumeThat(alias.getURI().getScheme(), is("http"));
// If it exists, it must be an alias
assertThat("resource.alias",alias,isAliasFor(resource));
assertThat("resource.uri.alias",newResource(alias.getURI()),isAliasFor(resource));
assertThat("resource.file.alias",newResource(alias.getFile()),isAliasFor(resource));
}
}
catch (InvalidPathException e)
{
// NTFS filesystem streams are unsupported on some platforms.
assumeNoException(e);
}
}
}
/**
* NTFS Alternative Data / File Streams.
* <p>
* See: http://msdn.microsoft.com/en-us/library/windows/desktop/aa364404(v=vs.85).aspx
* @throws Exception failed test
*/
@Test
public void testNTFSFileEncodedDataStreamAlias() throws Exception
{
Path dir = testdir.getDir().toPath().normalize().toRealPath();
Files.createDirectories(dir);
Path path = dir.resolve("testfile");
Files.createFile(path);
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());
try
{
// Attempt to reference same file, but via NTFS DATA stream (encoded addPath version)
Resource alias = base.addPath("testfile::%24DATA");
if (alias.exists())
{
// If it exists, it must be an alias
assertThat("resource.alias",alias,isAliasFor(resource));
assertThat("resource.uri.alias",newResource(alias.getURI()),isAliasFor(resource));
assertThat("resource.file.alias",newResource(alias.getFile()),isAliasFor(resource));
}
}
catch (InvalidPathException e)
{
// NTFS filesystem streams are unsupported on some platforms.
assumeNoException(e);
}
}
}
@Test
public void testSemicolon() throws Exception
{
Path dir = testdir.getDir().toPath().normalize().toRealPath();
try
{
// attempt to create file
Path foo = dir.resolve("foo;");
Files.createFile(foo);
}
catch (Exception e)
{
// if unable to create file, no point testing the rest.
// this is the path that Microsoft Windows takes.
assumeNoException(e);
}
try (Resource base = newResource(dir.toFile()))
{
Resource res = base.addPath("foo;");
assertThat("Alias: " + res,res,hasNoAlias());
}
}
@Test
public void testSingleQuote() throws Exception
{
Path dir = testdir.getDir().toPath().normalize().toRealPath();
Files.createDirectories(dir);
try
{
// attempt to create file
Path foo = dir.resolve("foo' bar");
Files.createFile(foo);
}
catch (Exception e)
{
// if unable to create file, no point testing the rest.
// this is the path that Microsoft Windows takes.
assumeNoException(e);
}
try (Resource base = newResource(dir.toFile()))
{
Resource res = base.addPath("foo' bar");
assertThat("Alias: " + res,res.getAlias(),nullValue());
}
}
@Test
public void testSingleBackTick() throws Exception
{
Path dir = testdir.getDir().toPath().normalize().toRealPath();
Files.createDirectories(dir);
try
{
// attempt to create file
Path foo = dir.resolve("foo` bar");
Files.createFile(foo);
}
catch (Exception e)
{
// if unable to create file, no point testing the rest.
// this is the path that Microsoft Windows takes.
assumeNoException(e);
}
try (Resource base = newResource(dir.toFile()))
{
// FileResource does not pass this test!
assumeFalse(base instanceof FileResource);
Resource res = base.addPath("foo` bar");
assertThat("Alias: " + res,res.getAlias(),nullValue());
}
}
@Test
public void testBrackets() throws Exception
{
Path dir = testdir.getDir().toPath().normalize().toRealPath();
Files.createDirectories(dir);
try
{
// attempt to create file
Path foo = dir.resolve("foo[1]");
Files.createFile(foo);
}
catch (Exception e)
{
// if unable to create file, no point testing the rest.
// this is the path that Microsoft Windows takes.
assumeNoException(e);
}
try (Resource base = newResource(dir.toFile()))
{
Resource res = base.addPath("foo[1]");
assertThat("Alias: " + res,res.getAlias(),nullValue());
}
}
@Test
public void testBraces() throws Exception
{
Path dir = testdir.getDir().toPath().normalize().toRealPath();
Files.createDirectories(dir);
try
{
// attempt to create file
Path foo = dir.resolve("foo.{bar}.txt");
Files.createFile(foo);
}
catch (Exception e)
{
// if unable to create file, no point testing the rest.
// this is the path that Microsoft Windows takes.
assumeNoException(e);
}
try (Resource base = newResource(dir.toFile()))
{
// FileResource does not pass this test!
assumeFalse(base instanceof FileResource);
Resource res = base.addPath("foo.{bar}.txt");
assertThat("Alias: " + res,res.getAlias(),nullValue());
}
}
@Test
public void testCaret() throws Exception
{
Path dir = testdir.getDir().toPath().normalize().toRealPath();
Files.createDirectories(dir);
try
{
// attempt to create file
Path foo = dir.resolve("foo^3.txt");
Files.createFile(foo);
}
catch (Exception e)
{
// if unable to create file, no point testing the rest.
// this is the path that Microsoft Windows takes.
assumeNoException(e);
}
try (Resource base = newResource(dir.toFile()))
{
// FileResource does not pass this test!
assumeFalse(base instanceof FileResource);
Resource res = base.addPath("foo^3.txt");
assertThat("Alias: " + res,res.getAlias(),nullValue());
}
}
@Test
public void testPipe() throws Exception
{
Path dir = testdir.getDir().toPath().normalize().toRealPath();
Files.createDirectories(dir);
try
{
// attempt to create file
Path foo = dir.resolve("foo|bar.txt");
Files.createFile(foo);
}
catch (Exception e)
{
// if unable to create file, no point testing the rest.
// this is the path that Microsoft Windows takes.
assumeNoException(e);
}
try (Resource base = newResource(dir.toFile()))
{
// FileResource does not pass this test!
assumeFalse(base instanceof FileResource);
Resource res = base.addPath("foo|bar.txt");
assertThat("Alias: " + res,res.getAlias(),nullValue());
}
}
/**
* The most basic access example
* @throws Exception failed test
*/
@Test
public void testExist_Normal() throws Exception
{
Path dir = testdir.getDir().toPath().normalize().toRealPath();
Files.createDirectories(dir);
Path path = dir.resolve("a.jsp");
Files.createFile(path);
URI ref = testdir.getDir().toURI().resolve("a.jsp");
try (Resource fileres = newResource(ref))
{
assertThat("Resource: " + fileres,fileres.exists(),is(true));
}
}
@Test
public void testSingleQuoteInFileName() throws Exception
{
Path dir = testdir.getDir().toPath().normalize().toRealPath();
Files.createDirectories(dir);
Path fooA = dir.resolve("foo's.txt");
Path fooB = dir.resolve("f o's.txt");
Files.createFile(fooA);
Files.createFile(fooB);
URI refQuoted = dir.resolve("foo's.txt").toUri();
try (Resource fileres = newResource(refQuoted))
{
// This test does not pass on FileResource
assumeFalse(fileres instanceof FileResource);
assertThat("Exists: " + refQuoted,fileres.exists(),is(true));
assertThat("Alias: " + refQuoted,fileres,hasNoAlias());
}
URI refEncoded = dir.toUri().resolve("foo%27s.txt");
try (Resource fileres = newResource(refEncoded))
{
assertThat("Exists: " + refEncoded,fileres.exists(),is(true));
assertThat("Alias: " + refEncoded,fileres,hasNoAlias());
}
URI refQuoteSpace = dir.toUri().resolve("f%20o's.txt");
try (Resource fileres = newResource(refQuoteSpace))
{
assertThat("Exists: " + refQuoteSpace,fileres.exists(),is(true));
assertThat("Alias: " + refQuoteSpace,fileres,hasNoAlias());
}
URI refEncodedSpace = dir.toUri().resolve("f%20o%27s.txt");
try (Resource fileres = newResource(refEncodedSpace))
{
assertThat("Exists: " + refEncodedSpace,fileres.exists(),is(true));
assertThat("Alias: " + refEncodedSpace,fileres,hasNoAlias());
}
URI refA = dir.toUri().resolve("foo's.txt");
URI refB = dir.toUri().resolve("foo%27s.txt");
StringBuilder msg = new StringBuilder();
msg.append("URI[a].equals(URI[b])").append(System.lineSeparator());
msg.append("URI[a] = ").append(refA).append(System.lineSeparator());
msg.append("URI[b] = ").append(refB);
// show that simple URI.equals() doesn't work
assertThat(msg.toString(),refA.equals(refB),is(false));
// now show that Resource.equals() does work
try (Resource a = newResource(refA); Resource b = newResource(refB);)
{
assertThat("A.equals(B)",a.equals(b),is(true));
}
}
@Test
public void testExist_BadURINull() throws Exception
{
Path dir = testdir.getDir().toPath().normalize().toRealPath();
Files.createDirectories(dir);
Path path = dir.resolve("a.jsp");
Files.createFile(path);
try
{
// request with null at end
URI uri = testdir.getDir().toURI().resolve("a.jsp%00");
assertThat("Null URI",uri,notNullValue());
Resource r = newResource(uri);
// if we have r, then it better not exist
assertFalse(r.exists());
}
catch (InvalidPathException e)
{
// Exception is acceptable
}
}
@Test
public void testExist_BadURINullX() throws Exception
{
Path dir = testdir.getDir().toPath().normalize().toRealPath();
Files.createDirectories(dir);
Path path = dir.resolve("a.jsp");
Files.createFile(path);
try
{
// request with null and x at end
URI uri = testdir.getDir().toURI().resolve("a.jsp%00x");
assertThat("NullX URI",uri,notNullValue());
Resource r = newResource(uri);
// if we have r, then it better not exist
assertFalse(r.exists());
}
catch (InvalidPathException e)
{
// Exception is acceptable
}
}
@Test
public void testEncoding() throws Exception
{
Path dir = testdir.getDir().toPath().normalize().toRealPath();
Files.createDirectories(dir);
Path specials = dir.resolve("a file with,spe#ials");
Files.createFile(specials);
try(Resource res = newResource(specials.toFile()))
{
assertThat("Specials URL", res.getURI().toASCIIString(), containsString("a%20file%20with,spe%23ials"));
assertThat("Specials Filename", res.getFile().toString(), containsString("a file with,spe#ials"));
res.delete();
assertThat("File should have been deleted.",res.exists(),is(false));
}
}
@Test
public void testUtf8Dir() throws Exception
{
Path dir = testdir.getDir().toPath().normalize().toRealPath();
Path utf8Dir = dir.resolve("bãm");
Files.createDirectories(utf8Dir);
Path file = utf8Dir.resolve("file.txt");
Files.createFile(file);
try (Resource base = newResource(utf8Dir.toFile()))
{
assertThat("Exists: " + utf8Dir,base.exists(),is(true));
assertThat("Alias: " + utf8Dir,base,hasNoAlias());
Resource r = base.addPath("file.txt");
assertThat("Exists: " + r,r.exists(),is(true));
assertThat("Alias: " + r,r,hasNoAlias());
}
}
}