From 778404bba8fba81e7d005d69754b3e6b023d71ad Mon Sep 17 00:00:00 2001 From: Ludovic Orban Date: Mon, 8 Sep 2025 10:59:17 +0200 Subject: [PATCH 1/2] #13563 fix BufferUtil.toMappedBuffer(Path) to catch UnsupportedOperationException and add related tests Signed-off-by: Ludovic Orban --- .../FileMappingHttpContentFactoryTest.java | 29 ++++++++++++++++++ .../jetty-http/src/test/resources/example.jar | Bin 0 -> 6047 bytes .../org/eclipse/jetty/util/BufferUtil.java | 3 +- .../eclipse/jetty/util/BufferUtilTest.java | 13 ++++++++ 4 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 jetty-core/jetty-http/src/test/resources/example.jar diff --git a/jetty-core/jetty-http/src/test/java/org/eclipse/jetty/http/content/FileMappingHttpContentFactoryTest.java b/jetty-core/jetty-http/src/test/java/org/eclipse/jetty/http/content/FileMappingHttpContentFactoryTest.java index bdb20a08ecff..2ed03f0a5619 100644 --- a/jetty-core/jetty-http/src/test/java/org/eclipse/jetty/http/content/FileMappingHttpContentFactoryTest.java +++ b/jetty-core/jetty-http/src/test/java/org/eclipse/jetty/http/content/FileMappingHttpContentFactoryTest.java @@ -15,16 +15,21 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.nio.channels.FileChannel; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.StandardOpenOption; import org.eclipse.jetty.http.MimeTypes; import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.io.Content; +import org.eclipse.jetty.toolchain.test.MavenTestingUtils; import org.eclipse.jetty.toolchain.test.jupiter.WorkDir; import org.eclipse.jetty.toolchain.test.jupiter.WorkDirExtension; import org.eclipse.jetty.util.Blocker; +import org.eclipse.jetty.util.URIUtil; +import org.eclipse.jetty.util.resource.Resource; import org.eclipse.jetty.util.resource.ResourceFactory; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -94,6 +99,30 @@ public void testMultiBufferFileMappedMaxBufferSizeRounding(int maxBufferSize) th assertThat(writeToString(content, 0, -1), is("0123456789abcdefghijABCDEFGHIJ")); } + @ParameterizedTest + @ValueSource(ints = {8, 10}) + public void testUnsupportedFileSystemStillServesContent(int maxBufferSize) throws IOException + { + Path jarFile = MavenTestingUtils.getTestResourcePathFile("example.jar"); + + try (ResourceFactory.Closeable resourceFactory = ResourceFactory.closeable()) + { + Resource jarResource = resourceFactory.newJarFileResource(jarFile.toUri()); + + // First make sure that this kind of FS cannot mmap files. + Resource resolved = jarResource.resolve("WEB-INF/web.xml"); + try (FileChannel channel = FileChannel.open(resolved.getPath(), StandardOpenOption.READ)) + { + assertThrows(UnsupportedOperationException.class, () -> channel.map(FileChannel.MapMode.READ_ONLY, 0, resolved.length())); + } + + // Then make sure FileMappingHttpContentFactory manages to fall back to some other way to serve the content. + FileMappingHttpContentFactory fileMappingHttpContentFactory = new FileMappingHttpContentFactory(new ResourceHttpContentFactory(jarResource, MimeTypes.DEFAULTS, ByteBufferPool.SIZED_NON_POOLING), 0, maxBufferSize); + HttpContent content = fileMappingHttpContentFactory.getContent("WEB-INF/web.xml"); + assertThat(content.getContentLengthValue(), is(35L)); + } + } + private static String writeToString(HttpContent content, long offset, long length) throws IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); diff --git a/jetty-core/jetty-http/src/test/resources/example.jar b/jetty-core/jetty-http/src/test/resources/example.jar new file mode 100644 index 0000000000000000000000000000000000000000..ae6588831400f7ad3ae07fc0d2d43487c5b3e35f GIT binary patch literal 6047 zcmb7IT})g>6uvAJwxy(6Dg8;)AEXV?-My3_32Gl8Lb$u^PbgFyeUQS{Qnw52La8P` zRE<(ee5e|2`Y1|jqp{GRSbZ=tjnG|KpcK=XCXFqnKQFYUVq!GT*}He=%rJNNG6dL! zIp6u_oSAdJgU^+oktV|TSjsjJ=FtIQb*KasJ$Z)l8yJT6Yk$#lEh@Akx57JO=R{V$838t zGxcc8;ZDCAGuKjei!+zam@9$ZCEkGlZAYuWB@}wxlhZZ*WFd4_))KL6rm}n@Dm#Do zeper{k0{p`BW30D(eUYM*SKPHWRkFES(VQ^|JqG_fj^pio{ilco0^X9gQmHJuE?Vk zh>7)!d!7%mgzf z0EsM60s%ExWs+9}(&>8`3A^k=_l1R<*{YrPs=}W}}Oy`_>VvJ3Ec@ zyQa6tlD%WDAaDI(-h&tNa_=6y9y|U}*XucuH@376aEI8I;t>A!11O{X0g6pnx2c_K zpv`fpCAhR#U7U`wpKaTDZ*U-Q;Lg`~)g5_hG5Xs#4s{n1cyK|VDo^0q6a;$J1CFDI z{f3@DAKZDb`Su-fk!9_BtG*(i00JmYdoLF;P)>S+=&mohT~DE1dK!(70dhmf)ORP6 zp55Cs1s&cC4cud&>9rM3qz}jH+4J*rU#%y$U{ASx!*N-S(39sgkK0Ler;~_|HcWXH zd;OSeGVHWzs%`V0icQdP!P@wYYY=ukEjp;|bx)lc8PgJfVZ;5KPm{f{pPq?t@EPQ< zY%~8c#HvI%HSEwUHf6>O9mqM}iCZCUI$=gs(ay&-80Rbbtsnvc(%2!?9PCglb~P;_ zReR=)t5|IdIc=V6sPBhP-}+<=K>;LVKadpcM?09nN337sw(vorcWx801_WdLq=6Hk z26g5jcc!!lkA8ugs>LqNk}I(TjfMOT77R4(N(=)q-uPUsDV`}nNYb^3d`y_4;RX;^ zNm{!Q%^nnC3L_+hX)^nD)R=s-q#*_g``Bb+OaUG{T@^+Uka)~QG^QglK5t z5#c!k#0*_$%)qge49**X`q2n~}4%?DqK;EmAr z!~lU$hiLYoD7(@{M`R@^4j9ZLcoqQ7Lsz>AG~r}|T|iE-um^EZS2}r*O*W(8A68z|xz&SfwjcAA%94JTz9*ps4Bk*#tB$&w#AgAdwoU$S-B4 zCatS#%oo%-mdNat`FI(qOG2U(7in!ud~24NxGscn2t?YOBJEFsq)RG%d{B~DBC|K) zlu5*dNW)}B8k>^cLIkAfrRc}j6dEnGKopB%5X5x7W&(|>I6eSa@q+55>qZLPxPrsS z771kv=vzr8F18X0XKHl>Ss7&!i(s}l4hXD;851dHN`gGZggO^x2kT$Zz;xL-OXEyn z)eFj(u0Dhzh&tbmSZy>zjQP$Z63W!w-*F40o{tr7J~bns^0P&1Q~QsSaW%$D7St?V zpK^G-O2(HNniJNnY)}4&L*fgqt~3D!t5EiQuab#kslte#FQImQt`($oN>Ty&x Date: Tue, 9 Sep 2025 09:57:09 +0200 Subject: [PATCH 2/2] #13563 fix checkstyle Signed-off-by: Ludovic Orban --- .../jetty/http/content/FileMappingHttpContentFactoryTest.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/jetty-core/jetty-http/src/test/java/org/eclipse/jetty/http/content/FileMappingHttpContentFactoryTest.java b/jetty-core/jetty-http/src/test/java/org/eclipse/jetty/http/content/FileMappingHttpContentFactoryTest.java index 2ed03f0a5619..32d936c82d15 100644 --- a/jetty-core/jetty-http/src/test/java/org/eclipse/jetty/http/content/FileMappingHttpContentFactoryTest.java +++ b/jetty-core/jetty-http/src/test/java/org/eclipse/jetty/http/content/FileMappingHttpContentFactoryTest.java @@ -19,8 +19,8 @@ import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; - import java.nio.file.StandardOpenOption; + import org.eclipse.jetty.http.MimeTypes; import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.io.Content; @@ -28,7 +28,6 @@ import org.eclipse.jetty.toolchain.test.jupiter.WorkDir; import org.eclipse.jetty.toolchain.test.jupiter.WorkDirExtension; import org.eclipse.jetty.util.Blocker; -import org.eclipse.jetty.util.URIUtil; import org.eclipse.jetty.util.resource.Resource; import org.eclipse.jetty.util.resource.ResourceFactory; import org.junit.jupiter.api.Test;