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 <btell...@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-unsubscr...@james.apache.org
For additional commands, e-mail: notifications-h...@james.apache.org

Reply via email to