You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@james.apache.org by bt...@apache.org on 2024/02/28 17:32:08 UTC
(james-project) 07/07: JAMES-4007 Manage IMAP litteral with Leak aware
This is an automated email from the ASF dual-hosted git repository.
btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git
commit 1fb2e4b4f784bbe8c1e21c7c73e4a2bcbc920337
Author: Benoit TELLIER <bt...@linagora.com>
AuthorDate: Tue Feb 27 10:34:11 2024 +0100
JAMES-4007 Manage IMAP litteral with Leak aware
---
.../imapserver/netty/ImapRequestFrameDecoder.java | 52 ++++++++++++++++++----
.../netty/NettyStreamImapRequestLineReader.java | 18 ++++----
2 files changed, 51 insertions(+), 19 deletions(-)
diff --git a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/ImapRequestFrameDecoder.java b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/ImapRequestFrameDecoder.java
index 4f9fd126a8..fbd8930423 100644
--- a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/ImapRequestFrameDecoder.java
+++ b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/ImapRequestFrameDecoder.java
@@ -36,6 +36,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
+import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.james.imap.api.ImapMessage;
import org.apache.james.imap.api.ImapSessionState;
@@ -43,6 +44,7 @@ import org.apache.james.imap.api.process.ImapSession;
import org.apache.james.imap.decode.DecodingException;
import org.apache.james.imap.decode.ImapDecoder;
import org.apache.james.imap.decode.ImapRequestLineReader;
+import org.apache.james.lifecycle.api.Disposable.LeakAware;
import org.apache.james.protocols.netty.LineHandlerAware;
import com.github.fge.lambdas.Throwing;
@@ -230,10 +232,7 @@ public class ImapRequestFrameDecoder extends ByteToMessageDecoder implements Net
// Not doing this causes IDLEd IMAP connections to clear IMAP append literal while they are processed.
attachment.remove(SUBSCRIPTION);
parseImapMessage(ctx, null, attachment, Pair.of(reader, size), readerIndex)
- .ifPresent(message -> {
-
- ctx.fireChannelRead(message);
- });
+ .ifPresent(ctx::fireChannelRead);
} catch (DecodingException e) {
ctx.fireExceptionCaught(e);
}
@@ -253,18 +252,53 @@ public class ImapRequestFrameDecoder extends ByteToMessageDecoder implements Net
}
}
+ public static class FileHolderInner extends LeakAware.Resource {
+ public static FileHolderInner create() throws IOException {
+ return new FileHolderInner(Files.createTempFile("imap-literal", ".tmp").toFile());
+ }
+
+ private final File file;
+
+ private FileHolderInner(File file) {
+ super(() -> FileUtils.deleteQuietly(file));
+ this.file = file;
+ }
+
+ public File getFile() {
+ return file;
+ }
+ }
+
+ public static class FileHolder extends LeakAware<FileHolderInner> {
+ public static FileHolder create() throws IOException {
+ return new FileHolder(FileHolderInner.create());
+ }
+
+ private final FileHolderInner file;
+
+ private FileHolder(FileHolderInner file) {
+ super(file);
+ this.file = file;
+ }
+
+ public File getFile() {
+ return file.file;
+ }
+
+ }
+
static class FileChunkConsumer implements Consumer<byte[]> {
private final int size;
private final AtomicInteger written = new AtomicInteger(0);
private final AtomicBoolean initialized = new AtomicBoolean(false);
private OutputStream outputStream;
- private File file;
+ private FileHolder file;
FileChunkConsumer(int size) {
this.size = size;
}
- public File getFile() {
+ public FileHolder getFile() {
return file;
}
@@ -279,8 +313,8 @@ public class ImapRequestFrameDecoder extends ByteToMessageDecoder implements Net
private void initialize() {
try {
- file = Files.createTempFile("imap-literal", ".tmp").toFile();
- outputStream = new FileOutputStream(file, true);
+ file = FileHolder.create();
+ outputStream = new FileOutputStream(file.getFile(), true);
initialized.set(true);
} catch (IOException e) {
throw new RuntimeException(e);
@@ -318,7 +352,7 @@ public class ImapRequestFrameDecoder extends ByteToMessageDecoder implements Net
outputStream.close();
}
if (file != null) {
- Files.delete(file.toPath());
+ file.dispose();
}
})).subscribeOn(Schedulers.boundedElastic())
.subscribe();
diff --git a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/NettyStreamImapRequestLineReader.java b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/NettyStreamImapRequestLineReader.java
index e567013f86..ee3d533a21 100644
--- a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/NettyStreamImapRequestLineReader.java
+++ b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/NettyStreamImapRequestLineReader.java
@@ -19,13 +19,11 @@
package org.apache.james.imapserver.netty;
import java.io.Closeable;
-import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
-import org.apache.commons.io.FileUtils;
import org.apache.james.imap.api.display.HumanReadableText;
import org.apache.james.imap.decode.DecodingException;
import org.apache.james.imap.message.Literal;
@@ -44,10 +42,10 @@ public class NettyStreamImapRequestLineReader extends AbstractNettyImapRequestLi
private final long offset;
private final int size;
private final boolean extraCRLF;
- private final File file;
+ private final ImapRequestFrameDecoder.FileHolder file;
private final AbstractNettyImapRequestLineReader reader;
- private FileLiteral(long offset, int size, boolean extraCRLF, File file, AbstractNettyImapRequestLineReader reader) {
+ private FileLiteral(long offset, int size, boolean extraCRLF, ImapRequestFrameDecoder.FileHolder file, AbstractNettyImapRequestLineReader reader) {
this.offset = offset;
this.size = size;
this.extraCRLF = extraCRLF;
@@ -57,19 +55,19 @@ public class NettyStreamImapRequestLineReader extends AbstractNettyImapRequestLi
@Override
public void close() {
- Mono.fromRunnable(Throwing.runnable(() -> FileUtils.deleteQuietly(file)))
+ Mono.fromRunnable(Throwing.runnable(() -> file.dispose()))
.subscribeOn(Schedulers.boundedElastic())
.subscribe();
}
@Override
public long size() {
- return Math.min(file.length() - offset, size);
+ return Math.min(file.getFile().length() - offset, size);
}
@Override
public InputStream getInputStream() throws IOException {
- FileInputStream fileInputStream = new FileInputStream(file);
+ FileInputStream fileInputStream = new FileInputStream(file.getFile());
fileInputStream.skip(offset);
InputStream limitedStream = ByteStreams.limit(fileInputStream, size);
if (extraCRLF) {
@@ -80,14 +78,14 @@ public class NettyStreamImapRequestLineReader extends AbstractNettyImapRequestLi
}
}
- private final File backingFile;
+ private final ImapRequestFrameDecoder.FileHolder backingFile;
private final CountingInputStream in;
- public NettyStreamImapRequestLineReader(Channel channel, File file, boolean retry) {
+ public NettyStreamImapRequestLineReader(Channel channel, ImapRequestFrameDecoder.FileHolder file, boolean retry) {
super(channel, retry);
this.backingFile = file;
try {
- this.in = new CountingInputStream(new FileInputStream(file));
+ this.in = new CountingInputStream(new FileInputStream(file.getFile()));
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
}
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org