Skip to content

Commit

Permalink
Consider empty jar entries as readable
Browse files Browse the repository at this point in the history
Prior to this commit, resource handling would not serve empty files and
return instead HTTP 404 responses. This would only happen for files
contained by JARs, but not on the filesystem.

This can be tracked to changes done in `AbstractFileResolvingResource`
where we avoid serving empty files for directories, see gh-21372.
This commit improves the `checkReadable` method to align this behavior
between file system and JAR files.

Closes gh-28850
  • Loading branch information
larsgrefer authored and bclozel committed Sep 26, 2022
1 parent dfd1a31 commit 94e5eb3
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,15 @@
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.JarURLConnection;
import java.net.URI;
import java.net.URL;
import java.net.URLConnection;
import java.nio.channels.FileChannel;
import java.nio.channels.ReadableByteChannel;
import java.nio.file.NoSuchFileException;
import java.nio.file.StandardOpenOption;
import java.util.jar.JarEntry;

import org.springframework.util.ResourceUtils;

Expand Down Expand Up @@ -115,6 +117,16 @@ boolean checkReadable(URL url) {
return false;
}
}
else if (con instanceof JarURLConnection) {
JarURLConnection jarCon = (JarURLConnection) con;
JarEntry jarEntry = jarCon.getJarEntry();
if (jarEntry == null) {
return false;
}
else {
return !jarEntry.isDirectory();
}
}
long contentLength = con.getContentLengthLong();
if (contentLength > 0) {
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,18 @@

package org.springframework.core.io;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
Expand Down Expand Up @@ -143,4 +151,32 @@ void directoryNotReadable() throws Exception {
assertThat(jarDir.isReadable()).isFalse();
}

@Test
void emptyFileReadable(@TempDir File tempDir) throws IOException {
File file = new File(tempDir, "empty.txt");
assertThat(file.createNewFile()).isTrue();
assertThat(file.isFile());

ClassLoader fileClassLoader = new URLClassLoader(new URL[]{tempDir.toURI().toURL()});

Resource emptyFile = new ClassPathResource("empty.txt", fileClassLoader);
assertThat(emptyFile.exists()).isTrue();
assertThat(emptyFile.isReadable()).isTrue();
assertThat(emptyFile.contentLength()).isEqualTo(0);

File jarFile = new File(tempDir, "test.jar");
try (ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(jarFile))) {
zipOut.putNextEntry(new ZipEntry("empty2.txt"));
zipOut.closeEntry();
}
assertThat(jarFile.isFile());

ClassLoader jarClassLoader = new URLClassLoader(new URL[]{jarFile.toURI().toURL()});

Resource emptyJarEntry = new ClassPathResource("empty2.txt", jarClassLoader);
assertThat(emptyJarEntry.exists()).isTrue();
assertThat(emptyJarEntry.isReadable()).isTrue();
assertThat(emptyJarEntry.contentLength()).isEqualTo(0);
}

}

0 comments on commit 94e5eb3

Please sign in to comment.