437800 - URLs with single quote and spaces return 404

+ Expanded FileResourceTest
+ Added PathResource + PathResourceTest to show java.nio.file
  alternative approach (currently POC)
This commit is contained in:
Joakim Erdfelt 2014-06-25 06:52:18 -07:00
parent 3ff4195dbc
commit 2a943887b6
6 changed files with 964 additions and 121 deletions

View File

@ -0,0 +1,331 @@
//
// ========================================================================
// 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.io.InputStream;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.channels.FileChannel;
import java.nio.channels.ReadableByteChannel;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.InvalidPathException;
import java.nio.file.LinkOption;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.nio.file.StandardOpenOption;
import java.nio.file.attribute.FileTime;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
/**
* Java NIO Path equivalent of FileResource.
*/
public class PathResource extends Resource
{
private static final Logger LOG = Log.getLogger(PathResource.class);
private final Path path;
private final URI uri;
private LinkOption linkOptions[] = new LinkOption[] { LinkOption.NOFOLLOW_LINKS };
public PathResource(File file)
{
this(file.toPath());
}
public PathResource(Path path)
{
this.path = path;
this.uri = this.path.toUri();
}
public PathResource(URI uri) throws IOException
{
if (!uri.isAbsolute())
{
throw new IllegalArgumentException("not an absolute uri");
}
if (!uri.getScheme().equalsIgnoreCase("file"))
{
throw new IllegalArgumentException("not file: scheme");
}
Path path;
try
{
path = new File(uri).toPath();
}
catch (InvalidPathException e)
{
throw e;
}
catch (IllegalArgumentException e)
{
throw e;
}
catch (Exception e)
{
LOG.ignore(e);
throw new IOException("Unable to build Path from: " + uri,e);
}
this.path = path;
this.uri = path.toUri();
}
public PathResource(URL url) throws IOException, URISyntaxException
{
this(url.toURI());
}
@Override
public Resource addPath(String apath) throws IOException, MalformedURLException
{
return new PathResource(this.path.resolve(apath));
}
@Override
public void close()
{
// not applicable for FileSytem / Path
}
@Override
public boolean delete() throws SecurityException
{
try
{
return Files.deleteIfExists(path);
}
catch (IOException e)
{
LOG.ignore(e);
return false;
}
}
@Override
public boolean equals(Object obj)
{
if (this == obj)
{
return true;
}
if (obj == null)
{
return false;
}
if (getClass() != obj.getClass())
{
return false;
}
PathResource other = (PathResource)obj;
if (path == null)
{
if (other.path != null)
{
return false;
}
}
else if (!path.equals(other.path))
{
return false;
}
return true;
}
@Override
public boolean exists()
{
return Files.exists(path,linkOptions);
}
@Override
public File getFile() throws IOException
{
return path.toFile();
}
public boolean getFollowLinks()
{
return (linkOptions != null) && (linkOptions.length > 0) && (linkOptions[0] == LinkOption.NOFOLLOW_LINKS);
}
@Override
public InputStream getInputStream() throws IOException
{
return Files.newInputStream(path,StandardOpenOption.READ);
}
@Override
public String getName()
{
return path.toAbsolutePath().toString();
}
@Override
public ReadableByteChannel getReadableByteChannel() throws IOException
{
return FileChannel.open(path,StandardOpenOption.READ);
}
@Override
public URI getURI()
{
return this.uri;
}
@Override
public URL getURL()
{
try
{
return path.toUri().toURL();
}
catch (MalformedURLException e)
{
return null;
}
}
@Override
public int hashCode()
{
final int prime = 31;
int result = 1;
result = (prime * result) + ((path == null)?0:path.hashCode());
return result;
}
@Override
public boolean isContainedIn(Resource r) throws MalformedURLException
{
// not applicable for FileSystem / path
return false;
}
@Override
public boolean isDirectory()
{
return Files.isDirectory(path,linkOptions);
}
@Override
public long lastModified()
{
try
{
FileTime ft = Files.getLastModifiedTime(path,linkOptions);
return ft.toMillis();
}
catch (IOException e)
{
LOG.ignore(e);
return 0;
}
}
@Override
public long length()
{
try
{
return Files.size(path);
}
catch (IOException e)
{
// in case of error, use File.length logic of 0L
return 0L;
}
}
@Override
public String[] list()
{
try
{
List<String> entries = new ArrayList<>();
try (DirectoryStream<Path> dir = Files.newDirectoryStream(path))
{
for (Path entry : dir)
{
String name = entry.getFileName().toString();
if (Files.isDirectory(entry))
{
name += "/";
}
entries.add(name);
}
}
int size = entries.size();
return entries.toArray(new String[size]);
}
catch (IOException e)
{
LOG.ignore(e);
}
return null;
}
@Override
public boolean renameTo(Resource dest) throws SecurityException
{
if (dest instanceof PathResource)
{
PathResource destRes = (PathResource)dest;
try
{
Path result = Files.move(path,destRes.path,StandardCopyOption.ATOMIC_MOVE);
return Files.exists(result,linkOptions);
}
catch (IOException e)
{
LOG.ignore(e);
return false;
}
}
else
{
return false;
}
}
public void setFollowLinks(boolean followLinks)
{
if (followLinks)
{
linkOptions = new LinkOption[0];
}
else
{
linkOptions = new LinkOption[] { LinkOption.NOFOLLOW_LINKS };
}
}
}

