Skip to content

Commit

Permalink
Merge pull request #8888 from eclipse/fix/jetty-12-extensible-resourc…
Browse files Browse the repository at this point in the history
…e-schemes

Issue #8886 - support extensible Resource URI schemes
  • Loading branch information
joakime authored Nov 23, 2022
2 parents b7d7e53 + 46ccfa1 commit 84208f9
Show file tree
Hide file tree
Showing 13 changed files with 659 additions and 130 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import java.util.stream.Stream;

import org.eclipse.jetty.util.Utf8Appendable.NotUtf8Exception;
import org.eclipse.jetty.util.resource.ResourceFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand Down Expand Up @@ -1903,7 +1904,8 @@ public static URI toURI(String resource)
Objects.requireNonNull(resource);

// Only try URI for string for known schemes, otherwise assume it is a Path
return (KNOWN_SCHEMES.getBest(resource) != null)
ResourceFactory resourceFactory = ResourceFactory.getBestByScheme(resource);
return (resourceFactory != null)
? correctFileURI(URI.create(resource))
: Paths.get(resource).toUri();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,8 @@ Mount mount(URI uri) throws IOException
{
if (!uri.isAbsolute())
throw new IllegalArgumentException("not an absolute uri: " + uri);
if (PathResource.ALLOWED_SCHEMES.contains(uri.getScheme()))
throw new IllegalArgumentException("not an allowed scheme: " + uri);
if (!uri.getScheme().equalsIgnoreCase("jar"))
throw new IllegalArgumentException("not an supported scheme: " + uri);

FileSystem fileSystem = null;
try (AutoLock ignore = poolLock.lock())
Expand All @@ -128,7 +128,7 @@ Mount mount(URI uri) throws IOException
}
// use root FS URI so that pool key/release/sweep is sane
URI rootURI = fileSystem.getPath("/").toUri();
Mount mount = new Mount(rootURI, Resource.create(uri));
Mount mount = new Mount(rootURI, new MountedPathResource(uri));
retain(rootURI, fileSystem, mount);
return mount;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,7 @@
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;

Expand All @@ -28,14 +26,6 @@
*/
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
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//
// ========================================================================
// 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;

import java.net.URI;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

public class MountedPathResourceFactory implements ResourceFactory
{
@Override
public Resource newResource(URI uri)
{
Path path = Paths.get(uri.normalize());
if (!Files.exists(path))
return null;
return new MountedPathResource(path, uri);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,20 +44,12 @@ public class PathResource extends Resource
{
private static final Logger LOG = LoggerFactory.getLogger(PathResource.class);

public static Index<String> ALLOWED_SCHEMES = new Index.Builder<String>()
public static Index<String> SUPPORTED_SCHEMES = new Index.Builder<String>()
.caseSensitive(false)
.with("file")
.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
Expand Down Expand Up @@ -176,7 +168,7 @@ public static boolean isSameName(Path pathA, Path pathB)
{
if (!uri.isAbsolute())
throw new IllegalArgumentException("not an absolute uri: " + uri);
if (!bypassAllowedSchemeCheck && !ALLOWED_SCHEMES.contains(uri.getScheme()))
if (!bypassAllowedSchemeCheck && !SUPPORTED_SCHEMES.contains(uri.getScheme()))
throw new IllegalArgumentException("not an allowed scheme: " + uri);

if (Files.isDirectory(path))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//
// ========================================================================
// 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;

import java.net.URI;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

public class PathResourceFactory implements ResourceFactory
{
@Override
public Resource newResource(URI uri)
{
Path path = Paths.get(uri.normalize());
if (!Files.exists(path))
return null;
return new PathResource(path, uri, false);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,10 @@
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.channels.ReadableByteChannel;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.ProviderNotFoundException;
import java.nio.file.StandardCopyOption;
import java.nio.file.StandardOpenOption;
import java.time.Instant;
Expand All @@ -33,9 +30,6 @@
import java.util.List;

import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.util.URIUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* <p>
Expand All @@ -47,9 +41,7 @@
*/
public abstract class Resource implements Iterable<Resource>
{
private static final Logger LOG = LoggerFactory.getLogger(Resource.class);
private static final LinkOption[] NO_FOLLOW_LINKS = new LinkOption[]{LinkOption.NOFOLLOW_LINKS};
private static final LinkOption[] FOLLOW_LINKS = new LinkOption[]{};

public static String dump(Resource resource)
{
Expand All @@ -59,43 +51,6 @@ public static String dump(Resource resource)
.formatted(resource.toString(), resource.exists(), resource.isDirectory(), resource.lastModified());
}

/**
* Construct a resource from a uri.
*
* @param uri A URI.
* @return A Resource object.
*/
static Resource create(URI uri)
{
try
{
// If the URI is not absolute
if (!uri.isAbsolute())
{
// If it is an absolute path,
if (uri.toString().startsWith("/"))
// just add the scheme
uri = new URI("file", uri.toString(), null);
else
// otherwise resolve against the current directory
uri = Paths.get("").toAbsolutePath().toUri().resolve(uri);

// Correct any `file:/path` to `file:///path` mistakes
uri = URIUtil.correctFileURI(uri);
}

// If the scheme is allowed by PathResource, we can build a non-mounted PathResource.
if (PathResource.ALLOWED_SCHEMES.contains(uri.getScheme()))
return PathResource.of(uri);

return MountedPathResource.of(uri);
}
catch (URISyntaxException | ProviderNotFoundException | IOException ex)
{
throw new IllegalArgumentException(ex);
}
}

/**
* Return the Path corresponding to this resource.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ default Resource newClassPathResource(String resource)
try
{
URI uri = url.toURI();
return Resource.create(uri);
return newResource(uri);
}
catch (URISyntaxException e)
{
Expand Down Expand Up @@ -244,6 +244,26 @@ default Resource newJarFileResource(URI uri)
return newResource(URIUtil.toJarFileUri(uri));
}

static void registerResourceFactory(String scheme, ResourceFactory resource)
{
ResourceFactoryInternals.RESOURCE_FACTORIES.put(scheme, resource);
}

static ResourceFactory unregisterResourceFactory(String scheme)
{
return ResourceFactoryInternals.RESOURCE_FACTORIES.remove(scheme);
}

static ResourceFactory byScheme(String scheme)
{
return ResourceFactoryInternals.RESOURCE_FACTORIES.get(scheme);
}

static ResourceFactory getBestByScheme(String str)
{
return ResourceFactoryInternals.RESOURCE_FACTORIES.getBest(str);
}

static ResourceFactory root()
{
return ResourceFactoryInternals.ROOT;
Expand Down
Loading

0 comments on commit 84208f9

Please sign in to comment.