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