#9984 fix URLResourceFactory isDirectory and newReadableByteChannel (#9985)

* #9984 fix URLResourceFactory isDirectory and newReadableByteChannel

Signed-off-by: Ludovic Orban <lorban@bitronix.be>
This commit is contained in:
Ludovic Orban 2023-06-28 18:36:00 +02:00 committed by GitHub
parent daa7167834
commit cc3bac27a5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 97 additions and 29 deletions

View File

@ -19,6 +19,7 @@ import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.net.URLConnection;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.nio.file.Path;
import java.time.Instant;
@ -109,7 +110,7 @@ public class URLResourceFactory implements ResourceFactory
@Override
public boolean isDirectory()
{
return uri.getPath().endsWith("/");
return uri.getSchemeSpecificPart().endsWith("/");
}
@Override
@ -200,10 +201,9 @@ public class URLResourceFactory implements ResourceFactory
}
@Override
public ReadableByteChannel newReadableByteChannel()
public ReadableByteChannel newReadableByteChannel() throws IOException
{
// not really possible with the URL interface
return null;
return Channels.newChannel(newInputStream());
}
@Override

View File

@ -16,9 +16,15 @@ package org.eclipse.jetty.util.resource;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URL;
import java.nio.ByteBuffer;
import java.nio.channels.ReadableByteChannel;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Instant;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
import org.eclipse.jetty.util.IO;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
@ -38,35 +44,97 @@ public class UrlResourceFactoryTest
public void testHttps() throws IOException
{
ResourceFactory.registerResourceFactory("https", new URLResourceFactory());
Resource resource = ResourceFactory.root().newResource(URI.create("https://webtide.com/"));
assertThat(resource, notNullValue());
assertTrue(resource.exists());
try (InputStream in = resource.newInputStream())
try
{
String result = IO.toString(in, StandardCharsets.UTF_8);
assertThat(result, containsString("webtide.com"));
Resource resource = ResourceFactory.root().newResource(URI.create("https://webtide.com/"));
assertThat(resource, notNullValue());
assertTrue(resource.exists());
try (InputStream in = resource.newInputStream())
{
String result = IO.toString(in, StandardCharsets.UTF_8);
assertThat(result, containsString("webtide.com"));
}
assertThat(resource.lastModified().toEpochMilli(), not(Instant.EPOCH));
assertThat(resource.length(), not(-1));
assertTrue(resource.isDirectory());
assertThat(resource.getFileName(), is(""));
Resource blogs = resource.resolve("blogs/");
assertThat(blogs, notNullValue());
assertTrue(blogs.exists());
assertThat(blogs.lastModified().toEpochMilli(), not(Instant.EPOCH));
assertThat(blogs.length(), not(-1));
assertTrue(blogs.isDirectory());
assertThat(blogs.getFileName(), is(""));
Resource favicon = resource.resolve("favicon.ico");
assertThat(favicon, notNullValue());
assertTrue(favicon.exists());
assertThat(favicon.lastModified().toEpochMilli(), not(Instant.EPOCH));
assertThat(favicon.length(), not(-1));
assertFalse(favicon.isDirectory());
assertThat(favicon.getFileName(), is("favicon.ico"));
}
finally
{
ResourceFactory.unregisterResourceFactory("https");
}
}
assertThat(resource.lastModified().toEpochMilli(), not(Instant.EPOCH));
assertThat(resource.length(), not(-1));
assertTrue(resource.isDirectory());
assertThat(resource.getFileName(), is(""));
@Test
public void testFileUrl() throws Exception
{
Path path = MavenTestingUtils.getTestResourcePath("example.jar");
int fileSize = (int)Files.size(path);
URL fileUrl = new URL("file:" + path.toAbsolutePath());
URLResourceFactory urlResourceFactory = new URLResourceFactory();
Resource resource = urlResourceFactory.newResource(fileUrl);
Resource blogs = resource.resolve("blogs/");
assertThat(blogs, notNullValue());
assertTrue(blogs.exists());
assertThat(blogs.lastModified().toEpochMilli(), not(Instant.EPOCH));
assertThat(blogs.length(), not(-1));
assertTrue(blogs.isDirectory());
assertThat(blogs.getFileName(), is(""));
assertThat(resource.isDirectory(), is(false));
Resource favicon = resource.resolve("favicon.ico");
assertThat(favicon, notNullValue());
assertTrue(favicon.exists());
assertThat(favicon.lastModified().toEpochMilli(), not(Instant.EPOCH));
assertThat(favicon.length(), not(-1));
assertFalse(favicon.isDirectory());
assertThat(favicon.getFileName(), is("favicon.ico"));
try (ReadableByteChannel channel = resource.newReadableByteChannel())
{
ByteBuffer buffer = ByteBuffer.allocate(fileSize);
int read = channel.read(buffer);
assertThat(read, is(fileSize));
}
}
@Test
public void testJarFileUrl() throws Exception
{
Path path = MavenTestingUtils.getTestResourcePath("example.jar");
URL jarFileUrl = new URL("jar:file:" + path.toAbsolutePath() + "!/WEB-INF/web.xml");
int fileSize = (int)fileSize(jarFileUrl);
URLResourceFactory urlResourceFactory = new URLResourceFactory();
Resource resource = urlResourceFactory.newResource(jarFileUrl);
assertThat(resource.isDirectory(), is(false));
try (ReadableByteChannel channel = resource.newReadableByteChannel())
{
ByteBuffer buffer = ByteBuffer.allocate(fileSize);
int read = channel.read(buffer);
assertThat(read, is(fileSize));
}
}
private static long fileSize(URL url) throws IOException
{
try (InputStream is = url.openStream())
{
long totalRead = 0;
byte[] buffer = new byte[512];
while (true)
{
int read = is.read(buffer);
if (read == -1)
break;
totalRead += read;
}
return totalRead;
}
}
}