Added alias tests to FileSystemResourceTest

This commit is contained in:
Greg Wilkins 2014-07-31 15:22:12 +10:00
parent 252933891c
commit 0dbf684298
6 changed files with 278 additions and 222 deletions

View File

@ -82,8 +82,7 @@ public class URIUtil
byte[] bytes=null;
if (buf==null)
{
loop:
for (int i=0;i<path.length();i++)
loop: for (int i=0;i<path.length();i++)
{
char c=path.charAt(i);
switch(c)
@ -97,6 +96,8 @@ public class URIUtil
case '<':
case '>':
case ' ':
case '[':
case ']':
buf=new StringBuilder(path.length()*2);
break loop;
default:
@ -106,103 +107,111 @@ public class URIUtil
buf=new StringBuilder(path.length()*2);
break loop;
}
}
}
if (buf==null)
return null;
}
synchronized(buf)
if (bytes!=null)
{
if (bytes!=null)
for (int i=0;i<bytes.length;i++)
{
for (int i=0;i<bytes.length;i++)
byte c=bytes[i];
switch(c)
{
byte c=bytes[i];
switch(c)
{
case '%':
buf.append("%25");
continue;
case '?':
buf.append("%3F");
continue;
case ';':
buf.append("%3B");
continue;
case '#':
buf.append("%23");
continue;
case '"':
buf.append("%22");
continue;
case '\'':
buf.append("%27");
continue;
case '<':
buf.append("%3C");
continue;
case '>':
buf.append("%3E");
continue;
case ' ':
buf.append("%20");
continue;
default:
if (c<0)
{
buf.append('%');
TypeUtil.toHex(c,buf);
}
else
buf.append((char)c);
continue;
}
}
}
else
{
for (int i=0;i<path.length();i++)
{
char c=path.charAt(i);
switch(c)
{
case '%':
buf.append("%25");
continue;
case '?':
buf.append("%3F");
continue;
case ';':
buf.append("%3B");
continue;
case '#':
buf.append("%23");
continue;
case '"':
buf.append("%22");
continue;
case '\'':
buf.append("%27");
continue;
case '<':
buf.append("%3C");
continue;
case '>':
buf.append("%3E");
continue;
case ' ':
buf.append("%20");
continue;
default:
buf.append(c);
continue;
}
case '%':
buf.append("%25");
continue;
case '?':
buf.append("%3F");
continue;
case ';':
buf.append("%3B");
continue;
case '#':
buf.append("%23");
continue;
case '"':
buf.append("%22");
continue;
case '\'':
buf.append("%27");
continue;
case '<':
buf.append("%3C");
continue;
case '>':
buf.append("%3E");
continue;
case ' ':
buf.append("%20");
continue;
case '[':
buf.append("%5B");
continue;
case ']':
buf.append("%5D");
continue;
default:
if (c<0)
{
buf.append('%');
TypeUtil.toHex(c,buf);
}
else
buf.append((char)c);
continue;
}
}
}
else
{
for (int i=0;i<path.length();i++)
{
char c=path.charAt(i);
switch(c)
{
case '%':
buf.append("%25");
continue;
case '?':
buf.append("%3F");
continue;
case ';':
buf.append("%3B");
continue;
case '#':
buf.append("%23");
continue;
case '"':
buf.append("%22");
continue;
case '\'':
buf.append("%27");
continue;
case '<':
buf.append("%3C");
continue;
case '>':
buf.append("%3E");
continue;
case ' ':
buf.append("%20");
continue;
case '[':
buf.append("%5B");
continue;
case ']':
buf.append("%5D");
continue;
default:
buf.append(c);
continue;
}
}
}
return buf;
}

View File

@ -46,9 +46,7 @@ import org.eclipse.jetty.util.log.Logger;
* 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} instead
*/
@Deprecated
public class FileResource extends Resource
{
private static final Logger LOG = Log.getLogger(FileResource.class);
@ -119,7 +117,7 @@ public class FileResource extends Resource
}
/* -------------------------------------------------------- */
FileResource(File file)
public FileResource(File file)
{
_file=file;
_uri=normalizeURI(_file,_file.toURI());
@ -155,7 +153,8 @@ public class FileResource extends Resource
URI alias=new File(can).toURI();
// Have to encode the path as File.toURI does not!
return new URI("file://"+URIUtil.encodePath(alias.getPath()));
String uri="file://"+URIUtil.encodePath(alias.getPath());
return new URI(uri);
}
}
catch(Exception e)

View File

