Jetty 12 - Resource `resolve()` and `newResource()` return null on resources that do not exist (#8702)
* Resource `resolve()` and `newResource()` return null on resources that do not exist * Introduce `Resources` utility methods and use them * Updating javadoc
This commit is contained in:
parent
ed3d4a46c7
commit
259deea2f7
|
@ -40,6 +40,7 @@ import org.eclipse.jetty.util.component.ContainerLifeCycle;
|
|||
import org.eclipse.jetty.util.component.Environment;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.eclipse.jetty.util.resource.ResourceFactory;
|
||||
import org.eclipse.jetty.util.resource.Resources;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -226,10 +227,26 @@ public abstract class ScanningAppProvider extends ContainerLifeCycle implements
|
|||
List<Path> files = new ArrayList<>();
|
||||
for (Resource resource : _monitored)
|
||||
{
|
||||
if (resource.exists() && Files.isReadable(resource.getPath()))
|
||||
files.add(resource.getPath());
|
||||
else
|
||||
if (Resources.missing(resource))
|
||||
{
|
||||
LOG.warn("Does not exist: {}", resource);
|
||||
continue; // skip
|
||||
}
|
||||
|
||||
// handle resource smartly
|
||||
for (Resource r: resource)
|
||||
{
|
||||
Path path = r.getPath();
|
||||
if (path == null)
|
||||
{
|
||||
LOG.warn("Not based on FileSystem Path: {}", r);
|
||||
continue; // skip
|
||||
}
|
||||
if (Files.isDirectory(path) || Files.isReadable(path))
|
||||
files.add(resource.getPath());
|
||||
else
|
||||
LOG.warn("Unsupported Path (not a directory and/or not readable): {}", r);
|
||||
}
|
||||
}
|
||||
|
||||
_scanner = new Scanner(null, _useRealPaths);
|
||||
|
|
|
@ -27,6 +27,7 @@ import org.eclipse.jetty.http.MimeTypes;
|
|||
import org.eclipse.jetty.http.ResourceHttpContent;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.eclipse.jetty.util.resource.ResourceFactory;
|
||||
import org.eclipse.jetty.util.resource.Resources;
|
||||
|
||||
/**
|
||||
* An HttpContent.Factory for transient content (not cached). The HttpContent's created by
|
||||
|
@ -54,6 +55,8 @@ public class ResourceContentFactory implements ContentFactory
|
|||
{
|
||||
// try loading the content from our factory.
|
||||
Resource resource = this._factory.newResource(pathInContext);
|
||||
if (Resources.missing(resource))
|
||||
return null;
|
||||
return load(pathInContext, resource);
|
||||
}
|
||||
catch (Throwable t)
|
||||
|
|
|
@ -31,6 +31,7 @@ import org.eclipse.jetty.util.URIUtil;
|
|||
import org.eclipse.jetty.util.UrlEncoded;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.eclipse.jetty.util.resource.ResourceCollators;
|
||||
import org.eclipse.jetty.util.resource.Resources;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -56,7 +57,9 @@ public class ResourceListing
|
|||
{
|
||||
// This method doesn't check aliases, so it is OK to canonicalize here.
|
||||
base = URIUtil.normalizePath(base);
|
||||
if (base == null || !resource.isDirectory())
|
||||
if (base == null)
|
||||
return null;
|
||||
if (!Resources.isReadableDirectory(resource))
|
||||
return null;
|
||||
|
||||
List<Resource> listing = resource.list().stream()
|
||||
|
|
|
@ -55,6 +55,7 @@ import org.eclipse.jetty.util.component.Graceful;
|
|||
import org.eclipse.jetty.util.component.LifeCycle;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.eclipse.jetty.util.resource.ResourceFactory;
|
||||
import org.eclipse.jetty.util.resource.Resources;
|
||||
import org.eclipse.jetty.util.thread.Invocable;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -715,7 +716,18 @@ public class ContextHandler extends Handler.Wrapper implements Attributes, Grace
|
|||
{
|
||||
if (isStarted())
|
||||
throw new IllegalStateException(getState());
|
||||
_baseResource = resourceBase;
|
||||
|
||||
// Allow resource base to be unset
|
||||
if (resourceBase == null)
|
||||
{
|
||||
_baseResource = null;
|
||||
return;
|
||||
}
|
||||
|
||||
if (Resources.isReadable(resourceBase))
|
||||
_baseResource = resourceBase;
|
||||
else
|
||||
throw new IllegalArgumentException("Base Resource is not valid: " + resourceBase);
|
||||
}
|
||||
|
||||
public void setBaseResource(Path path)
|
||||
|
@ -728,11 +740,10 @@ public class ContextHandler extends Handler.Wrapper implements Attributes, Grace
|
|||
}
|
||||
|
||||
Resource resource = ResourceFactory.of(this).newResource(path);
|
||||
if (resource != null && resource.exists())
|
||||
setBaseResource(resource);
|
||||
else
|
||||
if (!Resources.isReadable(resource))
|
||||
throw new IllegalArgumentException("Base Resource is not valid: " + path);
|
||||
|
||||
setBaseResource(resource);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -28,6 +28,7 @@ import org.eclipse.jetty.server.ResourceService;
|
|||
import org.eclipse.jetty.util.URIUtil;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.eclipse.jetty.util.resource.ResourceFactory;
|
||||
import org.eclipse.jetty.util.resource.Resources;
|
||||
|
||||
/**
|
||||
* Resource Handler.
|
||||
|
@ -93,7 +94,7 @@ public class ResourceHandler extends Handler.Wrapper
|
|||
{
|
||||
String welcomeInContext = URIUtil.addPaths(request.getPathInContext(), welcome);
|
||||
Resource welcomePath = _resourceBase.resolve(request.getPathInContext()).resolve(welcome);
|
||||
if (welcomePath != null && welcomePath.exists())
|
||||
if (Resources.isReadableFile(welcomePath))
|
||||
return welcomeInContext;
|
||||
}
|
||||
// not found
|
||||
|
|
|
@ -58,13 +58,27 @@ public class MemoryResource extends Resource
|
|||
@Override
|
||||
public Path getPath()
|
||||
{
|
||||
return Path.of(_uri);
|
||||
// memory resource has no path (it would be problematic for mounting reasons as well)
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDirectory()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReadable()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isContainedIn(Resource r)
|
||||
{
|
||||
return getPath().startsWith(r.getPath());
|
||||
// memory resource can never be contained in another memory resource
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -76,22 +90,13 @@ public class MemoryResource extends Resource
|
|||
@Override
|
||||
public String getName()
|
||||
{
|
||||
Path p = getPath();
|
||||
if (p == null)
|
||||
return _uri.toASCIIString();
|
||||
return p.toAbsolutePath().toString();
|
||||
return _uri.toASCIIString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFileName()
|
||||
{
|
||||
Path p = getPath();
|
||||
if (p == null)
|
||||
return FileID.getFileName(_uri);
|
||||
Path fn = p.getFileName();
|
||||
if (fn == null)
|
||||
return ""; // no segments, so no filename
|
||||
return fn.toString();
|
||||
return FileID.getFileName(_uri);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -106,6 +111,12 @@ public class MemoryResource extends Resource
|
|||
return _bytes.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Resource resolve(String subUriPath)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream newInputStream() throws IOException
|
||||
{
|
||||
|
|
|
@ -16,7 +16,9 @@ package org.eclipse.jetty.util.resource;
|
|||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.nio.file.FileSystem;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import org.eclipse.jetty.util.URIUtil;
|
||||
|
||||
|
@ -26,6 +28,14 @@ import org.eclipse.jetty.util.URIUtil;
|
|||
*/
|
||||
public class MountedPathResource extends PathResource
|
||||
{
|
||||
public static MountedPathResource of(URI uri) throws IOException
|
||||
{
|
||||
Path path = Paths.get(uri.normalize());
|
||||
if (!Files.exists(path))
|
||||
return null;
|
||||
return new MountedPathResource(path, uri);
|
||||
}
|
||||
|
||||
private final URI containerUri;
|
||||
|
||||
MountedPathResource(URI uri) throws IOException
|
||||
|
@ -34,6 +44,18 @@ public class MountedPathResource extends PathResource
|
|||
containerUri = URIUtil.unwrapContainer(getURI());
|
||||
}
|
||||
|
||||
MountedPathResource(Path path, URI uri)
|
||||
{
|
||||
super(path, uri, true);
|
||||
containerUri = URIUtil.unwrapContainer(getURI());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Resource newResource(Path path, URI uri)
|
||||
{
|
||||
return new MountedPathResource(path, uri);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isContainedIn(Resource r)
|
||||
{
|
||||
|
|
|
@ -18,11 +18,14 @@ import java.net.URI;
|
|||
import java.nio.file.DirectoryIteratorException;
|
||||
import java.nio.file.FileVisitResult;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.LinkOption;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.SimpleFileVisitor;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
import java.nio.file.attribute.FileTime;
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
@ -47,6 +50,14 @@ public class PathResource extends Resource
|
|||
.with("jrt")
|
||||
.build();
|
||||
|
||||
public static PathResource of(URI uri) throws IOException
|
||||
{
|
||||
Path path = Paths.get(uri.normalize());
|
||||
if (!Files.exists(path))
|
||||
return null;
|
||||
return new PathResource(path, uri, false);
|
||||
}
|
||||
|
||||
// The path object represented by this instance
|
||||
private final Path path;
|
||||
// The as-requested URI for this path object
|
||||
|
@ -262,6 +273,95 @@ public class PathResource extends Resource
|
|||
return this.uri;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Resource resolve(String subUriPath)
|
||||
{
|
||||
// Check that the path is within the root,
|
||||
// but use the original path to create the
|
||||
// resource, to preserve aliasing.
|
||||
if (URIUtil.isNotNormalWithinSelf(subUriPath))
|
||||
throw new IllegalArgumentException(subUriPath);
|
||||
|
||||
if (URIUtil.SLASH.equals(subUriPath))
|
||||
return this;
|
||||
|
||||
// Sub-paths are always resolved under the given URI,
|
||||
// we compensate for input sub-paths like "/subdir"
|
||||
// where default resolve behavior would be to treat
|
||||
// that like an absolute path.
|
||||
while (subUriPath.startsWith(URIUtil.SLASH))
|
||||
{
|
||||
// TODO XXX this appears entirely unnecessary and inefficient. We already have utilities
|
||||
// to handle appending path strings with/without slashes.
|
||||
subUriPath = subUriPath.substring(1);
|
||||
}
|
||||
|
||||
URI uri = getURI();
|
||||
URI resolvedUri = URIUtil.addPath(uri, subUriPath);
|
||||
Path path = Paths.get(resolvedUri);
|
||||
if (Files.exists(path))
|
||||
return newResource(path, resolvedUri);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal override for creating a new PathResource.
|
||||
* Used by MountedPathResource (eg)
|
||||
*/
|
||||
protected Resource newResource(Path path, URI uri)
|
||||
{
|
||||
return new PathResource(path, uri, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDirectory()
|
||||
{
|
||||
return Files.isDirectory(getPath(), LinkOption.NOFOLLOW_LINKS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReadable()
|
||||
{
|
||||
return Files.isReadable(getPath());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Instant lastModified()
|
||||
{
|
||||
Path path = getPath();
|
||||
if (path == null)
|
||||
return Instant.EPOCH;
|
||||
|
||||
if (!Files.exists(path))
|
||||
return Instant.EPOCH;
|
||||
|
||||
try
|
||||
{
|
||||
FileTime ft = Files.getLastModifiedTime(path, LinkOption.NOFOLLOW_LINKS);
|
||||
return ft.toInstant();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
LOG.trace("IGNORED", e);
|
||||
return Instant.EPOCH;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long length()
|
||||
{
|
||||
try
|
||||
{
|
||||
return Files.size(getPath());
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
// in case of error, use Files.size() logic of 0L
|
||||
return 0L;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isContainedIn(Resource r)
|
||||
{
|
||||
|
|
|
@ -26,7 +26,6 @@ import java.nio.file.Paths;
|
|||
import java.nio.file.ProviderNotFoundException;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.nio.file.attribute.FileTime;
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
@ -87,9 +86,9 @@ public abstract class Resource implements Iterable<Resource>
|
|||
|
||||
// If the scheme is allowed by PathResource, we can build a non-mounted PathResource.
|
||||
if (PathResource.ALLOWED_SCHEMES.contains(uri.getScheme()))
|
||||
return new PathResource(uri);
|
||||
return PathResource.of(uri);
|
||||
|
||||
return new MountedPathResource(uri);
|
||||
return MountedPathResource.of(uri);
|
||||
}
|
||||
catch (URISyntaxException | ProviderNotFoundException | IOException ex)
|
||||
{
|
||||
|
@ -140,69 +139,43 @@ public abstract class Resource implements Iterable<Resource>
|
|||
}
|
||||
|
||||
/**
|
||||
* Equivalent to {@link Files#isDirectory(Path, LinkOption...)} with the following parameter:
|
||||
* {@link #getPath()}.
|
||||
* Return true if resource represents a directory of potential resources.
|
||||
*
|
||||
* @return true if the represented resource is a container/directory.
|
||||
*/
|
||||
public boolean isDirectory()
|
||||
{
|
||||
return Files.isDirectory(getPath(), FOLLOW_LINKS);
|
||||
}
|
||||
public abstract boolean isDirectory();
|
||||
|
||||
/**
|
||||
* True if the resource is readable.
|
||||
*
|
||||
* @return true if the represented resource exists, and can read from.
|
||||
*/
|
||||
public abstract boolean isReadable();
|
||||
|
||||
/**
|
||||
* The time the resource was last modified.
|
||||
*
|
||||
* Equivalent to {@link Files#getLastModifiedTime(Path, LinkOption...)} with the following parameter:
|
||||
* {@link #getPath()} then returning {@link FileTime#toInstant()}.
|
||||
*
|
||||
* @return the last modified time instant, or {@link Instant#EPOCH} if unable to obtain last modified.
|
||||
*/
|
||||
public Instant lastModified()
|
||||
{
|
||||
Path path = getPath();
|
||||
if (path == null)
|
||||
return Instant.EPOCH;
|
||||
|
||||
if (!Files.exists(path))
|
||||
return Instant.EPOCH;
|
||||
|
||||
try
|
||||
{
|
||||
FileTime ft = Files.getLastModifiedTime(path, FOLLOW_LINKS);
|
||||
return ft.toInstant();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
LOG.trace("IGNORED", e);
|
||||
return Instant.EPOCH;
|
||||
}
|
||||
return Instant.EPOCH;
|
||||
}
|
||||
|
||||
/**
|
||||
* Length of the resource.
|
||||
* Equivalent to {@link Files#size(Path)} with the following parameter:
|
||||
* {@link #getPath()}.
|
||||
*
|
||||
* @return the length of the resource or 0 if {@link Files#size(Path)} throws {@link IOException}.
|
||||
* @return the length of the resource in bytes, or -1L if unable to provide a size (such as a directory resource).
|
||||
*/
|
||||
public long length()
|
||||
{
|
||||
try
|
||||
{
|
||||
return Files.size(getPath());
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
// in case of error, use File.length logic of 0L
|
||||
return 0L;
|
||||
}
|
||||
return -1L;
|
||||
}
|
||||
|
||||
/**
|
||||
* URI representing the resource.
|
||||
*
|
||||
* @return an URI representing the given resource
|
||||
* @return a URI representing the given resource
|
||||
*/
|
||||
public abstract URI getURI();
|
||||
|
||||
|
@ -258,39 +231,13 @@ public abstract class Resource implements Iterable<Resource>
|
|||
}
|
||||
|
||||
/**
|
||||
* Resolve a new Resource from an encoded subUriPath.
|
||||
* Resolve an existing Resource.
|
||||
*
|
||||
* @param subUriPath the encoded subUriPath
|
||||
* @return a Resource representing the subUriPath
|
||||
* @return an existing Resource representing the requested subUriPath, or null if resource does not exist.
|
||||
* @throws IllegalArgumentException if subUriPath is invalid
|
||||
*/
|
||||
public Resource resolve(String subUriPath)
|
||||
{
|
||||
// Check that the path is within the root,
|
||||
// but use the original path to create the
|
||||
// resource, to preserve aliasing.
|
||||
// TODO do a URI safe encoding?
|
||||
if (URIUtil.isNotNormalWithinSelf(subUriPath))
|
||||
throw new IllegalArgumentException(subUriPath);
|
||||
|
||||
if (URIUtil.SLASH.equals(subUriPath))
|
||||
return this;
|
||||
|
||||
// Sub-paths are always resolved under the given URI,
|
||||
// we compensate for input sub-paths like "/subdir"
|
||||
// where default resolve behavior would be to treat
|
||||
// that like an absolute path.
|
||||
while (subUriPath.startsWith(URIUtil.SLASH))
|
||||
{
|
||||
// TODO XXX this appears entirely unnecessary and inefficient. We already have utilities
|
||||
// to handle appending path strings with/without slashes.
|
||||
subUriPath = subUriPath.substring(1);
|
||||
}
|
||||
|
||||
URI uri = getURI();
|
||||
URI resolvedUri = URIUtil.addPath(uri, subUriPath);
|
||||
return create(resolvedUri);
|
||||
}
|
||||
public abstract Resource resolve(String subUriPath);
|
||||
|
||||
/**
|
||||
* @return true if this Resource is an alias to another real Resource
|
||||
|
|
|
@ -104,13 +104,13 @@ public class ResourceCollection extends Resource
|
|||
/**
|
||||
* Resolves a path against the resource collection.
|
||||
*
|
||||
* @param subUriPath The path segment to add
|
||||
* @return The resulting resource(s) :
|
||||
* @param subUriPath The path segment to resolve
|
||||
* @return The resulting resource :
|
||||
* <ul>
|
||||
* <li>is a file that exists in at least one of the collection, then the first one found is returned</li>
|
||||
* <li>is a directory that exists in at exactly one of the collection, then that directory resource is returned </li>
|
||||
* <li>is a directory that exists in at exactly one of the collection, then that simple directory resource is returned</li>
|
||||
* <li>is a directory that exists in several of the collection, then a ResourceCollection of those directories is returned</li>
|
||||
* <li>do not exist in any of the collection, then a new non existent resource relative to the first in the collection is returned.</li>
|
||||
* <li>is null if not found in any entry in this collection</li>
|
||||
* </ul>
|
||||
*/
|
||||
@Override
|
||||
|
@ -131,8 +131,8 @@ public class ResourceCollection extends Resource
|
|||
for (Resource res : _resources)
|
||||
{
|
||||
addedResource = res.resolve(subUriPath);
|
||||
if (!addedResource.exists())
|
||||
continue;
|
||||
if (Resources.missing(addedResource))
|
||||
continue; // skip, doesn't exist
|
||||
if (!addedResource.isDirectory())
|
||||
return addedResource; // Return simple (non-directory) Resource
|
||||
if (resources == null)
|
||||
|
@ -257,6 +257,17 @@ public class ResourceCollection extends Resource
|
|||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReadable()
|
||||
{
|
||||
for (Resource r : _resources)
|
||||
{
|
||||
if (r.isReadable())
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Instant lastModified()
|
||||
{
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
|
||||
//
|
||||
// This program and the accompanying materials are made available under the
|
||||
// terms of the Eclipse Public License v. 2.0 which is available at
|
||||
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
|
||||
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
|
||||
//
|
||||
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.util.resource;
|
||||
|
||||
/**
|
||||
* Collection of helpful static methods for working with {@link Resource} objects.
|
||||
*/
|
||||
public final class Resources
|
||||
{
|
||||
/**
|
||||
* True if the resource exists.
|
||||
*
|
||||
* @param resource the resource to test
|
||||
* @return true if resource is non-null and exists
|
||||
* @see Resource#exists()
|
||||
*/
|
||||
public static boolean exists(Resource resource)
|
||||
{
|
||||
return resource != null && resource.exists();
|
||||
}
|
||||
|
||||
/**
|
||||
* True if the resource is missing.
|
||||
*
|
||||
* @param resource the resource to test
|
||||
* @return true if resource is null or doesn't exist
|
||||
* @see Resource#exists()
|
||||
*/
|
||||
public static boolean missing(Resource resource)
|
||||
{
|
||||
return resource == null || !resource.exists();
|
||||
}
|
||||
|
||||
/**
|
||||
* True if resource is a valid directory.
|
||||
*
|
||||
* @param resource the resource to test
|
||||
* @return true if resource is non-null, exists, and is a directory
|
||||
* @see Resource#exists()
|
||||
* @see Resource#isDirectory()
|
||||
*/
|
||||
public static boolean isDirectory(Resource resource)
|
||||
{
|
||||
return resource != null && resource.isDirectory();
|
||||
}
|
||||
|
||||
/**
|
||||
* True if resource is readable.
|
||||
*
|
||||
* @param resource the resource to test
|
||||
* @return true if resource is non-null, exists, and is readable
|
||||
* @see Resource#exists()
|
||||
* @see Resource#isReadable()
|
||||
*/
|
||||
public static boolean isReadable(Resource resource)
|
||||
{
|
||||
return resource != null && resource.isReadable();
|
||||
}
|
||||
|
||||
/**
|
||||
* True if resource is a valid directory that can be read from.
|
||||
*
|
||||
* @param resource the resource to test
|
||||
* @return true if resource is non-null, exists, and is a directory
|
||||
* @see Resource#exists()
|
||||
* @see Resource#isDirectory()
|
||||
*/
|
||||
public static boolean isReadableDirectory(Resource resource)
|
||||
{
|
||||
return resource != null && resource.isDirectory() && resource.isReadable();
|
||||
}
|
||||
|
||||
/**
|
||||
* True if resource exists, is not a directory, is readable.
|
||||
*
|
||||
* @param resource the resource to test
|
||||
* @return true if resource exists, is not a directory, is
|
||||
*/
|
||||
public static boolean isReadableFile(Resource resource)
|
||||
{
|
||||
return resource != null && !resource.isDirectory() && resource.isReadable();
|
||||
}
|
||||
}
|
|
@ -82,6 +82,7 @@ import org.eclipse.jetty.util.component.ContainerLifeCycle;
|
|||
import org.eclipse.jetty.util.component.Dumpable;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.eclipse.jetty.util.resource.ResourceFactory;
|
||||
import org.eclipse.jetty.util.resource.Resources;
|
||||
import org.eclipse.jetty.util.security.CertificateUtils;
|
||||
import org.eclipse.jetty.util.security.CertificateValidator;
|
||||
import org.eclipse.jetty.util.security.Password;
|
||||
|
@ -640,10 +641,10 @@ public abstract class SslContextFactory extends ContainerLifeCycle implements Du
|
|||
}
|
||||
|
||||
Resource res = ResourceFactory.of(this).newResource(keyStorePath);
|
||||
if (!res.exists())
|
||||
if (!Resources.isReadableFile(res))
|
||||
{
|
||||
_keyStoreResource = null;
|
||||
throw new IllegalArgumentException("KeyStore Path does not exist: " + keyStorePath);
|
||||
throw new IllegalArgumentException("KeyStore Path not accessible: " + keyStorePath);
|
||||
}
|
||||
_keyStoreResource = res;
|
||||
}
|
||||
|
@ -724,10 +725,10 @@ public abstract class SslContextFactory extends ContainerLifeCycle implements Du
|
|||
}
|
||||
|
||||
Resource res = ResourceFactory.of(this).newResource(trustStorePath);
|
||||
if (!res.exists())
|
||||
if (!Resources.isReadableFile(res))
|
||||
{
|
||||
_trustStoreResource = null;
|
||||
throw new IllegalArgumentException("TrustStore Path does not exist: " + trustStorePath);
|
||||
throw new IllegalArgumentException("TrustStore Path not accessible: " + trustStorePath);
|
||||
}
|
||||
_trustStoreResource = res;
|
||||
}
|
||||
|
|
|
@ -166,7 +166,7 @@ public class FileSystemResourceTest
|
|||
{
|
||||
// Doesn't exist.
|
||||
Resource resource = ResourceFactory.root().newResource(new URI("path/to/resource"));
|
||||
assertFalse(resource.exists());
|
||||
assertTrue(Resources.missing(resource));
|
||||
|
||||
// Create a directory
|
||||
Path testdir = workDir.getEmptyPathDir().resolve("path/to/resource");
|
||||
|
@ -229,7 +229,7 @@ public class FileSystemResourceTest
|
|||
assertThat("sub/.isDirectory", sub.isDirectory(), is(true));
|
||||
|
||||
Resource tmp = sub.resolve("/tmp");
|
||||
assertThat("No root", tmp.exists(), is(false));
|
||||
assertTrue(Resources.missing(tmp), "Reference to root not allowed");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -245,7 +245,7 @@ public class FileSystemResourceTest
|
|||
assertThat("sub.isDirectory", sub.isDirectory(), is(true));
|
||||
|
||||
Resource tmp = sub.resolve("/tmp");
|
||||
assertThat("No root", tmp.exists(), is(false));
|
||||
assertTrue(Resources.missing(tmp), "Reference to root not allowed");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -266,7 +266,7 @@ public class FileSystemResourceTest
|
|||
{
|
||||
Resource rrd = sub.resolve(readableRootDir);
|
||||
// we are executing on unix and OSX
|
||||
assertThat("Readable Root Dir", rrd.exists(), is(false));
|
||||
assertTrue(Resources.missing(rrd), "Readable Root Dir");
|
||||
}
|
||||
catch (InvalidPathException e)
|
||||
{
|
||||
|
@ -398,16 +398,6 @@ public class FileSystemResourceTest
|
|||
assertThat("foo.lastModified", res.lastModified(), is(expected));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLastModifiedNotExists()
|
||||
{
|
||||
Path dir = workDir.getEmptyPathDir();
|
||||
|
||||
Resource base = ResourceFactory.root().newResource(dir);
|
||||
Resource res = base.resolve("foo");
|
||||
assertThat("foo.lastModified", res.lastModified(), is(Instant.EPOCH));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLength() throws Exception
|
||||
{
|
||||
|
@ -424,17 +414,6 @@ public class FileSystemResourceTest
|
|||
assertThat("foo.length", res.length(), is(expected));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLengthNotExists() throws Exception
|
||||
{
|
||||
Path dir = workDir.getEmptyPathDir();
|
||||
Files.createDirectories(dir);
|
||||
|
||||
Resource base = ResourceFactory.root().newResource(dir);
|
||||
Resource res = base.resolve("foo");
|
||||
assertThat("foo.length", res.length(), is(0L));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDelete() throws Exception
|
||||
{
|
||||
|
@ -453,22 +432,6 @@ public class FileSystemResourceTest
|
|||
assertThat("foo.exists", res.exists(), is(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteNotExists() throws Exception
|
||||
{
|
||||
Path dir = workDir.getEmptyPathDir();
|
||||
Files.createDirectories(dir);
|
||||
|
||||
Resource base = ResourceFactory.root().newResource(dir);
|
||||
// Is it there?
|
||||
Resource res = base.resolve("foo");
|
||||
assertThat("foo.exists", res.exists(), is(false));
|
||||
// delete it
|
||||
Files.deleteIfExists(res.getPath());
|
||||
// is it there?
|
||||
assertThat("foo.exists", res.exists(), is(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testName() throws Exception
|
||||
{
|
||||
|
@ -623,13 +586,13 @@ public class FileSystemResourceTest
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testNonExistantSymlink() throws Exception
|
||||
public void testNonExistentSymlink() throws Exception
|
||||
{
|
||||
Path dir = workDir.getEmptyPathDir();
|
||||
Files.createDirectories(dir);
|
||||
|
||||
Path foo = dir.resolve("foo");
|
||||
Path bar = dir.resolve("bar");
|
||||
Path foo = dir.resolve("foo"); // does not exist
|
||||
Path bar = dir.resolve("bar"); // to become a link to "foo"
|
||||
|
||||
boolean symlinkSupported;
|
||||
try
|
||||
|
@ -649,25 +612,8 @@ public class FileSystemResourceTest
|
|||
Resource resFoo = base.resolve("foo");
|
||||
Resource resBar = base.resolve("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));
|
||||
|
||||
// This is not an alias because the file does not exist.
|
||||
assertFalse(resFoo.exists());
|
||||
assertFalse(Files.exists(resFoo.getPath()));
|
||||
assertFalse(resFoo.isAlias());
|
||||
assertNotNull(resFoo.getURI());
|
||||
assertNull(resFoo.getRealURI());
|
||||
|
||||
// This is alias because the target file does not exist even though the symlink file does exist.
|
||||
// This resource cannot be served, so it should not exist, nor have an alias
|
||||
assertFalse(resBar.exists());
|
||||
assertFalse(Files.exists(resBar.getPath()));
|
||||
assertFalse(resBar.isAlias());
|
||||
assertNotNull(resBar.getURI());
|
||||
assertNull(resBar.getRealURI());
|
||||
assertTrue(Resources.missing(resFoo), "resFoo");
|
||||
assertTrue(Resources.missing(resBar), "resBar");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -689,7 +635,7 @@ public class FileSystemResourceTest
|
|||
// On some case-insensitive file systems, lets see if an alternate
|
||||
// case for the filename results in an alias reference
|
||||
Resource alias = base.resolve("FILE");
|
||||
if (alias.exists())
|
||||
if (Resources.exists(alias))
|
||||
{
|
||||
// If it exists, it must be an alias
|
||||
assertThat("targetURI", alias, isRealResourceFor(resource));
|
||||
|
@ -1188,11 +1134,11 @@ public class FileSystemResourceTest
|
|||
assertThat("Target URI: " + basePath, base, isNotAlias());
|
||||
|
||||
Resource r = base.resolve("aa%5C/foo.txt");
|
||||
assertThat("getURI()", r.getURI().toASCIIString(), containsString("aa%5C/foo.txt"));
|
||||
|
||||
if (WINDOWS.isCurrentOs())
|
||||
{
|
||||
assertThat("getPath().toString()", r.getPath().toString(), containsString("aa\\foo.txt"));
|
||||
assertThat("getURI()", r.getPath().toString(), containsString("aa\\/foo.txt"));
|
||||
assertThat("getURI()", r.getURI().toASCIIString(), containsString("aa%5C/foo.txt"));
|
||||
assertThat("isAlias()", r.isAlias(), is(true));
|
||||
assertThat("getRealURI()", r.getRealURI(), notNullValue());
|
||||
assertThat("getRealURI()", r.getRealURI().toASCIIString(), containsString("aa/foo.txt"));
|
||||
|
@ -1200,9 +1146,7 @@ public class FileSystemResourceTest
|
|||
}
|
||||
else
|
||||
{
|
||||
assertThat("getPath().toString()", r.getPath().toString(), containsString("aa\\/foo.txt"));
|
||||
assertThat("isAlias()", r.isAlias(), is(false));
|
||||
assertThat("Exists: " + r, r.exists(), is(false));
|
||||
assertTrue(Resources.missing(r), "Backslash resource");
|
||||
}
|
||||
}
|
||||
catch (IllegalArgumentException e)
|
||||
|
@ -1232,10 +1176,10 @@ public class FileSystemResourceTest
|
|||
assertThat("Is Not Alias: " + basePath, base, isNotAlias());
|
||||
|
||||
Resource r = base.resolve("aa./foo.txt");
|
||||
assertThat("getURI()", r.getURI().toASCIIString(), containsString("aa./foo.txt"));
|
||||
|
||||
if (WINDOWS.isCurrentOs())
|
||||
{
|
||||
assertThat("getURI()", r.getURI().toASCIIString(), containsString("aa./foo.txt"));
|
||||
assertThat("isAlias()", r.isAlias(), is(true));
|
||||
assertThat("getRealURI()", r.getRealURI(), notNullValue());
|
||||
assertThat("getRealURI()", r.getRealURI().toASCIIString(), containsString("aa/foo.txt"));
|
||||
|
@ -1243,8 +1187,7 @@ public class FileSystemResourceTest
|
|||
}
|
||||
else
|
||||
{
|
||||
assertThat("isAlias()", r.isAlias(), is(false));
|
||||
assertThat("Exists: " + r, r.exists(), is(false));
|
||||
assertTrue(Resources.missing(r), "extension-less directory reference");
|
||||
}
|
||||
}
|
||||
catch (IllegalArgumentException e)
|
||||
|
|
|
@ -165,9 +165,7 @@ public class PathResourceTest
|
|||
|
||||
// Resolve to name, but different case
|
||||
testText = archiveResource.resolve("/TEST.TXT");
|
||||
assertFalse(testText.exists());
|
||||
assertThat("Resource.getName", testText.getName(), is("/TEST.TXT"));
|
||||
assertThat("Resource.getFileName", testText.getFileName(), is("TEST.TXT"));
|
||||
assertNull(testText);
|
||||
|
||||
// Resolve using path navigation
|
||||
testText = archiveResource.resolve("/foo/../test.txt");
|
||||
|
@ -224,9 +222,9 @@ public class PathResourceTest
|
|||
|
||||
// Resolve file to name, but different case
|
||||
testText = archiveResource.resolve("/dir/TEST.TXT");
|
||||
assertFalse(testText.exists());
|
||||
assertNull(testText);
|
||||
testText = archiveResource.resolve("/DIR/test.txt");
|
||||
assertFalse(testText.exists());
|
||||
assertNull(testText);
|
||||
|
||||
// Resolve file using path navigation
|
||||
testText = archiveResource.resolve("/foo/../dir/test.txt");
|
||||
|
@ -240,8 +238,7 @@ public class PathResourceTest
|
|||
|
||||
// Resolve file using extension-less directory
|
||||
testText = archiveResource.resolve("/dir./test.txt");
|
||||
assertFalse(testText.exists());
|
||||
assertFalse(testText.isAlias());
|
||||
assertNull(testText);
|
||||
|
||||
// Resolve directory to name, no slash
|
||||
Resource dirResource = archiveResource.resolve("/dir");
|
||||
|
@ -471,7 +468,7 @@ public class PathResourceTest
|
|||
Resource rootRes = resourceFactory.newResource(docroot);
|
||||
// Test navigation through a directory that doesn't exist
|
||||
Resource fileResViaBar = rootRes.resolve("bar/../dir/test.txt");
|
||||
assertFalse(fileResViaBar.exists());
|
||||
assertTrue(Resources.missing(fileResViaBar));
|
||||
|
||||
// Test navigation through a directory that does exist
|
||||
Resource fileResViaFoo = rootRes.resolve("foo/../dir/test.txt");
|
||||
|
|
|
@ -76,12 +76,7 @@ public class ResourceAliasTest
|
|||
Resource rootRes = resourceFactory.newResource(docroot);
|
||||
// Test navigation through a directory that doesn't exist
|
||||
Resource fileResViaBar = rootRes.resolve("bar/../dir/test.txt");
|
||||
assertFalse(fileResViaBar.exists(), "Should not exist");
|
||||
assertFalse(fileResViaBar.isAlias(), "Should not be an alias");
|
||||
|
||||
Files.createDirectory(docroot.resolve("bar"));
|
||||
assertTrue(fileResViaBar.exists(), "Should exist");
|
||||
assertTrue(fileResViaBar.isAlias(), "Should be an alias");
|
||||
assertTrue(Resources.missing(fileResViaBar), "File doesn't exist");
|
||||
|
||||
// Test navigation through a directory that does exist
|
||||
Resource fileResViaFoo = rootRes.resolve("foo/../dir/test.txt");
|
||||
|
|
|
@ -48,6 +48,7 @@ import static org.hamcrest.Matchers.instanceOf;
|
|||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
@ExtendWith(WorkDirExtension.class)
|
||||
|
@ -111,7 +112,8 @@ public class ResourceCollectionTest
|
|||
|
||||
assertThat(listingFilenames, containsInAnyOrder(expected));
|
||||
|
||||
assertThat(rc.resolve("unknown").list(), is(empty()));
|
||||
Resource unk = rc.resolve("unknown");
|
||||
assertNull(unk);
|
||||
|
||||
assertEquals(getContent(rc, "1.txt"), "1 - one");
|
||||
assertEquals(getContent(rc, "2.txt"), "2 - two");
|
||||
|
|
|
@ -33,6 +33,7 @@ import org.eclipse.jetty.toolchain.test.jupiter.WorkDirExtension;
|
|||
import org.eclipse.jetty.util.IO;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.Assumptions;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.condition.EnabledOnOs;
|
||||
import org.junit.jupiter.api.condition.OS;
|
||||
|
@ -49,6 +50,7 @@ import static org.hamcrest.Matchers.startsWith;
|
|||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.junit.jupiter.api.Assumptions.assumeFalse;
|
||||
|
@ -257,12 +259,16 @@ public class ResourceTest
|
|||
|
||||
public WorkDir workDir;
|
||||
|
||||
@Disabled
|
||||
@ParameterizedTest
|
||||
@MethodSource("scenarios")
|
||||
public void testResourceExists(Scenario data)
|
||||
{
|
||||
Resource res = data.getResource();
|
||||
assertThat("Exists: " + res.getName(), res.exists(), equalTo(data.exists));
|
||||
if (data.exists)
|
||||
assertThat("Exists: " + res.getName(), res.exists(), equalTo(data.exists));
|
||||
else
|
||||
assertNull(res);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
|
@ -362,14 +368,37 @@ public class ResourceTest
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testClimbAboveBase()
|
||||
public void testClimbAboveBase(WorkDir workDir)
|
||||
{
|
||||
Resource resource = resourceFactory.newResource("/foo/bar");
|
||||
Path testdir = workDir.getEmptyPathDir().resolve("foo/bar");
|
||||
FS.ensureDirExists(testdir);
|
||||
Resource resource = resourceFactory.newResource(testdir);
|
||||
assertThrows(IllegalArgumentException.class, () -> resource.resolve(".."));
|
||||
assertThrows(IllegalArgumentException.class, () -> resource.resolve("./.."));
|
||||
assertThrows(IllegalArgumentException.class, () -> resource.resolve("./../bar"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNewResourcePathDoesNotExist(WorkDir workDir)
|
||||
{
|
||||
Path dir = workDir.getEmptyPathDir().resolve("foo/bar");
|
||||
// at this point we have a directory reference that does not exist
|
||||
Resource resource = resourceFactory.newResource(dir);
|
||||
assertNull(resource);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNewResourceFileDoesNotExists(WorkDir workDir) throws IOException
|
||||
{
|
||||
Path dir = workDir.getEmptyPathDir().resolve("foo");
|
||||
FS.ensureDirExists(dir);
|
||||
Path file = dir.resolve("bar.txt");
|
||||
// at this point we have a file reference that does not exist
|
||||
assertFalse(Files.exists(file));
|
||||
Resource resource = resourceFactory.newResource(file);
|
||||
assertNull(resource);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDotAliasDirExists(WorkDir workDir) throws IOException
|
||||
{
|
||||
|
@ -383,18 +412,6 @@ public class ResourceTest
|
|||
assertTrue(Files.isSameFile(dot.getPath(), Paths.get(dot.getRealURI())));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDotAliasDirDoesNotExist(WorkDir workDir)
|
||||
{
|
||||
Path dir = workDir.getEmptyPathDir().resolve("foo/bar");
|
||||
// at this point we have a directory reference that does not exist
|
||||
Resource resource = resourceFactory.newResource(dir);
|
||||
Resource dot = resource.resolve(".");
|
||||
assertNotNull(dot);
|
||||
assertFalse(dot.exists());
|
||||
assertFalse(dot.isAlias(), "Reference to '.' is not an alias as directory doesn't exist");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDotAliasFileExists(WorkDir workDir) throws IOException
|
||||
{
|
||||
|
@ -404,27 +421,9 @@ public class ResourceTest
|
|||
FS.touch(file);
|
||||
assertTrue(Files.exists(file));
|
||||
Resource resource = resourceFactory.newResource(file);
|
||||
// Requesting a resource that would point to a location called ".../testDotAliasFileExists/foo/bar.txt/."
|
||||
Resource dot = resource.resolve(".");
|
||||
// We are now pointing to a resource at ".../testDotAliasFileExists/foo/bar.txt/."
|
||||
assertNotNull(dot);
|
||||
assertFalse(dot.exists());
|
||||
assertFalse(dot.isAlias(), "Reference to '.' against a file is not an alias");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDotAliasFileDoesNotExists(WorkDir workDir) throws IOException
|
||||
{
|
||||
Path dir = workDir.getEmptyPathDir().resolve("foo");
|
||||
FS.ensureDirExists(dir);
|
||||
Path file = dir.resolve("bar.txt");
|
||||
// at this point we have a file reference that does not exist
|
||||
assertFalse(Files.exists(file));
|
||||
Resource resource = resourceFactory.newResource(file);
|
||||
Resource dot = resource.resolve(".");
|
||||
// We are now pointing to a resource at ".../testDotAliasFileDoesNotExists/foo/bar.txt/."
|
||||
assertNotNull(dot);
|
||||
assertFalse(dot.exists());
|
||||
assertFalse(dot.isAlias(), "Reference to '.' against a file is not an alias (the file also does not exist)");
|
||||
assertTrue(Resources.missing(dot), "Cannot reference file as a directory");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -258,7 +258,7 @@ public class SslContextFactoryTest
|
|||
cf.setTrustStorePath("/foo");
|
||||
cf.start();
|
||||
});
|
||||
assertThat(x.getMessage(), containsString("TrustStore Path does not exist: /foo"));
|
||||
assertThat(x.getMessage(), containsString("TrustStore Path not accessible: /foo"));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ import org.apache.maven.plugin.MojoExecutionException;
|
|||
import org.apache.maven.plugin.MojoFailureException;
|
||||
import org.apache.maven.plugins.annotations.Parameter;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.eclipse.jetty.util.resource.Resources;
|
||||
|
||||
/**
|
||||
* Base class for all goals that operate on unassembled webapps.
|
||||
|
@ -176,7 +177,7 @@ public abstract class AbstractUnassembledWebAppMojo extends AbstractWebAppMojo
|
|||
if (webXml != null)
|
||||
{
|
||||
Resource r = webApp.getResourceFactory().newResource(webXml.toPath());
|
||||
if (r.exists() && !r.isDirectory())
|
||||
if (Resources.isReadableFile(r))
|
||||
{
|
||||
webApp.setDescriptor(r.getURI().toASCIIString());
|
||||
}
|
||||
|
@ -188,7 +189,7 @@ public abstract class AbstractUnassembledWebAppMojo extends AbstractWebAppMojo
|
|||
// TODO: should never return from WEB-INF/lib/foo.jar!/WEB-INF/web.xml
|
||||
// TODO: should also never return from a META-INF/versions/#/WEB-INF/web.xml location
|
||||
Resource r = webApp.getBaseResource().resolve("WEB-INF/web.xml");
|
||||
if (r.exists() && !r.isDirectory())
|
||||
if (Resources.isReadableFile(r))
|
||||
{
|
||||
webApp.setDescriptor(r.getURI().toASCIIString());
|
||||
}
|
||||
|
|
|
@ -41,6 +41,7 @@ import org.eclipse.jetty.util.StringUtil;
|
|||
import org.eclipse.jetty.util.URIUtil;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.eclipse.jetty.util.resource.ResourceCollection;
|
||||
import org.eclipse.jetty.util.resource.Resources;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -391,11 +392,11 @@ public class MavenWebAppContext extends WebAppContext
|
|||
// try matching
|
||||
Resource res = null;
|
||||
int i = 0;
|
||||
while (res == null && (i < _webInfClasses.size()))
|
||||
while (Resources.missing(res) && (i < _webInfClasses.size()))
|
||||
{
|
||||
String newPath = StringUtil.replace(uri, WEB_INF_CLASSES_PREFIX, _webInfClasses.get(i).getPath());
|
||||
res = this.getResourceFactory().newResource(newPath);
|
||||
if (!res.exists())
|
||||
if (Resources.missing(res))
|
||||
{
|
||||
res = null;
|
||||
i++;
|
||||
|
|
|
@ -21,6 +21,7 @@ import java.net.URL;
|
|||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.attribute.FileTime;
|
||||
import java.time.Instant;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
@ -112,6 +113,24 @@ public class SelectiveJarResource extends Resource
|
|||
return _delegate.getPath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDirectory()
|
||||
{
|
||||
return _delegate.isDirectory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Instant lastModified()
|
||||
{
|
||||
return _delegate.lastModified();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReadable()
|
||||
{
|
||||
return _delegate.isReadable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isContainedIn(Resource r)
|
||||
{
|
||||
|
@ -136,6 +155,12 @@ public class SelectiveJarResource extends Resource
|
|||
return _delegate.getFileName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Resource resolve(String subUriPath)
|
||||
{
|
||||
return _delegate.resolve(subUriPath);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void copyTo(Path directory) throws IOException
|
||||
{
|
||||
|
|
|
@ -42,6 +42,7 @@ import org.eclipse.jetty.jndi.local.localContextRoot;
|
|||
import org.eclipse.jetty.util.IO;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.eclipse.jetty.util.resource.ResourceFactory;
|
||||
import org.eclipse.jetty.util.resource.Resources;
|
||||
import org.eclipse.jetty.xml.XmlConfiguration;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -101,7 +102,7 @@ public class EnvConfiguration extends AbstractConfiguration
|
|||
// TODO: should never return from WEB-INF/lib/foo.jar!/WEB-INF/jetty-env.xml
|
||||
// TODO: should also never return from a META-INF/versions/#/WEB-INF/jetty-env.xml location
|
||||
org.eclipse.jetty.util.resource.Resource jettyEnv = webInf.resolve("jetty-env.xml");
|
||||
if (jettyEnv.exists())
|
||||
if (Resources.exists(jettyEnv))
|
||||
{
|
||||
jettyEnvXmlResource = jettyEnv;
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ import org.eclipse.jetty.util.StringUtil;
|
|||
import org.eclipse.jetty.util.URIUtil;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.eclipse.jetty.util.resource.ResourceFactory;
|
||||
import org.eclipse.jetty.util.resource.Resources;
|
||||
import org.eclipse.jetty.xml.XmlParser;
|
||||
|
||||
/**
|
||||
|
@ -203,10 +204,9 @@ public class QuickStartDescriptorProcessor extends IterativeDescriptorProcessor
|
|||
for (URI uri : uris)
|
||||
{
|
||||
Resource r = _resourceFactory.newResource(uri);
|
||||
if (r.exists())
|
||||
visitMetaInfResource(context, r);
|
||||
else
|
||||
if (Resources.missing(r))
|
||||
throw new IllegalArgumentException("Resource not found: " + r);
|
||||
visitMetaInfResource(context, r);
|
||||
}
|
||||
}
|
||||
default ->
|
||||
|
|
|
@ -56,6 +56,7 @@ import org.eclipse.jetty.util.RolloverFileOutputStream;
|
|||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.eclipse.jetty.util.resource.ResourceFactory;
|
||||
import org.eclipse.jetty.util.resource.Resources;
|
||||
import org.eclipse.jetty.util.security.Constraint;
|
||||
import org.eclipse.jetty.xml.XmlConfiguration;
|
||||
import org.slf4j.Logger;
|
||||
|
@ -109,8 +110,8 @@ public class Runner
|
|||
|
||||
public void addJars(Resource lib)
|
||||
{
|
||||
if (lib == null || !lib.exists() || lib.isDirectory())
|
||||
throw new IllegalStateException("lib is invalid: " + lib);
|
||||
if (!Resources.isReadableFile(lib) || !FileID.isJavaArchive(lib.getURI()))
|
||||
throw new IllegalStateException("Invalid lib: " + lib);
|
||||
|
||||
for (Resource item: lib.list())
|
||||
{
|
||||
|
@ -195,23 +196,27 @@ public class Runner
|
|||
if ("--lib".equals(args[i]))
|
||||
{
|
||||
Resource lib = resourceFactory.newResource(args[++i]);
|
||||
if (!lib.exists() || !lib.isDirectory())
|
||||
usage("No such lib directory " + lib);
|
||||
_classpath.addJars(lib);
|
||||
if (Resources.isReadableDirectory(lib))
|
||||
_classpath.addJars(lib);
|
||||
else
|
||||
usage("Invalid directory: " + lib);
|
||||
}
|
||||
else if ("--jar".equals(args[i]))
|
||||
{
|
||||
Resource jar = resourceFactory.newResource(args[++i]);
|
||||
if (!jar.exists() || jar.isDirectory())
|
||||
usage("No such jar " + jar);
|
||||
_classpath.addPath(jar);
|
||||
if (Resources.isReadableFile(jar) && FileID.isJavaArchive(jar.getURI()))
|
||||
_classpath.addPath(jar);
|
||||
else
|
||||
usage("Invalid JAR: " + jar);
|
||||
|
||||
}
|
||||
else if ("--classes".equals(args[i]))
|
||||
{
|
||||
Resource classes = resourceFactory.newResource(args[++i]);
|
||||
if (!classes.exists() || !classes.isDirectory())
|
||||
usage("No such classes directory " + classes);
|
||||
_classpath.addPath(classes);
|
||||
if (Resources.isReadableDirectory(classes))
|
||||
_classpath.addPath(classes);
|
||||
else
|
||||
usage("Invalid classes directory: " + classes);
|
||||
}
|
||||
else if (args[i].startsWith("--"))
|
||||
i++;
|
||||
|
|
|
@ -74,6 +74,7 @@ import org.eclipse.jetty.util.IO;
|
|||
import org.eclipse.jetty.util.URIUtil;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.eclipse.jetty.util.resource.ResourceFactory;
|
||||
import org.eclipse.jetty.util.resource.Resources;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -182,7 +183,7 @@ public class DefaultServlet extends HttpServlet
|
|||
try
|
||||
{
|
||||
Resource stylesheet = _resourceFactory.newResource(stylesheetParam);
|
||||
if (stylesheet.exists())
|
||||
if (Resources.isReadableFile(stylesheet))
|
||||
{
|
||||
_resourceService.setStylesheet(stylesheet);
|
||||
}
|
||||
|
@ -347,7 +348,7 @@ public class DefaultServlet extends HttpServlet
|
|||
try
|
||||
{
|
||||
HttpContent content = _resourceService.getContent(pathInContext, ServletContextRequest.getServletContextRequest(req));
|
||||
if (content == null || !content.getResource().exists())
|
||||
if (content == null || Resources.missing(content.getResource()))
|
||||
{
|
||||
if (included)
|
||||
{
|
||||
|
@ -965,14 +966,14 @@ public class DefaultServlet extends HttpServlet
|
|||
|
||||
String welcomeServlet = null;
|
||||
Resource base = _baseResource.resolve(requestTarget);
|
||||
if (base != null && base.exists())
|
||||
if (Resources.isReadableDirectory(base))
|
||||
{
|
||||
for (String welcome : welcomes)
|
||||
{
|
||||
Resource welcomePath = base.resolve(welcome);
|
||||
String welcomeInContext = URIUtil.addPaths(coreRequest.getPathInContext(), welcome);
|
||||
|
||||
if (welcomePath != null && welcomePath.exists())
|
||||
if (Resources.isReadableFile(welcomePath))
|
||||
return welcomeInContext;
|
||||
|
||||
if ((_welcomeServlets || _welcomeExactServlets) && welcomeServlet == null)
|
||||
|
|
|
@ -97,6 +97,7 @@ import org.eclipse.jetty.util.component.Graceful;
|
|||
import org.eclipse.jetty.util.component.LifeCycle;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.eclipse.jetty.util.resource.ResourceFactory;
|
||||
import org.eclipse.jetty.util.resource.Resources;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -2927,7 +2928,8 @@ public class ServletContextHandler extends ContextHandler implements Graceful
|
|||
|
||||
for (Resource r: resource)
|
||||
{
|
||||
if (r.exists())
|
||||
// return first
|
||||
if (Resources.exists(r))
|
||||
return r.getURI().toURL();
|
||||
}
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@ import org.eclipse.jetty.util.PathWatcher;
|
|||
import org.eclipse.jetty.util.PathWatcher.PathWatchEvent;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.eclipse.jetty.util.resource.Resources;
|
||||
import org.eclipse.jetty.util.security.Credential;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -159,7 +160,7 @@ public class PropertyUserStore extends UserStore implements PathWatcher.Listener
|
|||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Loading {} from {}", this, config);
|
||||
|
||||
if (!config.exists())
|
||||
if (Resources.missing(config))
|
||||
throw new IllegalStateException("Config does not exist: " + config);
|
||||
|
||||
Properties properties = new Properties();
|
||||
|
|
|
@ -17,6 +17,7 @@ import java.io.IOException;
|
|||
import java.util.Map;
|
||||
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.eclipse.jetty.util.resource.Resources;
|
||||
import org.eclipse.jetty.xml.XmlConfiguration;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -56,14 +57,14 @@ public class JettyWebXmlConfiguration extends AbstractConfiguration
|
|||
// handle any WEB-INF descriptors
|
||||
if (webInf != null && webInf.isDirectory())
|
||||
{
|
||||
// do jetty.xml file
|
||||
// Attempt to load ancient jetty8-web.xml file
|
||||
Resource jetty = webInf.resolve("jetty8-web.xml");
|
||||
if (!jetty.exists())
|
||||
if (Resources.missing(jetty))
|
||||
jetty = webInf.resolve(JETTY_WEB_XML);
|
||||
if (!jetty.exists())
|
||||
if (Resources.missing(jetty))
|
||||
jetty = webInf.resolve("web-jetty.xml");
|
||||
|
||||
if (jetty.exists())
|
||||
if (Resources.isReadableFile(jetty))
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Configure: {}", jetty);
|
||||
|
|
|
@ -45,6 +45,7 @@ import org.eclipse.jetty.util.resource.Resource;
|
|||
import org.eclipse.jetty.util.resource.ResourceCollators;
|
||||
import org.eclipse.jetty.util.resource.ResourceFactory;
|
||||
import org.eclipse.jetty.util.resource.ResourceUriPatternPredicate;
|
||||
import org.eclipse.jetty.util.resource.Resources;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -148,7 +149,7 @@ public class MetaInfConfiguration extends AbstractConfiguration
|
|||
Consumer<URI> addContainerResource = (uri) ->
|
||||
{
|
||||
Resource resource = _resourceFactory.newResource(uri);
|
||||
if (resource == null || !resource.exists())
|
||||
if (Resources.missing(resource))
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Classpath URI doesn't exist: " + uri);
|
||||
|
@ -386,7 +387,7 @@ public class MetaInfConfiguration extends AbstractConfiguration
|
|||
public void scanForResources(WebAppContext context, Resource target, ConcurrentHashMap<Resource, Resource> cache)
|
||||
{
|
||||
// Resource target does not exist
|
||||
if (target == null || !target.exists())
|
||||
if (Resources.missing(target))
|
||||
return;
|
||||
|
||||
Resource resourcesDir = null;
|
||||
|
@ -419,7 +420,7 @@ public class MetaInfConfiguration extends AbstractConfiguration
|
|||
resourcesDir = _resourceFactory.newResource(URIUtil.uriJarPrefix(uri, "!/META-INF/resources"));
|
||||
}
|
||||
|
||||
if (cache != null)
|
||||
if (Resources.isReadableDirectory(resourcesDir) && (cache != null))
|
||||
{
|
||||
Resource old = cache.putIfAbsent(target, resourcesDir);
|
||||
if (old != null)
|
||||
|
@ -449,7 +450,7 @@ public class MetaInfConfiguration extends AbstractConfiguration
|
|||
|
||||
private static boolean isEmptyResource(Resource resourcesDir)
|
||||
{
|
||||
return !resourcesDir.exists() || !resourcesDir.isDirectory();
|
||||
return !Resources.isReadableFile(resourcesDir);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -489,7 +490,7 @@ public class MetaInfConfiguration extends AbstractConfiguration
|
|||
webFrag = _resourceFactory.newResource(URIUtil.uriJarPrefix(uri, "!/META-INF/web-fragment.xml"));
|
||||
}
|
||||
|
||||
if (cache != null)
|
||||
if (Resources.isReadable(webFrag) && (cache != null))
|
||||
{
|
||||
//web-fragment.xml doesn't exist: put token in cache to signal we've seen the jar
|
||||
Resource old = cache.putIfAbsent(jar, webFrag);
|
||||
|
@ -516,7 +517,7 @@ public class MetaInfConfiguration extends AbstractConfiguration
|
|||
|
||||
private static boolean isEmptyFragment(Resource webFrag)
|
||||
{
|
||||
return !webFrag.exists() || webFrag.isDirectory();
|
||||
return !Resources.isReadableFile(webFrag);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -704,7 +705,7 @@ public class MetaInfConfiguration extends AbstractConfiguration
|
|||
|
||||
Resource webInfLib = webInf.resolve("lib");
|
||||
|
||||
if (webInfLib != null && webInfLib.exists() && webInfLib.isDirectory())
|
||||
if (Resources.isReadableDirectory(webInfLib))
|
||||
{
|
||||
return webInfLib.list().stream()
|
||||
.filter((lib) -> FileID.isLibArchive(lib.getFileName()))
|
||||
|
@ -752,11 +753,11 @@ public class MetaInfConfiguration extends AbstractConfiguration
|
|||
|
||||
Resource webInf = context.getWebInf();
|
||||
// Find WEB-INF/classes
|
||||
if (webInf != null && webInf.isDirectory())
|
||||
if (Resources.isReadableDirectory(webInf))
|
||||
{
|
||||
// Look for classes directory
|
||||
Resource webInfClassesDir = webInf.resolve("classes/");
|
||||
if (webInfClassesDir != null && webInfClassesDir.exists() && webInfClassesDir.isDirectory())
|
||||
if (Resources.isReadableDirectory(webInfClassesDir))
|
||||
return webInfClassesDir;
|
||||
}
|
||||
return null;
|
||||
|
|
|
@ -45,6 +45,7 @@ import org.eclipse.jetty.util.URIUtil;
|
|||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.eclipse.jetty.util.resource.ResourceCollection;
|
||||
import org.eclipse.jetty.util.resource.ResourceFactory;
|
||||
import org.eclipse.jetty.util.resource.Resources;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -231,7 +232,7 @@ public class WebAppClassLoader extends URLClassLoader implements ClassVisibility
|
|||
{
|
||||
for (Resource resource: resources)
|
||||
{
|
||||
if (resource != null && resource.exists())
|
||||
if (Resources.exists(resource))
|
||||
addURL(resource.getURI().toURL());
|
||||
else
|
||||
{
|
||||
|
@ -280,7 +281,7 @@ public class WebAppClassLoader extends URLClassLoader implements ClassVisibility
|
|||
*/
|
||||
public void addJars(Resource libs)
|
||||
{
|
||||
if (libs == null || !libs.exists() || !libs.isDirectory())
|
||||
if (!Resources.isReadableDirectory(libs))
|
||||
return;
|
||||
|
||||
for (Resource libDir: libs)
|
||||
|
|
|
@ -61,6 +61,7 @@ import org.eclipse.jetty.util.component.DumpableCollection;
|
|||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.eclipse.jetty.util.resource.ResourceCollection;
|
||||
import org.eclipse.jetty.util.resource.ResourceFactory;
|
||||
import org.eclipse.jetty.util.resource.Resources;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -388,7 +389,7 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL
|
|||
try
|
||||
{
|
||||
resource = super.getResource(pathInContext);
|
||||
if (resource != null && resource.exists())
|
||||
if (Resources.exists(resource))
|
||||
return resource;
|
||||
|
||||
pathInContext = getResourceAlias(pathInContext);
|
||||
|
@ -815,10 +816,10 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL
|
|||
// Can return from WEB-INF/lib/foo.jar!/WEB-INF
|
||||
// Can also never return from a META-INF/versions/#/WEB-INF location
|
||||
Resource webInf = getBaseResource().resolve("WEB-INF/");
|
||||
if (!webInf.exists() || !webInf.isDirectory())
|
||||
return null;
|
||||
if (Resources.isReadableDirectory(webInf))
|
||||
return webInf;
|
||||
|
||||
return webInf;
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1454,8 +1455,8 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL
|
|||
|
||||
for (Resource r: resource)
|
||||
{
|
||||
if (r.exists())
|
||||
return r.getURI().toURL();
|
||||
// return first entry
|
||||
return r.getURI().toURL();
|
||||
}
|
||||
|
||||
// A Resource was returned, but did not exist
|
||||
|
|
|
@ -30,6 +30,7 @@ import org.eclipse.jetty.util.URIUtil;
|
|||
import org.eclipse.jetty.util.resource.MountedPathResource;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.eclipse.jetty.util.resource.ResourceFactory;
|
||||
import org.eclipse.jetty.util.resource.Resources;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -66,12 +67,12 @@ public class WebInfConfiguration extends AbstractConfiguration
|
|||
{
|
||||
// Look for classes directory
|
||||
Resource classes = webInf.resolve("classes/");
|
||||
if (classes.exists())
|
||||
if (Resources.isReadableDirectory(classes))
|
||||
((WebAppClassLoader)context.getClassLoader()).addClassPath(classes);
|
||||
|
||||
// Look for jars
|
||||
Resource lib = webInf.resolve("lib/");
|
||||
if (lib.exists() || lib.isDirectory())
|
||||
if (Resources.isReadableDirectory(lib))
|
||||
((WebAppClassLoader)context.getClassLoader()).addJars(lib);
|
||||
}
|
||||
}
|
||||
|
@ -298,7 +299,7 @@ public class WebInfConfiguration extends AbstractConfiguration
|
|||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("{} anti-aliased to {}", webApp, realURI);
|
||||
Resource realWebApp = context.newResource(realURI);
|
||||
if (realWebApp != null && realWebApp.exists())
|
||||
if (Resources.exists(realWebApp))
|
||||
webApp = realWebApp;
|
||||
}
|
||||
|
||||
|
@ -312,20 +313,19 @@ public class WebInfConfiguration extends AbstractConfiguration
|
|||
Resource originalWarResource = webApp;
|
||||
|
||||
// Is the WAR usable directly?
|
||||
if (webApp != null && webApp.exists() && !webApp.isDirectory() && FileID.isJavaArchive(webApp.getURI()) && !webApp.getURI().getScheme().equalsIgnoreCase("jar"))
|
||||
if (Resources.isReadableFile(webApp) && FileID.isJavaArchive(webApp.getURI()) && !webApp.getURI().getScheme().equalsIgnoreCase("jar"))
|
||||
{
|
||||
// Turned this into a jar URL.
|
||||
Resource jarWebApp = context.getResourceFactory().newJarFileResource(webApp.getURI());
|
||||
if (jarWebApp != null && jarWebApp.exists() && !jarWebApp.isDirectory())
|
||||
if (Resources.isReadableFile(jarWebApp)) // but only if it is readable
|
||||
webApp = jarWebApp;
|
||||
}
|
||||
|
||||
// If we should extract or the URL is still not usable
|
||||
if (webApp.exists() && (
|
||||
(context.isCopyWebDir() && webApp.getPath() != null && originalWarResource.isDirectory()) ||
|
||||
if ((context.isCopyWebDir() && webApp.getPath() != null && originalWarResource.isDirectory()) ||
|
||||
(context.isExtractWAR() && webApp.getPath() != null && !originalWarResource.isDirectory()) ||
|
||||
(context.isExtractWAR() && webApp.getPath() == null) ||
|
||||
!originalWarResource.isDirectory())
|
||||
!originalWarResource.isDirectory()
|
||||
)
|
||||
{
|
||||
// Look for sibling directory.
|
||||
|
@ -350,7 +350,7 @@ public class WebInfConfiguration extends AbstractConfiguration
|
|||
context.setAttribute(TEMPORARY_RESOURCE_BASE, extractedWebAppDir);
|
||||
}
|
||||
|
||||
if (webApp.getPath() != null && webApp.isDirectory())
|
||||
if (Resources.isReadableDirectory(webApp))
|
||||
{
|
||||
// Copy directory
|
||||
if (LOG.isDebugEnabled())
|
||||
|
@ -397,11 +397,15 @@ public class WebInfConfiguration extends AbstractConfiguration
|
|||
}
|
||||
}
|
||||
}
|
||||
webApp = context.getResourceFactory().newResource(extractedWebAppDir.normalize());
|
||||
Resource extractedWebApp = context.getResourceFactory().newResource(extractedWebAppDir.normalize());
|
||||
if (extractedWebApp == null)
|
||||
LOG.warn("Unable to use non-existent extracted war location: " + extractedWebApp);
|
||||
else
|
||||
webApp = extractedWebApp;
|
||||
}
|
||||
|
||||
// Now do we have something usable?
|
||||
if (!webApp.exists() || !webApp.isDirectory())
|
||||
if (Resources.missing(webApp))
|
||||
{
|
||||
LOG.warn("Web application not found {}", war);
|
||||
throw new java.io.FileNotFoundException(war);
|
||||
|
@ -418,7 +422,7 @@ public class WebInfConfiguration extends AbstractConfiguration
|
|||
{
|
||||
Resource webInf = webApp.resolve("WEB-INF/");
|
||||
|
||||
if (webInf != null && webInf.exists() && webInf.isDirectory())
|
||||
if (Resources.isReadableDirectory(webInf))
|
||||
{
|
||||
File extractedWebInfDir = new File(context.getTempDirectory(), "webinf");
|
||||
if (extractedWebInfDir.exists())
|
||||
|
@ -428,7 +432,7 @@ public class WebInfConfiguration extends AbstractConfiguration
|
|||
File webInfDir = new File(extractedWebInfDir, "WEB-INF");
|
||||
webInfDir.mkdir();
|
||||
|
||||
if (webInfLib != null && webInfLib.exists() && webInfLib.isDirectory())
|
||||
if (Resources.isReadableDirectory(webInfLib))
|
||||
{
|
||||
File webInfLibDir = new File(webInfDir, "lib");
|
||||
if (webInfLibDir.exists())
|
||||
|
@ -441,7 +445,7 @@ public class WebInfConfiguration extends AbstractConfiguration
|
|||
}
|
||||
|
||||
Resource webInfClasses = webInf.resolve("classes/");
|
||||
if (webInfClasses != null && webInfClasses.exists() && !webInfClasses.isDirectory())
|
||||
if (Resources.isReadableDirectory(webInfClasses))
|
||||
{
|
||||
File webInfClassesDir = new File(webInfDir, "classes");
|
||||
if (webInfClassesDir.exists())
|
||||
|
|
|
@ -22,6 +22,7 @@ import org.eclipse.jetty.ee10.servlet.ErrorPageErrorHandler;
|
|||
import org.eclipse.jetty.util.IO;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.eclipse.jetty.util.resource.ResourceFactory;
|
||||
import org.eclipse.jetty.util.resource.Resources;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -50,7 +51,7 @@ public class WebXmlConfiguration extends AbstractConfiguration
|
|||
if (defaultsDescriptor != null && defaultsDescriptor.length() > 0)
|
||||
{
|
||||
Resource dftResource = context.getResourceFactory().newSystemResource(defaultsDescriptor);
|
||||
if (dftResource == null)
|
||||
if (Resources.missing(dftResource))
|
||||
{
|
||||
String pkg = WebXmlConfiguration.class.getPackageName().replace(".", "/") + "/";
|
||||
if (defaultsDescriptor.startsWith(pkg))
|
||||
|
@ -62,10 +63,10 @@ public class WebXmlConfiguration extends AbstractConfiguration
|
|||
dftResource = context.getResourceFactory().newResource(uri);
|
||||
}
|
||||
}
|
||||
if (dftResource == null)
|
||||
if (Resources.missing(dftResource))
|
||||
dftResource = context.newResource(defaultsDescriptor);
|
||||
}
|
||||
if (dftResource != null && dftResource.exists() && !dftResource.isDirectory())
|
||||
if (Resources.isReadableFile(dftResource))
|
||||
context.getMetaData().setDefaultsDescriptor(new DefaultsDescriptor(dftResource));
|
||||
}
|
||||
|
||||
|
@ -84,9 +85,9 @@ public class WebXmlConfiguration extends AbstractConfiguration
|
|||
if (overrideDescriptor != null && overrideDescriptor.length() > 0)
|
||||
{
|
||||
Resource orideResource = context.getResourceFactory().newSystemResource(overrideDescriptor);
|
||||
if (orideResource == null)
|
||||
if (Resources.missing(orideResource))
|
||||
orideResource = context.newResource(overrideDescriptor);
|
||||
if (orideResource != null && orideResource.exists() && !orideResource.isDirectory())
|
||||
if (Resources.isReadableFile(orideResource))
|
||||
context.getMetaData().addOverrideDescriptor(new OverrideDescriptor(orideResource));
|
||||
}
|
||||
}
|
||||
|
@ -107,7 +108,7 @@ public class WebXmlConfiguration extends AbstractConfiguration
|
|||
if (descriptor != null)
|
||||
{
|
||||
Resource web = context.newResource(descriptor);
|
||||
if (web.exists() && !web.isDirectory())
|
||||
if (web != null && !web.isDirectory())
|
||||
return web;
|
||||
}
|
||||
|
||||
|
@ -116,7 +117,7 @@ public class WebXmlConfiguration extends AbstractConfiguration
|
|||
{
|
||||
// do web.xml file
|
||||
Resource web = webInf.resolve("web.xml");
|
||||
if (web.exists())
|
||||
if (Resources.isReadableFile(web))
|
||||
return web;
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("No WEB-INF/web.xml in {}. Serving files and default/dynamic servlets only", context.getWar());
|
||||
|
|
|
@ -29,6 +29,7 @@ import org.junit.jupiter.api.Test;
|
|||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class ClassMatcherTest
|
||||
|
@ -211,15 +212,15 @@ public class ClassMatcherTest
|
|||
{
|
||||
// jar from JVM classloader
|
||||
URI modString = TypeUtil.getLocationOfClass(String.class);
|
||||
// System.err.println(modString);
|
||||
assertNotNull(modString);
|
||||
|
||||
// a jar from maven repo jar
|
||||
URI locJunit = TypeUtil.getLocationOfClass(Test.class);
|
||||
// System.err.println(locJunit);
|
||||
assertNotNull(locJunit);
|
||||
|
||||
// class file
|
||||
URI locTest = TypeUtil.getLocationOfClass(ClassMatcherTest.class);
|
||||
// System.err.println(locTest);
|
||||
assertNotNull(locTest);
|
||||
|
||||
ClassMatcher pattern = new ClassMatcher();
|
||||
|
||||
|
@ -234,7 +235,7 @@ public class ClassMatcherTest
|
|||
pattern.exclude("jrt:/java.base/");
|
||||
|
||||
// Add jar for individual class and classes directory
|
||||
pattern.exclude(locJunit.toString(), locTest.toString());
|
||||
pattern.exclude(locJunit.toASCIIString(), locTest.toASCIIString());
|
||||
|
||||
assertThat(pattern.match(String.class), is(false));
|
||||
assertThat(pattern.match(Test.class), is(false));
|
||||
|
|
|
@ -27,6 +27,7 @@ import org.eclipse.jetty.util.IO;
|
|||
import org.eclipse.jetty.util.resource.FileSystemPool;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.eclipse.jetty.util.resource.ResourceFactory;
|
||||
import org.eclipse.jetty.util.resource.Resources;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
|
|
@ -234,8 +234,8 @@ public class WebAppContextTest
|
|||
server.start();
|
||||
|
||||
ServletContext ctx = context.getServletContext();
|
||||
assertNotNull(ctx.getRealPath("/doesnotexist"));
|
||||
assertNotNull(ctx.getRealPath("/doesnotexist/"));
|
||||
assertNull(ctx.getRealPath("/doesnotexist"));
|
||||
assertNull(ctx.getRealPath("/doesnotexist/"));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -38,25 +38,6 @@ public class WebInfConfigurationTest
|
|||
{
|
||||
public WorkDir workDir;
|
||||
|
||||
public static Stream<Arguments> rawResourceNames()
|
||||
{
|
||||
return Stream.of(
|
||||
Arguments.of("/", ""),
|
||||
Arguments.of("/a", "a")
|
||||
);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("rawResourceNames")
|
||||
public void testTinyGetResourceBaseName(String rawPath, String expectedName) throws IOException
|
||||
{
|
||||
try (ResourceFactory.Closeable resourceFactory = ResourceFactory.closeable())
|
||||
{
|
||||
Resource resource = resourceFactory.newResource(rawPath);
|
||||
assertThat(WebInfConfiguration.getResourceBaseName(resource), is(expectedName));
|
||||
}
|
||||
}
|
||||
|
||||
public static Stream<Arguments> fileBaseResourceNames()
|
||||
{
|
||||
return Stream.of(
|
||||
|
|
|
@ -547,9 +547,6 @@ public class AnnotationParser
|
|||
if (r == null)
|
||||
return;
|
||||
|
||||
if (!r.exists())
|
||||
return;
|
||||
|
||||
if (FileID.isJavaArchive(r.getPath()))
|
||||
{
|
||||
parseJar(handlers, r);
|
||||
|
|
|
@ -25,6 +25,7 @@ import org.apache.maven.plugin.MojoExecutionException;
|
|||
import org.apache.maven.plugins.annotations.Parameter;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.eclipse.jetty.util.resource.ResourceFactory;
|
||||
import org.eclipse.jetty.util.resource.Resources;
|
||||
|
||||
/**
|
||||
* Base class for all goals that operate on unassembled webapps.
|
||||
|
@ -167,7 +168,7 @@ public abstract class AbstractUnassembledWebAppMojo extends AbstractWebAppMojo
|
|||
if (webXml != null)
|
||||
{
|
||||
Resource r = webApp.getResourceFactory().newResource(webXml.toPath());
|
||||
if (r.exists() && !r.isDirectory())
|
||||
if (Resources.isReadableFile(r))
|
||||
{
|
||||
webApp.setDescriptor(r.getURI().toASCIIString());
|
||||
}
|
||||
|
@ -177,7 +178,7 @@ public abstract class AbstractUnassembledWebAppMojo extends AbstractWebAppMojo
|
|||
if (webApp.getDescriptor() == null && webApp.getBaseResource() != null)
|
||||
{
|
||||
Resource r = webApp.getBaseResource().resolve("WEB-INF/web.xml");
|
||||
if (r.exists() && !r.isDirectory())
|
||||
if (Resources.isReadableFile(r))
|
||||
{
|
||||
webApp.setDescriptor(r.toString());
|
||||
}
|
||||
|
|
|
@ -43,6 +43,7 @@ import org.eclipse.jetty.util.URIUtil;
|
|||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.eclipse.jetty.util.resource.ResourceCollection;
|
||||
import org.eclipse.jetty.util.resource.ResourceFactory;
|
||||
import org.eclipse.jetty.util.resource.Resources;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -369,7 +370,7 @@ public class MavenWebAppContext extends WebAppContext
|
|||
|
||||
// If no regular resource exists check for access to /WEB-INF/lib or
|
||||
// /WEB-INF/classes
|
||||
if ((resource == null || !resource.exists()) && pathInContext != null && _classes != null)
|
||||
if (resource == null && pathInContext != null && _classes != null)
|
||||
{
|
||||
// Normalize again to look for the resource inside /WEB-INF subdirectories.
|
||||
String uri = URIUtil.normalizePath(pathInContext);
|
||||
|
@ -394,11 +395,11 @@ public class MavenWebAppContext extends WebAppContext
|
|||
// try matching
|
||||
Resource res = null;
|
||||
int i = 0;
|
||||
while (res == null && (i < _webInfClasses.size()))
|
||||
while (Resources.missing(res) && (i < _webInfClasses.size()))
|
||||
{
|
||||
String newPath = StringUtil.replace(uri, WEB_INF_CLASSES_PREFIX, _webInfClasses.get(i).getPath());
|
||||
res = ResourceFactory.of(this).newResource(newPath);
|
||||
if (!res.exists())
|
||||
if (Resources.missing(res))
|
||||
{
|
||||
res = null;
|
||||
i++;
|
||||
|
|
|
@ -21,6 +21,7 @@ import java.net.URL;
|
|||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.attribute.FileTime;
|
||||
import java.time.Instant;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
@ -112,6 +113,24 @@ public class SelectiveJarResource extends Resource
|
|||
return _delegate.getPath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDirectory()
|
||||
{
|
||||
return _delegate.isDirectory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Instant lastModified()
|
||||
{
|
||||
return _delegate.lastModified();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReadable()
|
||||
{
|
||||
return _delegate.isReadable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isContainedIn(Resource r)
|
||||
{
|
||||
|
@ -136,6 +155,12 @@ public class SelectiveJarResource extends Resource
|
|||
return _delegate.getFileName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Resource resolve(String subUriPath)
|
||||
{
|
||||
return _delegate.resolve(subUriPath);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void copyTo(Path directory) throws IOException
|
||||
{
|
||||
|
|
|
@ -43,6 +43,7 @@ import org.eclipse.jetty.http.ResourceHttpContent;
|
|||
import org.eclipse.jetty.util.BufferUtil;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.eclipse.jetty.util.resource.ResourceFactory;
|
||||
import org.eclipse.jetty.util.resource.Resources;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -231,7 +232,8 @@ public class CachedContentFactory implements HttpContent.ContentFactory
|
|||
{
|
||||
compressedContent = null;
|
||||
Resource compressedResource = _factory.newResource(compressedPathInContext);
|
||||
if (compressedResource != null && compressedResource.exists() && ResourceContentFactory.newerThanOrEqual(compressedResource, resource) &&
|
||||
if (Resources.isReadable(compressedResource) &&
|
||||
ResourceContentFactory.newerThanOrEqual(compressedResource, resource) &&
|
||||
compressedResource.length() < resource.length())
|
||||
{
|
||||
compressedContent = new CachedHttpContent(compressedPathInContext, compressedResource, null);
|
||||
|
|
|
@ -89,6 +89,7 @@ import org.eclipse.jetty.util.component.Environment;
|
|||
import org.eclipse.jetty.util.component.Graceful;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.eclipse.jetty.util.resource.ResourceFactory;
|
||||
import org.eclipse.jetty.util.resource.Resources;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -1401,7 +1402,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
|
|||
public boolean checkAlias(String path, Resource resource)
|
||||
{
|
||||
// Is the resource aliased?
|
||||
if (resource.isAlias())
|
||||
if (Resources.isReadable(resource) && resource.isAlias())
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Alias resource {} for {}", resource, resource.getRealURI());
|
||||
|
|
|
@ -33,6 +33,7 @@ import org.eclipse.jetty.http.PreEncodedHttpField;
|
|||
import org.eclipse.jetty.util.URIUtil;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.eclipse.jetty.util.resource.ResourceFactory;
|
||||
import org.eclipse.jetty.util.resource.Resources;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -152,7 +153,7 @@ public class ResourceHandler extends HandlerWrapper implements ResourceFactory,
|
|||
r = contextBase.resolve(path);
|
||||
}
|
||||
|
||||
if ((r == null || !r.exists()) && path.endsWith("/jetty-dir.css"))
|
||||
if (Resources.missing(r) && path.endsWith("/jetty-dir.css"))
|
||||
r = getStylesheet();
|
||||
|
||||
if (r == null)
|
||||
|
|
|
@ -55,6 +55,7 @@ import org.eclipse.jetty.util.IO;
|
|||
import org.eclipse.jetty.util.MultiPartOutputStream;
|
||||
import org.eclipse.jetty.util.URIUtil;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.eclipse.jetty.util.resource.Resources;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -245,7 +246,7 @@ public class ResourceService
|
|||
LOG.debug("content={}", content);
|
||||
|
||||
// Not found?
|
||||
if (content == null || !content.getResource().exists())
|
||||
if (content == null || Resources.missing(content.getResource()))
|
||||
{
|
||||
if (included)
|
||||
throw new FileNotFoundException("!" + pathInContext);
|
||||
|
|
|
@ -42,6 +42,7 @@ import org.eclipse.jetty.jndi.local.localContextRoot;
|
|||
import org.eclipse.jetty.util.IO;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.eclipse.jetty.util.resource.ResourceFactory;
|
||||
import org.eclipse.jetty.util.resource.Resources;
|
||||
import org.eclipse.jetty.xml.XmlConfiguration;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -101,7 +102,7 @@ public class EnvConfiguration extends AbstractConfiguration
|
|||
// TODO: should never return from WEB-INF/lib/foo.jar!/WEB-INF/jetty-env.xml
|
||||
// TODO: should also never return from a META-INF/versions/#/WEB-INF/jetty-env.xml location
|
||||
org.eclipse.jetty.util.resource.Resource jettyEnv = webInf.resolve("jetty-env.xml");
|
||||
if (jettyEnv.exists())
|
||||
if (Resources.isReadableFile(jettyEnv))
|
||||
{
|
||||
jettyEnvXmlResource = jettyEnv;
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ import org.eclipse.jetty.util.StringUtil;
|
|||
import org.eclipse.jetty.util.URIUtil;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.eclipse.jetty.util.resource.ResourceFactory;
|
||||
import org.eclipse.jetty.util.resource.Resources;
|
||||
import org.eclipse.jetty.xml.XmlParser;
|
||||
|
||||
/**
|
||||
|
@ -203,10 +204,9 @@ public class QuickStartDescriptorProcessor extends IterativeDescriptorProcessor
|
|||
for (URI uri : uris)
|
||||
{
|
||||
Resource r = _resourceFactory.newResource(uri);
|
||||
if (r.exists())
|
||||
visitMetaInfResource(context, r);
|
||||
else
|
||||
if (Resources.missing(r))
|
||||
throw new IllegalArgumentException("Resource not found: " + r);
|
||||
visitMetaInfResource(context, r);
|
||||
}
|
||||
}
|
||||
default ->
|
||||
|
|
|
@ -40,6 +40,7 @@ import org.eclipse.jetty.util.IO;
|
|||
import org.eclipse.jetty.util.URIUtil;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.eclipse.jetty.util.resource.ResourceFactory;
|
||||
import org.eclipse.jetty.util.resource.Resources;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -212,7 +213,7 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory, Welc
|
|||
if (stylesheet != null)
|
||||
{
|
||||
_stylesheet = _resourceFactory.newResource(stylesheet);
|
||||
if (!_stylesheet.exists())
|
||||
if (Resources.missing(_stylesheet))
|
||||
{
|
||||
LOG.warn("Stylesheet {} does not exist", stylesheet);
|
||||
_stylesheet = null;
|
||||
|
@ -475,7 +476,7 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory, Welc
|
|||
LOG.trace("IGNORED", e);
|
||||
}
|
||||
|
||||
if ((r == null || !r.exists()) && subUriPath.endsWith("/jetty-dir.css"))
|
||||
if (Resources.missing(r) && subUriPath.endsWith("/jetty-dir.css"))
|
||||
r = _stylesheet;
|
||||
|
||||
return r;
|
||||
|
|
|
@ -17,6 +17,7 @@ import java.io.IOException;
|
|||
import java.util.Map;
|
||||
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.eclipse.jetty.util.resource.Resources;
|
||||
import org.eclipse.jetty.xml.XmlConfiguration;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -58,12 +59,12 @@ public class JettyWebXmlConfiguration extends AbstractConfiguration
|
|||
{
|
||||
// do jetty.xml file
|
||||
Resource jetty = webInf.resolve("jetty8-web.xml");
|
||||
if (!jetty.exists())
|
||||
if (Resources.missing(jetty))
|
||||
jetty = webInf.resolve(JETTY_WEB_XML);
|
||||
if (!jetty.exists())
|
||||
if (Resources.missing(jetty))
|
||||
jetty = webInf.resolve("web-jetty.xml");
|
||||
|
||||
if (jetty.exists())
|
||||
if (Resources.isReadableFile(jetty))
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Configure: {}", jetty);
|
||||
|
|
|
@ -45,6 +45,7 @@ import org.eclipse.jetty.util.resource.Resource;
|
|||
import org.eclipse.jetty.util.resource.ResourceCollators;
|
||||
import org.eclipse.jetty.util.resource.ResourceFactory;
|
||||
import org.eclipse.jetty.util.resource.ResourceUriPatternPredicate;
|
||||
import org.eclipse.jetty.util.resource.Resources;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -148,7 +149,7 @@ public class MetaInfConfiguration extends AbstractConfiguration
|
|||
Consumer<URI> addContainerResource = (uri) ->
|
||||
{
|
||||
Resource resource = _resourceFactory.newResource(uri);
|
||||
if (resource == null || !resource.exists())
|
||||
if (Resources.missing(resource))
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Classpath URI doesn't exist: " + uri);
|
||||
|
@ -385,6 +386,10 @@ public class MetaInfConfiguration extends AbstractConfiguration
|
|||
*/
|
||||
public void scanForResources(WebAppContext context, Resource target, ConcurrentHashMap<Resource, Resource> cache)
|
||||
{
|
||||
// Resource target does not exist
|
||||
if (target == null)
|
||||
return;
|
||||
|
||||
Resource resourcesDir = null;
|
||||
if (cache != null && cache.containsKey(target))
|
||||
{
|
||||
|
@ -415,7 +420,7 @@ public class MetaInfConfiguration extends AbstractConfiguration
|
|||
resourcesDir = _resourceFactory.newResource(URIUtil.uriJarPrefix(uri, "!/META-INF/resources"));
|
||||
}
|
||||
|
||||
if (cache != null)
|
||||
if (Resources.isReadableDirectory(resourcesDir) && (cache != null))
|
||||
{
|
||||
Resource old = cache.putIfAbsent(target, resourcesDir);
|
||||
if (old != null)
|
||||
|
@ -445,7 +450,7 @@ public class MetaInfConfiguration extends AbstractConfiguration
|
|||
|
||||
private static boolean isEmptyResource(Resource resourcesDir)
|
||||
{
|
||||
return !resourcesDir.exists() || !resourcesDir.isDirectory();
|
||||
return resourcesDir == null || !resourcesDir.isDirectory();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -485,7 +490,7 @@ public class MetaInfConfiguration extends AbstractConfiguration
|
|||
webFrag = _resourceFactory.newResource(URIUtil.uriJarPrefix(uri, "!/META-INF/web-fragment.xml"));
|
||||
}
|
||||
|
||||
if (cache != null)
|
||||
if ((webFrag != null) && (cache != null))
|
||||
{
|
||||
//web-fragment.xml doesn't exist: put token in cache to signal we've seen the jar
|
||||
Resource old = cache.putIfAbsent(jar, webFrag);
|
||||
|
@ -512,7 +517,7 @@ public class MetaInfConfiguration extends AbstractConfiguration
|
|||
|
||||
private static boolean isEmptyFragment(Resource webFrag)
|
||||
{
|
||||
return !webFrag.exists() || webFrag.isDirectory();
|
||||
return !Resources.isReadableFile(webFrag);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -694,15 +699,20 @@ public class MetaInfConfiguration extends AbstractConfiguration
|
|||
return List.of();
|
||||
|
||||
Resource webInf = context.getWebInf();
|
||||
if (webInf == null || !webInf.exists() || !webInf.isDirectory())
|
||||
return List.of();
|
||||
if (Resources.isReadableDirectory(webInf))
|
||||
{
|
||||
Resource webInfLib = webInf.resolve("lib");
|
||||
|
||||
Resource webInfLib = webInf.resolve("/lib");
|
||||
if (Resources.isReadableDirectory(webInfLib))
|
||||
{
|
||||
return webInfLib.list().stream()
|
||||
.filter((lib) -> FileID.isLibArchive(lib.getFileName()))
|
||||
.sorted(ResourceCollators.byName(true))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
|
||||
return webInfLib.list().stream()
|
||||
.filter((lib) -> FileID.isLibArchive(lib.getFileName()))
|
||||
.sorted(ResourceCollators.byName(true))
|
||||
.collect(Collectors.toList());
|
||||
return List.of();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -741,12 +751,12 @@ public class MetaInfConfiguration extends AbstractConfiguration
|
|||
Resource webInf = context.getWebInf();
|
||||
|
||||
// Find WEB-INF/classes
|
||||
if (webInf != null && webInf.isDirectory())
|
||||
if (Resources.isReadableDirectory(webInf))
|
||||
{
|
||||
// Look for classes directory
|
||||
Resource classes = webInf.resolve("classes/");
|
||||
if (classes.exists())
|
||||
return classes;
|
||||
Resource classesDir = webInf.resolve("classes/");
|
||||
if (Resources.isReadableDirectory(classesDir))
|
||||
return classesDir;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -45,6 +45,7 @@ import org.eclipse.jetty.util.URIUtil;
|
|||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.eclipse.jetty.util.resource.ResourceCollection;
|
||||
import org.eclipse.jetty.util.resource.ResourceFactory;
|
||||
import org.eclipse.jetty.util.resource.Resources;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -231,7 +232,7 @@ public class WebAppClassLoader extends URLClassLoader implements ClassVisibility
|
|||
{
|
||||
for (Resource resource: resources)
|
||||
{
|
||||
if (resource.exists())
|
||||
if (Resources.exists(resource))
|
||||
addURL(resource.getURI().toURL());
|
||||
else
|
||||
{
|
||||
|
@ -280,7 +281,7 @@ public class WebAppClassLoader extends URLClassLoader implements ClassVisibility
|
|||
*/
|
||||
public void addJars(Resource libs)
|
||||
{
|
||||
if (libs == null || !libs.exists() || !libs.isDirectory())
|
||||
if (!Resources.isReadableDirectory(libs))
|
||||
return;
|
||||
|
||||
for (Resource libDir: libs)
|
||||
|
|
|
@ -65,6 +65,7 @@ import org.eclipse.jetty.util.component.DumpableCollection;
|
|||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.eclipse.jetty.util.resource.ResourceCollection;
|
||||
import org.eclipse.jetty.util.resource.ResourceFactory;
|
||||
import org.eclipse.jetty.util.resource.Resources;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -397,7 +398,7 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL
|
|||
try
|
||||
{
|
||||
resource = super.getResource(pathInContext);
|
||||
if (resource != null && resource.exists())
|
||||
if (Resources.exists(resource))
|
||||
return resource;
|
||||
|
||||
pathInContext = getResourceAlias(pathInContext);
|
||||
|
@ -817,10 +818,10 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL
|
|||
// Can return from WEB-INF/lib/foo.jar!/WEB-INF
|
||||
// Can also never return from a META-INF/versions/#/WEB-INF location
|
||||
Resource webInf = super.getBaseResource().resolve("WEB-INF/");
|
||||
if (!webInf.exists() || !webInf.isDirectory())
|
||||
return null;
|
||||
if (Resources.isReadableDirectory(webInf))
|
||||
return webInf;
|
||||
|
||||
return webInf;
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1443,7 +1444,8 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL
|
|||
|
||||
for (Resource r: resource)
|
||||
{
|
||||
if (r.exists())
|
||||
// return first entry
|
||||
if (Resources.exists(r))
|
||||
return r.getURI().toURL();
|
||||
}
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@ import org.eclipse.jetty.util.URIUtil;
|
|||
import org.eclipse.jetty.util.resource.MountedPathResource;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.eclipse.jetty.util.resource.ResourceFactory;
|
||||
import org.eclipse.jetty.util.resource.Resources;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -65,12 +66,12 @@ public class WebInfConfiguration extends AbstractConfiguration
|
|||
{
|
||||
// Look for classes directory
|
||||
Resource classes = webInf.resolve("classes/");
|
||||
if (classes.exists())
|
||||
if (Resources.isReadableDirectory(classes))
|
||||
((WebAppClassLoader)context.getClassLoader()).addClassPath(classes);
|
||||
|
||||
// Look for jars
|
||||
Resource lib = webInf.resolve("lib/");
|
||||
if (lib.exists() || lib.isDirectory())
|
||||
if (Resources.isReadableDirectory(lib))
|
||||
((WebAppClassLoader)context.getClassLoader()).addJars(lib);
|
||||
}
|
||||
}
|
||||
|
@ -310,12 +311,12 @@ public class WebInfConfiguration extends AbstractConfiguration
|
|||
Resource originalWarResource = webApp;
|
||||
|
||||
// Is the WAR usable directly?
|
||||
if (webApp.exists() && !webApp.isDirectory() && FileID.isJavaArchive(webApp.getURI()) && !webApp.getURI().getScheme().equalsIgnoreCase("jar"))
|
||||
if (Resources.isReadableFile(webApp) && FileID.isJavaArchive(webApp.getURI()) && !webApp.getURI().getScheme().equalsIgnoreCase("jar"))
|
||||
{
|
||||
// No - then lets see if it can be turned into a jar URL.
|
||||
// Turned this into a jar URL.
|
||||
Resource jarWebApp = context.getResourceFactory().newJarFileResource(webApp.getURI());
|
||||
if (jarWebApp != null && jarWebApp.exists())
|
||||
if (Resources.isReadableFile(jarWebApp)) // but only if it is readable
|
||||
webApp = jarWebApp;
|
||||
}
|
||||
|
||||
|
@ -400,7 +401,7 @@ public class WebInfConfiguration extends AbstractConfiguration
|
|||
}
|
||||
|
||||
// Now do we have something usable?
|
||||
if (!webApp.exists() || !webApp.isDirectory())
|
||||
if (Resources.missing(webApp))
|
||||
{
|
||||
LOG.warn("Web application not found {}", war);
|
||||
throw new java.io.FileNotFoundException(war);
|
||||
|
@ -417,7 +418,7 @@ public class WebInfConfiguration extends AbstractConfiguration
|
|||
{
|
||||
Resource webInf = webApp.resolve("WEB-INF/");
|
||||
|
||||
if (webInf != null && webInf.isDirectory())
|
||||
if (Resources.isReadableDirectory(webInf))
|
||||
{
|
||||
File extractedWebInfDir = new File(context.getTempDirectory(), "webinf");
|
||||
if (extractedWebInfDir.exists())
|
||||
|
@ -428,7 +429,7 @@ public class WebInfConfiguration extends AbstractConfiguration
|
|||
webInfDir.mkdir();
|
||||
|
||||
Resource webInfLib = webInf.resolve("lib/");
|
||||
if (webInfLib != null && webInfLib.isDirectory())
|
||||
if (Resources.isReadableDirectory(webInfLib))
|
||||
{
|
||||
File webInfLibDir = new File(webInfDir, "lib");
|
||||
if (webInfLibDir.exists())
|
||||
|
@ -441,7 +442,7 @@ public class WebInfConfiguration extends AbstractConfiguration
|
|||
}
|
||||
|
||||
Resource webInfClasses = webInf.resolve("classes/");
|
||||
if (webInfClasses != null && webInfClasses.isDirectory())
|
||||
if (Resources.isReadableDirectory(webInfClasses))
|
||||
{
|
||||
File webInfClassesDir = new File(webInfDir, "classes");
|
||||
if (webInfClassesDir.exists())
|
||||
|
|
|
@ -22,6 +22,7 @@ import org.eclipse.jetty.ee9.servlet.ErrorPageErrorHandler;
|
|||
import org.eclipse.jetty.util.IO;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.eclipse.jetty.util.resource.ResourceFactory;
|
||||
import org.eclipse.jetty.util.resource.Resources;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -50,7 +51,7 @@ public class WebXmlConfiguration extends AbstractConfiguration
|
|||
if (defaultsDescriptor != null && defaultsDescriptor.length() > 0)
|
||||
{
|
||||
Resource dftResource = context.getResourceFactory().newSystemResource(defaultsDescriptor);
|
||||
if (dftResource == null)
|
||||
if (Resources.missing(dftResource))
|
||||
{
|
||||
String pkg = WebXmlConfiguration.class.getPackageName().replace(".", "/") + "/";
|
||||
if (defaultsDescriptor.startsWith(pkg))
|
||||
|
@ -62,10 +63,10 @@ public class WebXmlConfiguration extends AbstractConfiguration
|
|||
dftResource = context.getResourceFactory().newResource(uri);
|
||||
}
|
||||
}
|
||||
if (dftResource == null)
|
||||
if (Resources.missing(dftResource))
|
||||
dftResource = context.newResource(defaultsDescriptor);
|
||||
}
|
||||
if (dftResource != null && dftResource.exists() && !dftResource.isDirectory())
|
||||
if (Resources.isReadableFile(dftResource))
|
||||
context.getMetaData().setDefaultsDescriptor(new DefaultsDescriptor(dftResource));
|
||||
}
|
||||
|
||||
|
@ -106,7 +107,7 @@ public class WebXmlConfiguration extends AbstractConfiguration
|
|||
if (descriptor != null)
|
||||
{
|
||||
Resource web = context.newResource(descriptor);
|
||||
if (web.exists() && !web.isDirectory())
|
||||
if (web != null && !web.isDirectory())
|
||||
return web;
|
||||
}
|
||||
|
||||
|
@ -115,7 +116,7 @@ public class WebXmlConfiguration extends AbstractConfiguration
|
|||
{
|
||||
// do web.xml file
|
||||
Resource web = webInf.resolve("web.xml");
|
||||
if (web.exists())
|
||||
if (Resources.isReadableFile(web))
|
||||
return web;
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("No WEB-INF/web.xml in {}. Serving files and default/dynamic servlets only", context.getWar());
|
||||
|
|
|
@ -27,6 +27,7 @@ import org.eclipse.jetty.util.IO;
|
|||
import org.eclipse.jetty.util.resource.FileSystemPool;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.eclipse.jetty.util.resource.ResourceFactory;
|
||||
import org.eclipse.jetty.util.resource.Resources;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
@ -86,7 +87,7 @@ public class TestMetaData
|
|||
Resource fragMount = resourceFactory.newJarFileResource(fragFile.toUri());
|
||||
assertNotNull(fragMount);
|
||||
webfragxml = fragMount.resolve("/META-INF/web-fragment.xml");
|
||||
assertNotNull(webfragxml);
|
||||
assertTrue(Resources.isReadableFile(webfragxml));
|
||||
|
||||
Path testContainerDir = testDir.resolve("container");
|
||||
FS.ensureDirExists(testContainerDir);
|
||||
|
@ -94,9 +95,9 @@ public class TestMetaData
|
|||
FS.ensureDirExists(testWebInfClassesDir);
|
||||
|
||||
containerDir = resourceFactory.newResource(testContainerDir);
|
||||
assertNotNull(containerDir);
|
||||
assertTrue(Resources.isReadableDirectory(containerDir));
|
||||
webInfClassesDir = resourceFactory.newResource(testWebInfClassesDir);
|
||||
assertNotNull(webInfClassesDir);
|
||||
assertTrue(Resources.isReadableDirectory(webInfClassesDir));
|
||||
|
||||
wac = new WebAppContext();
|
||||
applications = new ArrayList<>();
|
||||
|
|
|
@ -52,6 +52,7 @@ import org.eclipse.jetty.util.component.LifeCycle;
|
|||
import org.eclipse.jetty.util.resource.FileSystemPool;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.eclipse.jetty.util.resource.ResourceFactory;
|
||||
import org.eclipse.jetty.util.resource.Resources;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
|
@ -235,8 +236,8 @@ public class WebAppContextTest
|
|||
server.start();
|
||||
|
||||
ServletContext ctx = context.getServletContext();
|
||||
assertNotNull(ctx.getRealPath("/doesnotexist"));
|
||||
assertNotNull(ctx.getRealPath("/doesnotexist/"));
|
||||
assertNull(ctx.getRealPath("/doesnotexist"));
|
||||
assertNull(ctx.getRealPath("/doesnotexist/"));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -410,7 +411,7 @@ public class WebAppContextTest
|
|||
WebAppContext context = new WebAppContext();
|
||||
Path testWebapp = MavenPaths.findTestResourceDir("webapp");
|
||||
Resource testWebappResource = context.getResourceFactory().newResource(testWebapp);
|
||||
assertTrue(testWebappResource.isDirectory());
|
||||
assertTrue(Resources.isReadableDirectory(testWebappResource));
|
||||
context.setBaseResource(testWebappResource);
|
||||
context.setContextPath("/");
|
||||
|
||||
|
|
Loading…
Reference in New Issue