Merged branch 'origin/master' into 'jetty-http2'.
This commit is contained in:
commit
e63ceabafe
|
@ -236,6 +236,11 @@ public class ConnectionPool implements Closeable, Dumpable
|
|||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return String.format("%s %d/%d", getClass().getSimpleName(), connectionCount.get(), maxConnections);
|
||||
return String.format("%s[c=%d/%d,a=%d,i=%d]",
|
||||
getClass().getSimpleName(),
|
||||
connectionCount.get(),
|
||||
maxConnections,
|
||||
activeConnections.size(),
|
||||
idleConnections.size());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -176,7 +176,7 @@ public abstract class HttpDestination implements Destination, Closeable, Dumpabl
|
|||
else
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Queued {}", request);
|
||||
LOG.debug("Queued {} for {}", request, this);
|
||||
requestNotifier.notifyQueued(request);
|
||||
send();
|
||||
}
|
||||
|
@ -184,7 +184,7 @@ public abstract class HttpDestination implements Destination, Closeable, Dumpabl
|
|||
else
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Max queue size {} exceeded by {}", client.getMaxRequestsQueuedPerDestination(), request);
|
||||
LOG.debug("Max queue size {} exceeded by {} for {}", client.getMaxRequestsQueuedPerDestination(), request, this);
|
||||
request.abort(new RejectedExecutionException("Max requests per destination " + client.getMaxRequestsQueuedPerDestination() + " exceeded for " + this));
|
||||
}
|
||||
}
|
||||
|
@ -258,9 +258,10 @@ public abstract class HttpDestination implements Destination, Closeable, Dumpabl
|
|||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return String.format("%s(%s)%s",
|
||||
return String.format("%s[%s]%s,queue=%d",
|
||||
HttpDestination.class.getSimpleName(),
|
||||
asString(),
|
||||
proxy == null ? "" : " via " + proxy);
|
||||
proxy == null ? "" : "(via " + proxy + ")",
|
||||
exchanges.size());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -94,7 +94,7 @@ public abstract class PoolingHttpDestination<C extends Connection> extends HttpD
|
|||
HttpClient client = getHttpClient();
|
||||
final HttpExchange exchange = getHttpExchanges().poll();
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Processing exchange {} on connection {}", exchange, connection);
|
||||
LOG.debug("Processing exchange {} on {} of {}", exchange, connection, this);
|
||||
if (exchange == null)
|
||||
{
|
||||
if (!connectionPool.release(connection))
|
||||
|
@ -213,4 +213,10 @@ public abstract class PoolingHttpDestination<C extends Connection> extends HttpD
|
|||
{
|
||||
ContainerLifeCycle.dump(out, indent, Arrays.asList(connectionPool));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return String.format("%s,pool=%s", super.toString(), connectionPool);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -142,6 +142,7 @@ public class MainTest
|
|||
File homePath = MavenTestingUtils.getTestResourceDir("usecases/home").getAbsoluteFile();
|
||||
cmdLineArgs.add("jetty.home=" + homePath);
|
||||
cmdLineArgs.add("user.dir=" + homePath);
|
||||
cmdLineArgs.add("java.version=1.7.0_60");
|
||||
|
||||
// Modules
|
||||
cmdLineArgs.add("--module=server");
|
||||
|
|
|
@ -46,6 +46,7 @@ LIB|${jetty.base}/lib/websocket/websocket-server-TEST.jar
|
|||
LIB|${jetty.base}/lib/websocket/websocket-servlet-TEST.jar
|
||||
|
||||
# The Properties we expect (order is irrelevant)
|
||||
PROP|java.version=1.7.0_60
|
||||
PROP|jetty.keymanager.password=OBF:1u2u1wml1z7s1z7a1wnl1u2g
|
||||
PROP|jetty.keystore=etc/keystore
|
||||
PROP|jetty.keystore.password=OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4
|
||||
|
|
|
@ -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 };
|
||||
}
|
||||
}
|
||||
}
|
|
@ -352,6 +352,7 @@ public abstract class Resource implements ResourceFactory, Closeable
|
|||
/**
|
||||
* Returns an URL representing the given resource
|
||||
*/
|
||||
// TODO: should deprecate this one and only use getURI()
|
||||
public abstract URL getURL();
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -405,6 +406,7 @@ public abstract class Resource implements ResourceFactory, Closeable
|
|||
/**
|
||||
* Deletes the given resource
|
||||
*/
|
||||
// TODO: can throw IOException
|
||||
public abstract boolean delete()
|
||||
throws SecurityException;
|
||||
|
||||
|
@ -412,6 +414,7 @@ public abstract class Resource implements ResourceFactory, Closeable
|
|||
/**
|
||||
* Rename the given resource
|
||||
*/
|
||||
// TODO: can throw IOException
|
||||
public abstract boolean renameTo( Resource dest)
|
||||
throws SecurityException;
|
||||
|
||||
|
@ -420,6 +423,7 @@ public abstract class Resource implements ResourceFactory, Closeable
|
|||
* Returns a list of resource names contained in the given resource
|
||||
* The resource names are not URL encoded.
|
||||
*/
|
||||
// TODO: can throw IOException
|
||||
public abstract String[] list();
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
|
@ -18,150 +18,36 @@
|
|||
|
||||
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.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
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.Rule;
|
||||
import org.junit.Test;
|
||||
|
||||
public class FileResourceTest
|
||||
public class FileResourceTest extends AbstractFSResourceTest
|
||||
{
|
||||
@Rule
|
||||
public TestingDir testdir = new TestingDir();
|
||||
|
||||
private URI createDummyFile(String name) throws IOException
|
||||
@Override
|
||||
public Resource newResource(URI uri) throws IOException
|
||||
{
|
||||
File file = testdir.getFile(name);
|
||||
file.createNewFile();
|
||||
return file.toURI();
|
||||
return new FileResource(uri);
|
||||
}
|
||||
|
||||
private URL decode(URL url) throws MalformedURLException
|
||||
@Override
|
||||
public Resource newResource(File file) throws IOException
|
||||
{
|
||||
String raw = url.toExternalForm();
|
||||
String decoded = UrlEncoded.decodeString(raw,0,raw.length(), StandardCharsets.UTF_8);
|
||||
return new URL(decoded);
|
||||
return new FileResource(file);
|
||||
}
|
||||
|
||||
@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")
|
||||
@Test
|
||||
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")
|
||||
@Test
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue