Making updates to FileResource and PathResource for Windows 8.1

This commit is contained in:
Joakim Erdfelt 2015-04-28 08:28:09 -07:00
parent 71efdf0f89
commit c17f1982be
3 changed files with 73 additions and 17 deletions

View File

@ -180,7 +180,7 @@ public class FileResource extends Resource
/* -------------------------------------------------------- */
@Override
public Resource addPath(String path)
throws IOException,MalformedURLException
throws IOException, MalformedURLException
{
path = org.eclipse.jetty.util.URIUtil.canonicalPath(path);
@ -205,9 +205,14 @@ public class FileResource extends Resource
uri=new URI(_uri+path);
}
}
catch(final URISyntaxException e)
catch (final URISyntaxException e)
{
throw new MalformedURLException(){{initCause(e);}};
throw new MalformedURLException(e.getMessage())
{
{
initCause(e);
}
};
}
return new FileResource(uri);

View File

@ -32,7 +32,6 @@ import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.InvalidPathException;
import java.nio.file.LinkOption;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.nio.file.attribute.FileTime;
@ -72,23 +71,66 @@ public class PathResource extends Resource
if (Files.exists(path))
{
Path real = abs.toRealPath(FOLLOW_LINKS);
// We don't use (!Files.isSameFile(abs,real)) here as this
// results in invalid alias detection on systems like OSX.
// Where a real file "foo" can be referenced via Path "FOO",
// this results in Files.isSameFile(Path("foo"), Path("FOO")) == true
if (!abs.equals(real))
/*
* If the real path is not the same as the absolute path
* then we know that the real path is the alias for the
* provided path.
*
* For OS's that are case insensitive, this should
* return the real (on-disk / case correct) version
* of the path.
*
* We have to be careful on Windows and OSX.
*
* Assume we have the following scenario
* Path a = new File("foo").toPath();
* Files.createFile(a);
* Path b = new File("FOO").toPath();
*
* There now exists a file called "foo" on disk.
* Using Windows or OSX, with a Path reference of
* "FOO", "Foo", "fOO", etc.. means the following
*
* | OSX | Windows | Linux
* -----------------------+---------+------------+---------
* Files.exists(a) | True | True | True
* Files.exists(b) | True | True | False
* Files.isSameFile(a,b) | True | True | False
* a.equals(b) | False | True | False
*
* See the javadoc for Path.equals() for details about this FileSystem
* behavior difference
*
* We also cannot rely on a.compareTo(b) as this is roughly equivalent
* in implementation to a.equals(b)
*/
int absCount = abs.getNameCount();
int realCount = abs.getNameCount();
if (absCount != realCount)
{
// different number of segments
return real;
}
// compare each segment of path, backwards
for (int i = realCount-1; i >= 0; i--)
{
if (!abs.getName(i).toString().equals(real.getName(i).toString()))
{
return real;
}
}
catch (NoSuchFileException e)
}
}
catch (IOException e)
{
// Ignore
}
catch (Exception e)
{
// TODO: reevaluate severity level
LOG.warn("bad alias ({}) for {}", e.getClass().getName(), e.getMessage());
return abs;
}
return null;
}

View File

@ -30,6 +30,7 @@ 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;
@ -251,9 +252,17 @@ public class FileSystemResourceTest
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
@ -265,7 +274,7 @@ public class FileSystemResourceTest
{
for (Path entry : dir)
{
if (Files.isDirectory(entry))
if (Files.isDirectory(entry) && !Files.isHidden(entry))
{
return entry.toAbsolutePath().toString();
}
@ -324,7 +333,7 @@ public class FileSystemResourceTest
try (Resource base = newResource(dir.toFile()))
{
Resource res = base.addPath("foo");
assertThat("foo.lastModified",res.lastModified()/1000*1000,is(expected));
assertThat("foo.lastModified",res.lastModified()/1000*1000, lessThanOrEqualTo(expected));
}
}