@ -49,10 +49,10 @@ import org.eclipse.jetty.util.log.Logger;
public class PathResource extends Resource
{
private static final Logger LOG = Log.getLogger(PathResource.class);
private final static LinkOption NO_FOLLOW_OPTIONS[] = new LinkOption[] { LinkOption.NOFOLLOW_LINKS };
private final Path path;
private final URI uri;
private LinkOption linkOptions[] = new LinkOption[] { LinkOption.NOFOLLOW_LINKS };
public PathResource(File file)
{
@ -179,7 +179,7 @@ public class PathResource extends Resource
@Override
public boolean exists()
{
return Files.exists(path,linkOptions);
return Files.exists(path,NO_FOLLOW_OPTIONS);
}
@Override
@ -188,11 +188,6 @@ public class PathResource extends Resource
return path.toFile();
}
public boolean getFollowLinks()
{
return (linkOptions != null) && (linkOptions.length > 0) && (linkOptions[0] == LinkOption.NOFOLLOW_LINKS);
}
@Override
public InputStream getInputStream() throws IOException
{
@ -249,7 +244,7 @@ public class PathResource extends Resource
@Override
public boolean isDirectory()
{
return Files.isDirectory(path,linkOptions);
return Files.isDirectory(path,NO_FOLLOW_OPTIONS);
}
@Override
@ -257,7 +252,7 @@ public class PathResource extends Resource
{
try
{
FileTime ft = Files.getLastModifiedTime(path,linkOptions);
FileTime ft = Files.getLastModifiedTime(path,NO_FOLLOW_OPTIONS);
return ft.toMillis();
}
catch (IOException e)
@ -342,7 +337,7 @@ public class PathResource extends Resource
try
{
Path result = Files.move(path,destRes.path);
return Files.exists(result,linkOptions);
return Files.exists(result,NO_FOLLOW_OPTIONS);
}
catch (IOException e)
{
@ -369,18 +364,6 @@ public class PathResource extends Resource
}
}
public void setFollowLinks(boolean followLinks)
{
if (followLinks)
{
linkOptions = new LinkOption[0];
}
else
{
linkOptions = new LinkOption[] { LinkOption.NOFOLLOW_LINKS };
}
}
@Override
public String toString()
{

View File

@ -1,53 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2014 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 java.io.File;
import java.io.IOException;
import java.net.URI;
import org.junit.Ignore;
import org.junit.Test;
public class FileResourceTest extends AbstractFSResourceTest
{
@Override
public Resource newResource(URI uri) throws IOException
{
return new FileResource(uri);
}
@Override
public Resource newResource(File file) throws IOException
{
return new FileResource(file);
}
@Ignore("Cannot get null to be seen by FileResource")
@Test
public void testExist_BadNull() throws Exception
{
}
@Ignore("Validation shouldn't be done in FileResource")
@Test
public void testExist_BadNullX() throws Exception
{
}
}

View File

@ -29,6 +29,7 @@ import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.io.StringWriter;
import java.lang.reflect.InvocationTargetException;
import java.net.URI;
import java.net.URL;
import java.nio.ByteBuffer;
@ -39,8 +40,11 @@ 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 javax.management.RuntimeErrorException;
import org.eclipse.jetty.toolchain.test.FS;
import org.eclipse.jetty.toolchain.test.IO;
import org.eclipse.jetty.toolchain.test.OS;
@ -49,15 +53,78 @@ import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.CollectionAssert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
public abstract class AbstractFSResourceTest
@RunWith(Parameterized.class)
public class FileSystemResourceTest
{
@Rule
public TestingDir testdir = new TestingDir();
private final Class<? extends Resource> _class;
public abstract Resource newResource(URI uri) throws IOException;
@Parameters
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 abstract Resource newResource(File file) throws IOException;
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 URI createEmptyFile(String name) throws IOException
{
@ -361,11 +428,96 @@ public abstract class AbstractFSResourceTest
// 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("foo.alias", resFoo.getAlias(), nullValue());
assertThat("bar.alias", resBar.getAlias(), is(foo.toUri()));
assertThat("foo !alias", resFoo.getAlias(), nullValue());
assertThat(newResource(resFoo.getURI()).getAlias(), nullValue());
assertThat(newResource(resFoo.getFile()).getAlias(), nullValue());
assertThat("bar alias", resBar.getAlias(), is(foo.toUri()));
assertThat(newResource(resBar.getURI()).getAlias(), is(foo.toUri()));
assertThat(newResource(resBar.getFile()).getAlias(), is(foo.toUri()));
}
}
@Test
public void testCaseInsensitiveAlias() throws Exception
{
File dir = testdir.getDir();
Path path = new File(dir, "file").toPath();
Files.createFile(path);
try (Resource base = newResource(testdir.getDir()))
{
Resource resource = base.addPath("file");
assertThat("!alias", resource.getAlias(), nullValue());
assertThat(newResource(resource.getURI()).getAlias(), nullValue());
assertThat(newResource(resource.getFile()).getAlias(), nullValue());
Resource alias = base.addPath("FILE");
if (alias.exists())
{
// If it exists, it must be an alias
assertThat(alias.getAlias(), is(path.toUri()));
assertThat(newResource(alias.getURI()).getAlias(), is(path.toUri()));
assertThat(newResource(alias.getFile()).getAlias(), is(path.toUri()));
}
}
}
@Test
public void testCase8dot3Alias() throws Exception
{
File dir = testdir.getDir();
Path path = new File(dir, "TextFile.Long.txt").toPath();
Files.createFile(path);
try (Resource base = newResource(testdir.getDir()))
{
Resource resource = base.addPath("TextFile.Long.txt");
assertThat("!alias", resource.getAlias(), nullValue());
assertThat(newResource(resource.getURI()).getAlias(), nullValue());
assertThat(newResource(resource.getFile()).getAlias(), nullValue());
Resource alias = base.addPath("TEXTFI~1.TXT");
if (alias.exists())
{
// If it exists, it must be an alias
assertThat(alias.getAlias(), is(path.toUri()));
assertThat(newResource(alias.getURI()).getAlias(), is(path.toUri()));
assertThat(newResource(alias.getFile()).getAlias(), is(path.toUri()));
}
}
}
@Test
public void testCaseNTParamAlias() throws Exception
{
File dir = testdir.getDir();
Path path = new File(dir, "file").toPath();
Files.createFile(path);
try (Resource base = newResource(testdir.getDir()))
{
Resource resource = base.addPath("file");
assertThat("!alias", resource.getAlias(), nullValue());
assertThat(newResource(resource.getURI()).getAlias(), nullValue());
assertThat(newResource(resource.getFile()).getAlias(), nullValue());
Resource alias = base.addPath("file::$DATA");
if (alias.exists())
{
// If it exists, it must be an alias
assertThat(alias.getAlias(), is(path.toUri()));
assertThat(newResource(alias.getURI()).getAlias(), is(path.toUri()));
assertThat(newResource(alias.getFile()).getAlias(), is(path.toUri()));
}
}
}
@Test
public void testSemicolon() throws Exception
{
@ -460,42 +612,46 @@ public abstract class AbstractFSResourceTest
}
@Test
public void testExist_BadNull() throws Exception
public void testExist_BadURINull() throws Exception
{
createEmptyFile("a.jsp");
try
{
// request with null at end
URI ref = testdir.getDir().toURI().resolve("a.jsp%00");
assertThat("Null URI",ref,notNullValue());
URI uri = testdir.getDir().toURI().resolve("a.jsp%00");
assertThat("Null URI",uri,notNullValue());
newResource(ref);
fail("Should have thrown " + InvalidPathException.class);
Resource r = newResource(uri);
// if we have r, then it better not exist
assertFalse(r.exists());
}
catch (InvalidPathException e)
{
// Expected path
// Exception is acceptable
}
}
@Test
public void testExist_BadNullX() throws Exception
public void testExist_BadURINullX() throws Exception
{
createEmptyFile("a.jsp");
try
{
// request with null and x at end
URI ref = testdir.getDir().toURI().resolve("a.jsp%00x");
assertThat("NullX URI",ref,notNullValue());
URI uri = testdir.getDir().toURI().resolve("a.jsp%00x");
assertThat("NullX URI",uri,notNullValue());
newResource(ref);
fail("Should have thrown " + InvalidPathException.class);
Resource r = newResource(uri);
// if we have r, then it better not exist
assertFalse(r.exists());
}
catch (InvalidPathException e)
{
// Expected path
// Exception is acceptable
}
}

View File

@ -1,38 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2014 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 java.io.File;
import java.io.IOException;
import java.net.URI;
public class PathResourceTest extends AbstractFSResourceTest
{
@Override
public Resource newResource(URI uri) throws IOException
{
return new PathResource(uri);
}
@Override
public Resource newResource(File file) throws IOException
{
return new PathResource(file);
}
}