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/03/22 02:01:39 UTC

[james-project] 08/29: JAMES-3715 IMAP incorporate line overrides to the frame decoder

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 c8d2e984132be2761b4b9a472d48c59ce7c89d5f
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Mon Mar 7 15:07:00 2022 +0700

    JAMES-3715 IMAP incorporate line overrides to the frame decoder
---
 .../netty/BasicChannelUpstreamHandler.java         |  6 ++--
 .../james/protocols/netty/LineHandlerAware.java    |  4 ++-
 .../imapserver/netty/ImapLineHandlerAdapter.java   |  2 +-
 .../imapserver/netty/ImapRequestFrameDecoder.java  | 34 ++++++++++++++++++----
 .../james/imapserver/netty/NettyImapSession.java   | 12 ++++----
 5 files changed, 41 insertions(+), 17 deletions(-)

diff --git a/protocols/netty/src/main/java/org/apache/james/protocols/netty/BasicChannelUpstreamHandler.java b/protocols/netty/src/main/java/org/apache/james/protocols/netty/BasicChannelUpstreamHandler.java
index 8534a99..96a9d0d 100644
--- a/protocols/netty/src/main/java/org/apache/james/protocols/netty/BasicChannelUpstreamHandler.java
+++ b/protocols/netty/src/main/java/org/apache/james/protocols/netty/BasicChannelUpstreamHandler.java
@@ -68,7 +68,7 @@ public class BasicChannelUpstreamHandler extends ChannelInboundHandlerAdapter im
     protected final Protocol protocol;
     protected final ProtocolHandlerChain chain;
     protected final Encryption secure;