View File

@ -352,6 +352,7 @@ public abstract class Resource implements ResourceFactory, Closeable
/** /**
* Returns an URL representing the given resource * Returns an URL representing the given resource
*/ */
// TODO: should deprecate this one and only use getURI()
public abstract URL getURL(); public abstract URL getURL();
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
@ -405,6 +406,7 @@ public abstract class Resource implements ResourceFactory, Closeable
/** /**
* Deletes the given resource * Deletes the given resource
*/ */
// TODO: can throw IOException
public abstract boolean delete() public abstract boolean delete()
throws SecurityException; throws SecurityException;
@ -412,6 +414,7 @@ public abstract class Resource implements ResourceFactory, Closeable
/** /**
* Rename the given resource * Rename the given resource
*/ */
// TODO: can throw IOException
public abstract boolean renameTo( Resource dest) public abstract boolean renameTo( Resource dest)
throws SecurityException; throws SecurityException;
@ -420,6 +423,7 @@ public abstract class Resource implements ResourceFactory, Closeable
* Returns a list of resource names contained in the given resource * Returns a list of resource names contained in the given resource
* The resource names are not URL encoded. * The resource names are not URL encoded.
*/ */
// TODO: can throw IOException
public abstract String[] list(); public abstract String[] list();
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */

View File

@ -0,0 +1,137 @@
//
// ========================================================================
// 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;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.junit.Assert;
public class CollectionAssert
{
public static void assertContainsUnordered(String msg, Collection<String> expectedSet, Collection<String> actualSet)
{
// same size?
boolean mismatch = expectedSet.size() != actualSet.size();
// test content
Set<String> missing = new HashSet<>();
for (String expected : expectedSet)
{
if (!actualSet.contains(expected))
{
missing.add(expected);
}
}
if (mismatch || missing.size() > 0)
{
// build up detailed error message
StringWriter message = new StringWriter();
PrintWriter err = new PrintWriter(message);
err.printf("%s: Assert Contains (Unordered)",msg);
if (mismatch)
{
err.print(" [size mismatch]");
}
if (missing.size() >= 0)
{
err.printf(" [%d entries missing]",missing.size());
}
err.println();
err.printf("Actual Entries (size: %d)%n",actualSet.size());
for (String actual : actualSet)
{
char indicator = expectedSet.contains(actual)?' ':'>';
err.printf("%s| %s%n",indicator,actual);
}
err.printf("Expected Entries (size: %d)%n",expectedSet.size());
for (String expected : expectedSet)
{
char indicator = actualSet.contains(expected)?' ':'>';
err.printf("%s| %s%n",indicator,expected);
}
err.flush();
Assert.fail(message.toString());
}
}
public static void assertOrdered(String msg, List<String> expectedList, List<String> actualList)
{
// same size?
boolean mismatch = expectedList.size() != actualList.size();
// test content
List<Integer> badEntries = new ArrayList<>();
int min = Math.min(expectedList.size(),actualList.size());
int max = Math.max(expectedList.size(),actualList.size());
for (int i = 0; i < min; i++)
{
if (!expectedList.get(i).equals(actualList.get(i)))
{
badEntries.add(i);
}
}
for (int i = min; i < max; i++)
{
badEntries.add(i);
}
if (mismatch || badEntries.size() > 0)
{
// build up detailed error message
StringWriter message = new StringWriter();
PrintWriter err = new PrintWriter(message);
err.printf("%s: Assert Contains (Unordered)",msg);
if (mismatch)
{
err.print(" [size mismatch]");
}
if (badEntries.size() >= 0)
{
err.printf(" [%d entries not matched]",badEntries.size());
}
err.println();
err.printf("Actual Entries (size: %d)%n",actualList.size());
for (int i = 0; i < actualList.size(); i++)
{
String actual = actualList.get(i);
char indicator = badEntries.contains(i)?'>':' ';
err.printf("%s[%d] %s%n",indicator,i,actual);
}
err.printf("Expected Entries (size: %d)%n",expectedList.size());
for (int i = 0; i < expectedList.size(); i++)
{
String expected = expectedList.get(i);
char indicator = badEntries.contains(i)?'>':' ';
err.printf("%s[%d] %s%n",indicator,i,expected);
}
err.flush();
Assert.fail(message.toString());
}
}
}

