You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by se...@apache.org on 2014/04/10 02:14:56 UTC

svn commit: r1586180 - in /commons/proper/net/trunk/src: changes/changes.xml main/java/org/apache/commons/net/imap/IMAP.java main/java/org/apache/commons/net/imap/IMAPReply.java

Author: sebb
Date: Thu Apr 10 00:14:56 2014
New Revision: 1586180

URL: http://svn.apache.org/r1586180
Log:
NET-535 IMAP FETCH can overflow reply buffer; provide for partial responses

Modified:
    commons/proper/net/trunk/src/changes/changes.xml
    commons/proper/net/trunk/src/main/java/org/apache/commons/net/imap/IMAP.java
    commons/proper/net/trunk/src/main/java/org/apache/commons/net/imap/IMAPReply.java

Modified: commons/proper/net/trunk/src/changes/changes.xml
URL: http://svn.apache.org/viewvc/commons/proper/net/trunk/src/changes/changes.xml?rev=1586180&r1=1586179&r2=1586180&view=diff
==============================================================================
--- commons/proper/net/trunk/src/changes/changes.xml [utf-8] (original)
+++ commons/proper/net/trunk/src/changes/changes.xml [utf-8] Thu Apr 10 00:14:56 2014
@@ -65,6 +65,9 @@ The <action> type attribute can be add,u
         <release version="3.4" date="2014-01-??" description="
 This is mainly a bug-fix release. See further details below.
         ">
+            <action issue="NET-535" type="add" dev="sebb">
+            IMAP FETCH can overflow reply buffer; provide for partial responses
+            </action>
             <action issue="NET-534" type="update" dev="sebb">
             Unnecesssary call to getReplyString() if no listeners configured
             </action>

Modified: commons/proper/net/trunk/src/main/java/org/apache/commons/net/imap/IMAP.java
URL: http://svn.apache.org/viewvc/commons/proper/net/trunk/src/main/java/org/apache/commons/net/imap/IMAP.java?rev=1586180&r1=1586179&r2=1586180&view=diff
==============================================================================
--- commons/proper/net/trunk/src/main/java/org/apache/commons/net/imap/IMAP.java (original)
+++ commons/proper/net/trunk/src/main/java/org/apache/commons/net/imap/IMAP.java Thu Apr 10 00:14:56 2014
@@ -64,6 +64,23 @@ public class IMAP extends SocketClient
     private int _replyCode;
     private final List<String> _replyLines;
 
+    /**
+     * Implement this interface and register it via {@link #setChunkListener(IMAPChunkListener)}
+     * in order to get access to multi-line partial command responses.
+     * Useful when processing large FETCH responses.
+     */
+    public interface IMAPChunkListener {
+        /**
+         * Called when a multi-line partial response has been received.
+         * @param imap the instance, get the response 
+         * by calling {@link #getReplyString()} or {@link #getReplyStrings()}
+         * @return {@code true} if the reply buffer is to be cleared on return
+         */
+        boolean chunkReceived(IMAP imap);
+    }
+
+    private volatile IMAPChunkListener __chunkListener;
+
     private final char[] _initialID = { 'A', 'A', 'A', 'A' };
 
     /**
@@ -111,6 +128,7 @@ public class IMAP extends SocketClient
         if (wantTag) {
             while(IMAPReply.isUntagged(line)) {
                 int literalCount = IMAPReply.literalCount(line);
+                final boolean isMultiLine = literalCount >= 0;
                 while (literalCount >= 0) {
                     line=_reader.readLine();
                     if (line == null) {
@@ -119,6 +137,16 @@ public class IMAP extends SocketClient
                     _replyLines.add(line);
                     literalCount -= (line.length() + 2); // Allow for CRLF
                 }
+                if (isMultiLine) {
+                    IMAPChunkListener il = __chunkListener;
+                    if (il != null) {
+                        boolean clear = il.chunkReceived(this);
+                        if (clear) {
+                            fireReplyReceived(IMAPReply.PARTIAL, getReplyString());
+                            _replyLines.clear();
+                        }
+                    }
+                }
                 line = _reader.readLine(); // get next chunk or final tag
                 if (line == null) {
                     throw new EOFException("Connection closed without indication.");
@@ -366,6 +394,19 @@ public class IMAP extends SocketClient
     }
 
     /**
+     * Sets the current chunk listener.
+     * If a listener is registered and the implementation returns true,
+     * then any registered 
+     * {@link org.apache.commons.net.PrintCommandListener PrintCommandListener}
+     * instances will be invoked with the partial response and a status of
+     * {@link IMAPReply#PARTIAL} to indicate that the final reply code is not yet known.
+     * @param listener the class to use, or {@code null} to disable
+     */
+    public void setChunkListener(IMAPChunkListener listener) {
+        __chunkListener = listener;
+    }
+
+    /**
      * Generates a new command ID (tag) for a command.
      * @return a new command ID (tag) for an IMAP command.
      */

Modified: commons/proper/net/trunk/src/main/java/org/apache/commons/net/imap/IMAPReply.java
URL: http://svn.apache.org/viewvc/commons/proper/net/trunk/src/main/java/org/apache/commons/net/imap/IMAPReply.java?rev=1586180&r1=1586179&r2=1586180&view=diff
==============================================================================
--- commons/proper/net/trunk/src/main/java/org/apache/commons/net/imap/IMAPReply.java (original)
+++ commons/proper/net/trunk/src/main/java/org/apache/commons/net/imap/IMAPReply.java Thu Apr 10 00:14:56 2014
@@ -41,6 +41,13 @@ public final class IMAPReply
     /** The reply code indicating command continuation. */
     public static final int CONT = 3;
 
+    /**
+     * The reply code indicating a partial response. 
+     * This is used when a chunk listener is registered and the listener
+     * requests that the reply lines are cleared on return. 
+     */
+    public static final int PARTIAL = 3;
+
     /** The IMAP reply String indicating success of an operation. */
     private static final String IMAP_OK = "OK";