-    private final Deque<LineHandlerUpstreamHandler> behaviourOverrides = new ConcurrentLinkedDeque<>();
+    private final Deque<ChannelInboundHandlerAdapter> behaviourOverrides = new ConcurrentLinkedDeque<>();
 
     public BasicChannelUpstreamHandler(ProtocolMDCContextFactory mdcContextFactory, Protocol protocol) {
         this(mdcContextFactory, protocol, null);
@@ -150,7 +150,7 @@ public class BasicChannelUpstreamHandler extends ChannelInboundHandlerAdapter im
     @SuppressWarnings({ "unchecked", "rawtypes" })
     @Override
     public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
-        LineHandlerUpstreamHandler override = Iterables.getFirst(behaviourOverrides, null);
+        ChannelInboundHandlerAdapter override = Iterables.getFirst(behaviourOverrides, null);
         if (override != null) {
             override.channelRead(ctx, msg);
             return;
@@ -240,7 +240,7 @@ public class BasicChannelUpstreamHandler extends ChannelInboundHandlerAdapter im
     }
 
     @Override
-    public void pushLineHandler(LineHandlerUpstreamHandler lineHandlerUpstreamHandler) {
+    public void pushLineHandler(ChannelInboundHandlerAdapter lineHandlerUpstreamHandler) {
         behaviourOverrides.addFirst(lineHandlerUpstreamHandler);
     }
 
diff --git a/protocols/netty/src/main/java/org/apache/james/protocols/netty/LineHandlerAware.java b/protocols/netty/src/main/java/org/apache/james/protocols/netty/LineHandlerAware.java
index 516dadf..355d1c8 100644
--- a/protocols/netty/src/main/java/org/apache/james/protocols/netty/LineHandlerAware.java
+++ b/protocols/netty/src/main/java/org/apache/james/protocols/netty/LineHandlerAware.java
@@ -1,7 +1,9 @@
 package org.apache.james.protocols.netty;
 
+import io.netty.channel.ChannelInboundHandlerAdapter;
+
 public interface LineHandlerAware {
-    void pushLineHandler(LineHandlerUpstreamHandler lineHandlerUpstreamHandler);
+    void pushLineHandler(ChannelInboundHandlerAdapter lineHandlerUpstreamHandler);
 
     void popLineHandler();
 }
diff --git a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/ImapLineHandlerAdapter.java b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/ImapLineHandlerAdapter.java
index 82f1ac6..2f1f260 100644
--- a/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/ImapLineHandlerAdapter.java
+++ b/server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/ImapLineHandlerAdapter.java
@@ -44,7 +44,7 @@ public class ImapLineHandlerAdapter extends ChannelInboundHandlerAdapter {
     }
 
     @Override
-    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
+    public void channelRead(ChannelHandlerContext ctx, Object msg) {
         ByteBuf buf = (ByteBuf) msg;
         byte[] data;
         if (buf.hasArray()) {
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 696e54f..485362b 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
@@ -23,22 +23,27 @@ import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.OutputStream;
+import java.util.Deque;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.ConcurrentLinkedDeque;
 
 import org.apache.james.imap.api.ImapMessage;
 import org.apache.james.imap.api.ImapSessionState;
 import org.apache.james.imap.api.process.ImapSession;
 import org.apache.james.imap.decode.ImapDecoder;
 import org.apache.james.imap.decode.ImapRequestLineReader;
+import org.apache.james.protocols.netty.LineHandlerAware;
 
 import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.Iterables;
 
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
 import io.netty.channel.ChannelFutureListener;
 import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelInboundHandlerAdapter;
 import io.netty.channel.ChannelPipeline;
 import io.netty.handler.codec.ByteToMessageDecoder;
 
@@ -46,17 +51,18 @@ import io.netty.handler.codec.ByteToMessageDecoder;
 /**
  * {@link ByteToMessageDecoder} which will decode via and {@link ImapDecoder} instance
  */
-public class ImapRequestFrameDecoder extends ByteToMessageDecoder implements NettyConstants {
-
-    private final ImapDecoder decoder;
-    private final int inMemorySizeLimit;
-    private final int literalSizeLimit;
+public class ImapRequestFrameDecoder extends ByteToMessageDecoder implements NettyConstants, LineHandlerAware {
     @VisibleForTesting
     static final String NEEDED_DATA = "NEEDED_DATA";
     private static final String STORED_DATA = "STORED_DATA";
     private static final String WRITTEN_DATA = "WRITTEN_DATA";
     private static final String OUTPUT_STREAM = "OUTPUT_STREAM";
 
+    private final ImapDecoder decoder;
+    private final int inMemorySizeLimit;
+    private final int literalSizeLimit;
+    private final Deque<ChannelInboundHandlerAdapter> behaviourOverrides = new ConcurrentLinkedDeque<>();
+
     public ImapRequestFrameDecoder(ImapDecoder decoder, int inMemorySizeLimit, int literalSizeLimit) {
         this.decoder = decoder;
         this.inMemorySizeLimit = inMemorySizeLimit;
@@ -72,6 +78,12 @@ public class ImapRequestFrameDecoder extends ByteToMessageDecoder implements Net
     @Override
     @SuppressWarnings("unchecked")
     protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
+        ChannelInboundHandlerAdapter override = Iterables.getFirst(behaviourOverrides, null);
+        if (override != null) {
+            override.channelRead(ctx, in);
+            return;
+        }
+
         in.markReaderIndex();
         boolean retry = false;
 
@@ -196,4 +208,16 @@ public class ImapRequestFrameDecoder extends ByteToMessageDecoder implements Net
             }
         }
     }
+
+    @Override
+    public void pushLineHandler(ChannelInboundHandlerAdapter lineHandlerUpstreamHandler) {
+        behaviourOverrides.addFirst(lineHandlerUpstreamHandler);
+    }
+
+    @Override
+    public void popLineHandler() {
+        if (!behaviourOverrides.isEmpty()) {
+            behaviourOverrides.removeFirst();
+        }
+    }
 }
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 a70a8a6..11223ef 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
@@ -28,6 +28,7 @@ import org.apache.james.imap.api.process.ImapSession;
 import org.apache.james.imap.api.process.SelectedMailbox;
 import org.apache.james.protocols.api.Encryption;
 import org.apache.james.protocols.api.OidcSASLConfiguration;
+import org.apache.james.protocols.netty.LineHandlerAware;
 
 import io.netty.channel.Channel;
 import io.netty.handler.codec.compression.JZlibDecoder;
@@ -44,7 +45,6 @@ public class NettyImapSession implements ImapSession, NettyConstants {
     private final Encryption secure;
     private final boolean compress;
     private final Channel channel;
-    private int handlerCount;
     private final boolean requiredSSL;
     private final boolean plainAuthEnabled;
     private final SessionId sessionId;
@@ -195,16 +195,14 @@ public class NettyImapSession implements ImapSession, NettyConstants {
 
     @Override
     public void pushLineHandler(ImapLineHandler lineHandler) {
-        channel.config().setAutoRead(false);
-        channel.pipeline().addBefore(REQUEST_DECODER, "lineHandler" + handlerCount++, new ImapLineHandlerAdapter(this, lineHandler));
-        channel.config().setAutoRead(true);
+        LineHandlerAware handler = (LineHandlerAware) channel.pipeline().get(REQUEST_DECODER);
+        handler.pushLineHandler(new ImapLineHandlerAdapter(this, lineHandler));
     }
 
     @Override
     public void popLineHandler() {
-        channel.config().setAutoRead(false);
-        channel.pipeline().remove("lineHandler" + --handlerCount);
-        channel.config().setAutoRead(true);
+        LineHandlerAware handler = (LineHandlerAware) channel.pipeline().get(REQUEST_DECODER);
+        handler.popLineHandler();
     }
 
     @Override

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