diff --git a/src/main/java/reactor/ipc/netty/http/HttpOperations.java b/src/main/java/reactor/ipc/netty/http/HttpOperations.java index 336582e08d..6d5ec0e7f5 100644 --- a/src/main/java/reactor/ipc/netty/http/HttpOperations.java +++ b/src/main/java/reactor/ipc/netty/http/HttpOperations.java @@ -145,7 +145,7 @@ public Mono then() { protected abstract HttpMessage newFullEmptyBodyMessage(); @Override - public final NettyOutbound sendFile(Path file, long position, long count) { + public NettyOutbound sendFile(Path file, long position, long count) { Objects.requireNonNull(file); if (hasSentHeaders()) { diff --git a/src/main/java/reactor/ipc/netty/http/server/HttpServerOperations.java b/src/main/java/reactor/ipc/netty/http/server/HttpServerOperations.java index 2c8d521e80..d81412bd73 100644 --- a/src/main/java/reactor/ipc/netty/http/server/HttpServerOperations.java +++ b/src/main/java/reactor/ipc/netty/http/server/HttpServerOperations.java @@ -309,6 +309,14 @@ public NettyOutbound sendFile(Path file) { } } + @Override + public NettyOutbound sendFile(Path file, long position, long count) { + if (compressionPredicate != null && compressionPredicate.test(this, this)) { + compression(true); + } + return super.sendFile(file, position, count); + } + @Override public Mono sendNotFound() { return this.status(HttpResponseStatus.NOT_FOUND) diff --git a/src/test/java/reactor/ipc/netty/http/server/HttpSendFileTests.java b/src/test/java/reactor/ipc/netty/http/server/HttpSendFileTests.java index d2acdfaac8..a9e4d1b565 100644 --- a/src/test/java/reactor/ipc/netty/http/server/HttpSendFileTests.java +++ b/src/test/java/reactor/ipc/netty/http/server/HttpSendFileTests.java @@ -31,6 +31,7 @@ import java.nio.file.StandardOpenOption; import java.time.Duration; import java.util.concurrent.atomic.AtomicLong; +import java.util.function.BiPredicate; import java.util.function.Consumer; import java.util.function.Function; @@ -69,7 +70,7 @@ public void sendFileChunkedOffset() throws IOException, URISyntaxException { Path largeFile = Paths.get(getClass().getResource("/largeFile.txt").toURI()); long fileSize = Files.size(largeFile); assertSendFile(out -> out.sendFileChunked(largeFile, 1024, fileSize - 1024), - false, + false, (req, res) -> false, body -> assertThat(body).startsWith("<- 1024 mark here") .endsWith("End of File")); } @@ -111,16 +112,31 @@ public void sendZipFileCompressionOn() throws IOException { Path fromZipFile = zipFs.getPath("/largeFile.txt"); long fileSize = Files.size(fromZipFile); - assertSendFile(out -> out.compression(true).sendFile(fromZipFile, 0, fileSize), true); + assertSendFile(out -> out.compression(true).sendFile(fromZipFile, 0, fileSize), true, (req, res) -> false); + } + } + + @Test + public void sendZipFileCompressionPredicate() throws IOException { + Path path = Files.createTempFile(null, ".zip"); + Files.copy(this.getClass().getResourceAsStream("/zipFile.zip"), path, StandardCopyOption.REPLACE_EXISTING); + path.toFile().deleteOnExit(); + + try (FileSystem zipFs = FileSystems.newFileSystem(path, null)) { + Path fromZipFile = zipFs.getPath("/largeFile.txt"); + long fileSize = Files.size(fromZipFile); + + assertSendFile(out -> out.sendFile(fromZipFile, 0, fileSize), true, (req, res) -> true); } } private void assertSendFile(Function fn) { - assertSendFile(fn, false); + assertSendFile(fn, false, (req, res) -> false); } - private void assertSendFile(Function fn, boolean compression) { - assertSendFile(fn, compression, + private void assertSendFile(Function fn, boolean compression, + BiPredicate compressionPredicate) { + assertSendFile(fn, compression, compressionPredicate, body -> assertThat(body).startsWith("This is an UTF-8 file that is larger than 1024 bytes. " + "It contains accents like é.") @@ -128,9 +144,10 @@ private void assertSendFile(Function fn, bool .endsWith("End of File")); } - private void assertSendFile(Function fn, boolean compression, Consumer bodyAssertion) { + private void assertSendFile(Function fn, boolean compression, + BiPredicate compressionPredicate, Consumer bodyAssertion) { NettyContext context = - HttpServer.create(opt -> customizeServerOptions(opt.host("localhost"))) + HttpServer.create(opt -> customizeServerOptions(opt.host("localhost").compression(compressionPredicate))) .newHandler((req, resp) -> fn.apply(resp)) .block(); assertThat(context).isNotNull();