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 2022/05/09 01:35:36 UTC

[james-project] 06/09: JAMES-3737 Avoid a race condition upon compress

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 1f2791f3256a92224aa11dbeaadb2af32c25c014
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Tue May 3 09:04:06 2022 +0700

    JAMES-3737 Avoid a race condition upon compress
    
    Compress response and activation was sent from
    the event loop causing them to be sent and
    activated prior earlier responses. This causes
    a race condition when several commands are
    batched.
---
 .../apache/james/imap/api/process/ImapSession.java |  2 +-
 .../apache/james/imap/encode/FakeImapSession.java  |  2 +-
 .../james/imap/processor/CompressProcessor.java    |  3 +-
 .../james/imapserver/netty/NettyImapSession.java   | 37 ++++++++++++----------
 4 files changed, 23 insertions(+), 21 deletions(-)

diff --git a/protocols/imap/src/main/java/org/apache/james/imap/api/process/ImapSession.java b/protocols/imap/src/main/java/org/apache/james/imap/api/process/ImapSession.java
index f2938af6d6..62fd6bf599 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/api/process/ImapSession.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/api/process/ImapSession.java
@@ -195,7 +195,7 @@ public interface ImapSession extends CommandDetectionSession {
      * 
      * @return success
      */
-    boolean startCompression();
+    boolean startCompression(Runnable runnable);
 
     /**
      * Push in a new {@link ImapLineHandler} which is called for the next line received
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/encode/FakeImapSession.java b/protocols/imap/src/main/java/org/apache/james/imap/encode/FakeImapSession.java
index 07d9a772cc..776d98b205 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/encode/FakeImapSession.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/encode/FakeImapSession.java
@@ -145,7 +145,7 @@ public class FakeImapSession implements ImapSession {
     }
 
     @Override
-    public boolean startCompression() {
+    public boolean startCompression(Runnable runnable) {
         return false;
     }
 
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/CompressProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/CompressProcessor.java
index 0deee52959..a350901647 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/CompressProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/CompressProcessor.java
@@ -59,8 +59,7 @@ public class CompressProcessor extends AbstractProcessor<CompressRequest> implem
                     } else {
                         StatusResponse response = factory.taggedOk(request.getTag(), request.getCommand(), HumanReadableText.DEFLATE_ACTIVE);
 
-                        responder.respond(response);
-                        if (session.startCompression()) {
+                        if (session.startCompression(() -> responder.respond(response))) {
                             session.setAttribute(COMPRESSED, true);
                         }
                     }
diff --git a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/NettyImapSession.java b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/NettyImapSession.java
index 5f62999e4f..d294c963c5 100644
--- a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/NettyImapSession.java
+++ b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/NettyImapSession.java
@@ -207,28 +207,31 @@ public class NettyImapSession implements ImapSession, NettyConstants {
     }
 
     @Override
-    public boolean startCompression() {
+    public boolean startCompression(Runnable runnable) {
         if (!isCompressionSupported()) {
             return false;
         }
 
-        channel.config().setAutoRead(false);
-        ZlibDecoder decoder = new JZlibDecoder(ZlibWrapper.NONE);
-        ZlibEncoder encoder = new JZlibEncoder(ZlibWrapper.NONE, 5);
-
-        // Check if we have the SslHandler in the pipeline already
-        // if so we need to move the compress encoder and decoder
-        // behind it in the chain
-        // See JAMES-1186
-        if (channel.pipeline().get(SSL_HANDLER) == null) {
-            channel.pipeline().addFirst(ZLIB_DECODER, decoder);
-            channel.pipeline().addFirst(ZLIB_ENCODER, encoder);
-        } else {
-            channel.pipeline().addAfter(SSL_HANDLER, ZLIB_DECODER, decoder);
-            channel.pipeline().addAfter(SSL_HANDLER, ZLIB_ENCODER, encoder);
-        }
+        channel.eventLoop().execute(() -> {
+            channel.config().setAutoRead(false);
+            runnable.run();
+            ZlibDecoder decoder = new JZlibDecoder(ZlibWrapper.NONE);
+            ZlibEncoder encoder = new JZlibEncoder(ZlibWrapper.NONE, 5);
+
+            // Check if we have the SslHandler in the pipeline already
+            // if so we need to move the compress encoder and decoder
+            // behind it in the chain
+            // See JAMES-1186
+            if (channel.pipeline().get(SSL_HANDLER) == null) {
+                channel.pipeline().addFirst(ZLIB_DECODER, decoder);
+                channel.pipeline().addFirst(ZLIB_ENCODER, encoder);
+            } else {
+                channel.pipeline().addAfter(SSL_HANDLER, ZLIB_DECODER, decoder);
+                channel.pipeline().addAfter(SSL_HANDLER, ZLIB_ENCODER, encoder);
+            }
 
-        channel.config().setAutoRead(true);
+            channel.config().setAutoRead(true);
+        });
 
         return true;
     }


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org