Author: eric
Date: Sun Jan 20 16:01:56 2013
New Revision: 1435870

URL: http://svn.apache.org/viewvc?rev=1435870&view=rev
Log:
Fix APPEND IMAP command can result in JAMES IMAP waiting indefinitely for data 
with a SwitchableDelimiterBasedFrameDecoder (JAMES-1436)

Added:
    
james/server/trunk/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/SwitchableDelimiterBasedFrameDecoder.java
Modified:
    
james/server/trunk/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/IMAPServer.java
    
james/server/trunk/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/ImapRequestFrameDecoder.java

Modified: 
james/server/trunk/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/IMAPServer.java
URL: 
http://svn.apache.org/viewvc/james/server/trunk/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/IMAPServer.java?rev=1435870&r1=1435869&r2=1435870&view=diff
==============================================================================
--- 
james/server/trunk/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/IMAPServer.java
 (original)
+++ 
james/server/trunk/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/IMAPServer.java
 Sun Jan 20 16:01:56 2013
@@ -40,7 +40,6 @@ import org.jboss.netty.channel.ChannelPi
 import org.jboss.netty.channel.ChannelPipelineFactory;
 import org.jboss.netty.channel.ChannelUpstreamHandler;
 import org.jboss.netty.channel.group.ChannelGroup;
-import org.jboss.netty.handler.codec.frame.DelimiterBasedFrameDecoder;
 import org.jboss.netty.handler.codec.frame.Delimiters;
 import org.jboss.netty.handler.codec.oneone.OneToOneEncoder;
 import org.jboss.netty.handler.execution.ExecutionHandler;
@@ -70,12 +69,10 @@ public class IMAPServer extends Abstract
 
     private boolean plainAuthDisallowed;
     
-    
     private int timeout;
     
     private int literalSizeLimit;
 
-
     // Use a big default
     public final static int DEFAULT_MAX_LINE_LENGTH = 65536;
 
@@ -155,7 +152,8 @@ public class IMAPServer extends Abstract
 
                 // Add the text line decoder which limit the max line length,
                 // don't strip the delimiter and use CRLF as delimiter
-                pipeline.addLast(FRAMER, new 
DelimiterBasedFrameDecoder(maxLineLength, false, Delimiters.lineDelimiter()));
+                // Use a SwitchableDelimiterBasedFrameDecoder, see JAMES-1436
+                pipeline.addLast(FRAMER, new 
SwitchableDelimiterBasedFrameDecoder(maxLineLength, false, 
Delimiters.lineDelimiter()));
                
                 Encryption secure = getEncryption();
                 if (secure != null && !secure.isStartTLS()) {

Modified: 
james/server/trunk/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/ImapRequestFrameDecoder.java
URL: 
http://svn.apache.org/viewvc/james/server/trunk/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/ImapRequestFrameDecoder.java?rev=1435870&r1=1435869&r2=1435870&view=diff
==============================================================================
--- 
james/server/trunk/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/ImapRequestFrameDecoder.java
 (original)
+++ 
james/server/trunk/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/ImapRequestFrameDecoder.java
 Sun Jan 20 16:01:56 2013
@@ -39,6 +39,7 @@ import org.jboss.netty.channel.Channel;
 import org.jboss.netty.channel.ChannelFutureListener;
 import org.jboss.netty.channel.ChannelHandler;
 import org.jboss.netty.channel.ChannelHandlerContext;
+import org.jboss.netty.channel.ChannelPipeline;
 import org.jboss.netty.channel.ChannelStateEvent;
 import org.jboss.netty.handler.codec.frame.FrameDecoder;
 
@@ -174,10 +175,15 @@ public class ImapRequestFrameDecoder ext
                     reader.consumeLine();
                 }
                 
