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";