Skip to content

Commit

Permalink
fix #411: Apply compression predicate before sendFile invocation
Browse files Browse the repository at this point in the history
Compression predicate has to be applied before sendFile invocation
because when there is a compression in place, send file with zero copy
cannot be used.
  • Loading branch information
violetagg committed Aug 16, 2018
1 parent fc9e43f commit caa1adf
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 8 deletions.
2 changes: 1 addition & 1 deletion src/main/java/reactor/ipc/netty/http/HttpOperations.java
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ public Mono<Void> 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()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<Void> sendNotFound() {
return this.status(HttpResponseStatus.NOT_FOUND)
Expand Down
31 changes: 24 additions & 7 deletions src/test/java/reactor/ipc/netty/http/server/HttpSendFileTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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"));
}
Expand Down Expand Up @@ -111,26 +112,42 @@ 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<HttpServerResponse, NettyOutbound> fn) {
assertSendFile(fn, false);
assertSendFile(fn, false, (req, res) -> false);
}

private void assertSendFile(Function<HttpServerResponse, NettyOutbound> fn, boolean compression) {
assertSendFile(fn, compression,
private void assertSendFile(Function<HttpServerResponse, NettyOutbound> fn, boolean compression,
BiPredicate<HttpServerRequest, HttpServerResponse> 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 é.")
.contains("1024 mark here -><- 1024 mark here")
.endsWith("End of File"));
}

private void assertSendFile(Function<HttpServerResponse, NettyOutbound> fn, boolean compression, Consumer<String> bodyAssertion) {
private void assertSendFile(Function<HttpServerResponse, NettyOutbound> fn, boolean compression,
BiPredicate<HttpServerRequest, HttpServerResponse> compressionPredicate, Consumer<String> 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();
Expand Down

0 comments on commit caa1adf

Please sign in to comment.