-                ChannelHandler handler = (ChannelHandler) 
attachment.remove(FRAMER);
-                if (handler != null) {
-                    channel.getPipeline().addFirst(FRAMER, handler);
-                }
+                // Code portion commented further to JAMES-1436.
+                // TODO Remove if no negative feedback on JAMES-1436.
+//                ChannelHandler handler = (ChannelHandler) 
attachment.remove(FRAMER);
+//                if (handler != null) {
+//                    channel.getPipeline().addFirst(FRAMER, handler);
+//                }
+                
+                ((SwitchableDelimiterBasedFrameDecoder) 
channel.getPipeline().get(FRAMER)).enableFraming();
+                
                 attachment.clear();
                 return message;
             } catch (NettyImapRequestLineReader.NotEnoughDataException e) {
@@ -187,9 +193,17 @@ public class ImapRequestFrameDecoder ext
                 // store the needed data size for later usage
                 attachment.put(NEEDED_DATA, neededData);
                 
-
-                ChannelHandler handler = channel.getPipeline().remove(FRAMER);
-                attachment.put(FRAMER, handler);
+                final ChannelPipeline pipeline = channel.getPipeline();
+                final ChannelHandlerContext framerContext = 
pipeline.getContext(FRAMER);
+                
+                // Code portion commented further to JAMES-1436.
+                // TODO Remove if no negative feedback on JAMES-1436.
+//                ChannelHandler handler = 
channel.getPipeline().remove(FRAMER);
+//                attachment.put(FRAMER, handler);
+
+                // SwitchableDelimiterBasedFrameDecoder added further to 
JAMES-1436.
+                final SwitchableDelimiterBasedFrameDecoder framer = 
(SwitchableDelimiterBasedFrameDecoder) pipeline.get(FRAMER);
+                framer.disableFraming(framerContext);
                 
                 buffer.resetReaderIndex();
                 return null;

Added: 
james/server/trunk/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/SwitchableDelimiterBasedFrameDecoder.java
URL: 
http://svn.apache.org/viewvc/james/server/trunk/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/SwitchableDelimiterBasedFrameDecoder.java?rev=1435870&view=auto
==============================================================================
--- 
james/server/trunk/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/SwitchableDelimiterBasedFrameDecoder.java
 (added)
+++ 
james/server/trunk/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/SwitchableDelimiterBasedFrameDecoder.java
 Sun Jan 20 16:01:56 2013
@@ -0,0 +1,64 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.imapserver.netty;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.jboss.netty.channel.ChannelHandlerContext;
+import org.jboss.netty.channel.Channels;
+import org.jboss.netty.channel.MessageEvent;
+import org.jboss.netty.handler.codec.frame.DelimiterBasedFrameDecoder;
+
+public class SwitchableDelimiterBasedFrameDecoder extends 
DelimiterBasedFrameDecoder {
+
+       private volatile boolean framingEnabled = true;
+       private volatile ChannelBuffer cumulation;
+
+       public SwitchableDelimiterBasedFrameDecoder(final int maxFrameLength, 
final boolean stripDelimiter, final ChannelBuffer... delimiters) {
+               super(maxFrameLength, stripDelimiter, delimiters);
+       }
+
+       @Override
+       public synchronized void messageReceived(final ChannelHandlerContext 
ctx, final MessageEvent e) throws Exception {
+               if(this.framingEnabled) {
+                       super.messageReceived(ctx, e);
+               } else {
+                       ctx.sendUpstream(e);
+               }
+       }
+
+       public synchronized void enableFraming() {
+               this.framingEnabled = true;
+
+       }
+
+       public synchronized void disableFraming(final ChannelHandlerContext 
ctx) {
+               this.framingEnabled = false;
+               if(this.cumulation != null && this.cumulation.readable()) {
+                       final ChannelBuffer spareBytes = 
this.cumulation.readBytes(this.cumulation.readableBytes());
+                       Channels.fireMessageReceived(ctx, spareBytes);
+               }
+       }
+
+       @Override
+       protected synchronized ChannelBuffer 
createCumulationDynamicBuffer(final ChannelHandlerContext ctx) {
+               this.cumulation = super.createCumulationDynamicBuffer(ctx);
+               return this.cumulation;
+       }
+}
\ No newline at end of file



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to