View File

@ -0,0 +1,447 @@
//
// ========================================================================
// 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 static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import static org.junit.Assume.*;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.io.StringWriter;
import java.net.URI;
import java.net.URL;
import java.nio.ByteBuffer;
import java.nio.channels.ReadableByteChannel;
import java.nio.file.InvalidPathException;
import java.util.ArrayList;
import java.util.Arrays;
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.eclipse.jetty.util.CollectionAssert;
import org.junit.Rule;
import org.junit.Test;
public abstract class AbstractFSResourceTest
{
@Rule
public TestingDir testdir = new TestingDir();
public abstract Resource newResource(URI uri) throws IOException;
public abstract Resource newResource(File file) throws IOException;
private URI createEmptyFile(String name) throws IOException
{
File file = testdir.getFile(name);
file.createNewFile();
return file.toURI();
}
@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)
{
newResource(new URI("file://Z:/:"));
}
else if (OS.IS_WINDOWS)
{
newResource(new URI("file:/dev/null"));
}
}
@Test
public void testIsContainedIn() throws Exception
{
createEmptyFile("foo");
try (Resource base = newResource(testdir.getDir()))
{
Resource res = base.addPath("foo");
assertThat("is contained in",res.isContainedIn(base),is(false));
}
}
@Test
public void testIsDirectory() throws Exception
{
File dir = testdir.getDir();
createEmptyFile("foo");
File subdir = new File(dir,"sub");
FS.ensureDirExists(subdir);
try (Resource base = newResource(testdir.getDir()))
{
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
{
File file = testdir.getFile("foo");
file.createNewFile();
long expected = file.lastModified();
try (Resource base = newResource(testdir.getDir()))
{
Resource res = base.addPath("foo");
assertThat("foo.lastModified",res.lastModified(),is(expected));
}
}
@Test
public void testLastModified_NotExists() throws Exception
{
try (Resource base = newResource(testdir.getDir()))
{
Resource res = base.addPath("foo");
assertThat("foo.lastModified",res.lastModified(),is(0L));
}
}
@Test
public void testLength() throws Exception
{
File file = testdir.getFile("foo");
file.createNewFile();
try (StringReader reader = new StringReader("foo"); FileWriter writer = new FileWriter(file))
{
IO.copy(reader,writer);
}
long expected = file.length();
try (Resource base = newResource(testdir.getDir()))
{
Resource res = base.addPath("foo");
assertThat("foo.length",res.length(),is(expected));
}
}
@Test
public void testLength_NotExists() throws Exception
{
try (Resource base = newResource(testdir.getDir()))
{
Resource res = base.addPath("foo");
assertThat("foo.length",res.length(),is(0L));
}
}
@Test
public void testDelete() throws Exception
{
File file = testdir.getFile("foo");
file.createNewFile();
try (Resource base = newResource(testdir.getDir()))
{
// 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
{
try (Resource base = newResource(testdir.getDir()))
{
// 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
{
String expected = testdir.getDir().getAbsolutePath();
try (Resource base = newResource(testdir.getDir()))
{
assertThat("base.name",base.getName(),is(expected));
}
}
@Test
public void testInputStream() throws Exception
{
File file = testdir.getFile("foo");
file.createNewFile();
String content = "Foo is here";
try (StringReader reader = new StringReader(content); FileWriter writer = new FileWriter(file))
{
IO.copy(reader,writer);
}
try (Resource base = newResource(testdir.getDir()))
{
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
{
File file = testdir.getFile("foo");
file.createNewFile();
String content = "Foo is here";
try (StringReader reader = new StringReader(content); FileWriter writer = new FileWriter(file))
{
IO.copy(reader,writer);
}
try (Resource base = newResource(testdir.getDir()))
{
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
{
File file = testdir.getFile("foo");
file.createNewFile();
URI expected = file.toURI();
try (Resource base = newResource(testdir.getDir()))
{
Resource foo = base.addPath("foo");
assertThat("getURI",foo.getURI(),is(expected));
}
}
@Test
public void testGetURL() throws Exception
{
File file = testdir.getFile("foo");
file.createNewFile();
URL expected = file.toURI().toURL();
try (Resource base = newResource(testdir.getDir()))
{
Resource foo = base.addPath("foo");
assertThat("getURL",foo.getURL(),is(expected));
}
}
@Test
public void testList() throws Exception
{
File dir = testdir.getDir();
FS.touch(new File(dir, "foo"));
FS.touch(new File(dir, "bar"));
FS.ensureDirExists(new File(dir, "tick"));
FS.ensureDirExists(new File(dir, "tock"));
List<String> expected = new ArrayList<>();
expected.add("foo");
expected.add("bar");
expected.add("tick/");
expected.add("tock/");
try (Resource base = newResource(testdir.getDir()))
{
String list[] = base.list();
List<String> actual = Arrays.asList(list);
CollectionAssert.assertContainsUnordered("Resource Directory Listing",
expected,actual);
}
}
@Test
public void testSemicolon() throws Exception
{
assumeTrue(!OS.IS_WINDOWS);
createEmptyFile("foo;");
try (Resource base = newResource(testdir.getDir()))
{
Resource res = base.addPath("foo;");
assertThat("Alias: " + res,res.getAlias(),nullValue());
}
}
@Test
public void testExist_Normal() throws Exception
{
createEmptyFile("a.jsp");
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
{
createEmptyFile("foo's.txt");
createEmptyFile("f o's.txt");
URI refQuoted = testdir.getDir().toURI().resolve("foo's.txt");
try (Resource fileres = newResource(refQuoted))
{
assertThat("Exists: " + refQuoted,fileres.exists(),is(true));
assertThat("Alias: " + refQuoted,fileres.getAlias(),nullValue());
}
URI refEncoded = testdir.getDir().toURI().resolve("foo%27s.txt");
try (Resource fileres = newResource(refEncoded))
{
assertThat("Exists: " + refEncoded,fileres.exists(),is(true));
assertThat("Alias: " + refEncoded,fileres.getAlias(),nullValue());
}
URI refQuoteSpace = testdir.getDir().toURI().resolve("f%20o's.txt");
try (Resource fileres = newResource(refQuoteSpace))
{
assertThat("Exists: " + refQuoteSpace,fileres.exists(),is(true));
assertThat("Alias: " + refQuoteSpace,fileres.getAlias(),nullValue());
}
URI refEncodedSpace = testdir.getDir().toURI().resolve("f%20o%27s.txt");
try (Resource fileres = newResource(refEncodedSpace))
{
assertThat("Exists: " + refEncodedSpace,fileres.exists(),is(true));
assertThat("Alias: " + refEncodedSpace,fileres.getAlias(),nullValue());
}
URI refA = testdir.getDir().toURI().resolve("foo's.txt");
URI refB = testdir.getDir().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_BadNull() 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());
newResource(ref);
fail("Should have thrown " + InvalidPathException.class);
}
catch (InvalidPathException e)
{
// Expected path
}
}
@Test
public void testExist_BadNullX() 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());
newResource(ref);
fail("Should have thrown " + InvalidPathException.class);
}
catch (InvalidPathException e)
{
// Expected path
}
}
}

View File

@ -18,150 +18,36 @@
package org.eclipse.jetty.util.resource; package org.eclipse.jetty.util.resource;
import static org.hamcrest.Matchers.is;
import static org.junit.Assume.assumeTrue;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URI; import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import org.eclipse.jetty.toolchain.test.OS;
import org.eclipse.jetty.toolchain.test.TestingDir;
import org.eclipse.jetty.util.UrlEncoded;
import org.hamcrest.Matchers;
import org.junit.Assert;
import org.junit.Ignore; import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
public class FileResourceTest public class FileResourceTest extends AbstractFSResourceTest
{ {
@Rule @Override
public TestingDir testdir = new TestingDir(); public Resource newResource(URI uri) throws IOException
private URI createDummyFile(String name) throws IOException
{ {
File file = testdir.getFile(name); return new FileResource(uri);
file.createNewFile();
return file.toURI();
} }
private URL decode(URL url) throws MalformedURLException @Override
public Resource newResource(File file) throws IOException
{ {
String raw = url.toExternalForm(); return new FileResource(file);
String decoded = UrlEncoded.decodeString(raw,0,raw.length(), StandardCharsets.UTF_8);
return new URL(decoded);
} }
@Test
public void testSemicolon() throws Exception
{
assumeTrue(!OS.IS_WINDOWS);
createDummyFile("foo;");
try(Resource base = new FileResource(testdir.getDir());)
{
Resource res = base.addPath("foo;");
Assert.assertNull(res.getAlias());
}
}
@Test
public void testExist_Normal() throws Exception
{
createDummyFile("a.jsp");
URI ref = testdir.getDir().toURI().resolve("a.jsp");
try(FileResource fileres = new FileResource(decode(ref.toURL()));)
{
Assert.assertThat("FileResource: " + fileres,fileres.exists(),is(true));
}
}
@Test
public void testSingleQuoteInFileName() throws Exception
{
createDummyFile("foo's.txt");
createDummyFile("f o's.txt");
URI refQuoted = testdir.getDir().toURI().resolve("foo's.txt");
try(FileResource fileres = new FileResource(refQuoted))
{
Assert.assertThat(fileres.exists(),is(true));
Assert.assertThat(fileres.getAlias(),Matchers.nullValue());
}
URI refEncoded = testdir.getDir().toURI().resolve("foo%27s.txt");
try(FileResource fileres = new FileResource(refEncoded))
{
Assert.assertThat(fileres.exists(),is(true));
Assert.assertThat(fileres.getAlias(),Matchers.nullValue());
}
URI refQuoteSpace = testdir.getDir().toURI().resolve("f%20o's.txt");
try(FileResource fileres = new FileResource(refQuoteSpace))
{
Assert.assertThat(fileres.exists(),is(true));
Assert.assertThat(fileres.getAlias(),Matchers.nullValue());
}
URI refEncodedSpace = testdir.getDir().toURI().resolve("f%20o%27s.txt");
try(FileResource fileres = new FileResource(refEncodedSpace))
{
Assert.assertThat(fileres.exists(),is(true));
Assert.assertThat(fileres.getAlias(),Matchers.nullValue());
}
}
@Ignore("Cannot get null to be seen by FileResource") @Ignore("Cannot get null to be seen by FileResource")
@Test @Test
public void testExist_BadNull() throws Exception public void testExist_BadNull() throws Exception
{ {
createDummyFile("a.jsp");
try
{
// request with null at end
URI ref = testdir.getDir().toURI().resolve("a.jsp%00");
try(FileResource fileres = new FileResource(decode(ref.toURL()));)
{
Assert.assertThat("FileResource: " + fileres,fileres.exists(),is(false));
}
}
catch(URISyntaxException e)
{
// Valid path
}
} }
@Ignore("Validation shouldn't be done in FileResource") @Ignore("Validation shouldn't be done in FileResource")
@Test @Test
public void testExist_BadNullX() throws Exception public void testExist_BadNullX() throws Exception
{ {
createDummyFile("a.jsp");
try
{
// request with null and x at end
URI ref = testdir.getDir().toURI().resolve("a.jsp%00x");
try(FileResource fileres = new FileResource(decode(ref.toURL()));)
{
Assert.assertThat("FileResource: " + fileres,fileres.exists(),is(false));
}
}
catch(URISyntaxException e)
{
// Valid path
}
} }
} }

View File

@ -0,0 +1,38 @@
//
// ========================================================================
// 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);
}
}