1
0
mirror of https://github.com/moparisthebest/k-9 synced 2025-03-03 10:01:59 -05:00

Better handling of IMAP FETCH responses.

Fixes issue 1068
This commit is contained in:
cketti 2010-02-10 13:52:25 +00:00
parent e83a428107
commit 2bd4f9632b
2 changed files with 79 additions and 55 deletions

View File

@ -442,6 +442,36 @@ public class ImapResponseParser
throw new MessagingException("Unable to parse IMAP datetime", pe); throw new MessagingException("Unable to parse IMAP datetime", pe);
} }
} }
public boolean containsKey(Object key)
{
if (key == null)
{
return false;
}
for (int i = 0, count = size(); i < count; i++)
{
if (key.equals(get(i)))
{
return true;
}
}
return false;
}
public int getKeyIndex(Object key)
{
for (int i = 0, count = size(); i < count; i++)
{
if (key.equals(get(i)))
{
return i;
}
}
throw new IllegalArgumentException("getKeyIndex() only works for keys that are in the collection.");
}
private Date parseDate(String value) throws ParseException private Date parseDate(String value) throws ParseException
{ {

View File

@ -41,13 +41,6 @@ import java.util.concurrent.atomic.AtomicInteger;
* TODO Need a default response handler for things like folder updates * TODO Need a default response handler for things like folder updates
* TODO In fetch(), if we need a ImapMessage and were given * TODO In fetch(), if we need a ImapMessage and were given
* something else we can try to do a pre-fetch first. * something else we can try to do a pre-fetch first.
*
* ftp://ftp.isi.edu/in-notes/rfc2683.txt When a client asks for
* certain information in a FETCH command, the server may return the requested
* information in any order, not necessarily in the order that it was requested.
* Further, the server may return the information in separate FETCH responses
* and may also return information that was not explicitly requested (to reflect
* to the client changes in the state of the subject message).
* </pre> * </pre>
*/ */
public class ImapStore extends Store public class ImapStore extends Store
@ -1109,10 +1102,11 @@ public class ImapStore extends Store
listener.messageStarted(uid, messageNumber++, messageMap.size()); listener.messageStarted(uid, messageNumber++, messageMap.size());
} }
if (fp.contains(FetchProfile.Item.FLAGS)) ImapMessage imapMessage = (ImapMessage) message;
if (fetchList.containsKey("FLAGS"))
{ {
ImapList flags = fetchList.getKeyedList("FLAGS"); ImapList flags = fetchList.getKeyedList("FLAGS");
ImapMessage imapMessage = (ImapMessage) message;
if (flags != null) if (flags != null)
{ {
for (int i = 0, count = flags.size(); i < count; i++) for (int i = 0, count = flags.size(); i < count; i++)
@ -1137,19 +1131,18 @@ public class ImapStore extends Store
} }
} }
} }
if (fp.contains(FetchProfile.Item.ENVELOPE))
if (fetchList.containsKey("INTERNALDATE"))
{ {
Date internalDate = fetchList.getKeyedDate("INTERNALDATE"); Date internalDate = fetchList.getKeyedDate("INTERNALDATE");
int size = fetchList.getKeyedNumber("RFC822.SIZE");
InputStream headerStream = fetchList.getLiteral(fetchList.size() - 1);
ImapMessage imapMessage = (ImapMessage) message;
message.setInternalDate(internalDate); message.setInternalDate(internalDate);
imapMessage.setSize(size);
imapMessage.parse(headerStream);
} }
if (fp.contains(FetchProfile.Item.STRUCTURE)) if (fetchList.containsKey("RFC822.SIZE"))
{
int size = fetchList.getKeyedNumber("RFC822.SIZE");
imapMessage.setSize(size);
}
if (fetchList.containsKey("BODYSTRUCTURE"))
{ {
ImapList bs = fetchList.getKeyedList("BODYSTRUCTURE"); ImapList bs = fetchList.getKeyedList("BODYSTRUCTURE");
if (bs != null) if (bs != null)
@ -1166,49 +1159,50 @@ public class ImapStore extends Store
} }
} }
} }
if (fp.contains(FetchProfile.Item.BODY))
if (fetchList.containsKey("BODY"))
{ {
InputStream bodyStream = fetchList.getLiteral(fetchList.size() - 1); int index = fetchList.getKeyIndex("BODY") + 2;
ImapMessage imapMessage = (ImapMessage) message;
imapMessage.parse(bodyStream); boolean partFound = false;
} for (Object o : fp)
if (fp.contains(FetchProfile.Item.BODY_SANE))
{
InputStream bodyStream = fetchList.getLiteral(fetchList.size() - 1);
ImapMessage imapMessage = (ImapMessage) message;
imapMessage.parse(bodyStream);
}
for (Object o : fp)
{
if (o instanceof Part)
{ {
Part part = (Part) o; if (o instanceof Part)
Object literal = fetchList.getObject(fetchList.size() - 1);
if (literal instanceof InputStream)
{ {
InputStream bodyStream = (InputStream)literal; partFound = true;
String contentType = part.getContentType(); Part part = (Part) o;
String contentTransferEncoding = part.getHeader( Object literal = fetchList.getLiteral(index);
MimeHeader.HEADER_CONTENT_TRANSFER_ENCODING)[0]; if (literal instanceof InputStream)
part.setBody(MimeUtility.decodeBody( {
bodyStream, InputStream bodyStream = (InputStream)literal;
contentTransferEncoding)); String contentTransferEncoding = part.getHeader(
} MimeHeader.HEADER_CONTENT_TRANSFER_ENCODING)[0];
else if (literal instanceof String) part.setBody(MimeUtility.decodeBody(
{ bodyStream,
String bodyString = (String)literal; contentTransferEncoding));
}
else if (literal instanceof String)
{
String bodyString = (String)literal;
if (K9.DEBUG) if (K9.DEBUG)
Log.v(K9.LOG_TAG, "Part is a String: '" + bodyString + "' for " + getLogId()); Log.v(K9.LOG_TAG, "Part is a String: '" + bodyString + "' for " + getLogId());
InputStream bodyStream = new ByteArrayInputStream(bodyString.getBytes()); InputStream bodyStream = new ByteArrayInputStream(bodyString.getBytes());
String contentTransferEncoding = part.getHeader( String contentTransferEncoding = part.getHeader(
MimeHeader.HEADER_CONTENT_TRANSFER_ENCODING)[0]; MimeHeader.HEADER_CONTENT_TRANSFER_ENCODING)[0];
part.setBody(MimeUtility.decodeBody( part.setBody(MimeUtility.decodeBody(
bodyStream, bodyStream,
contentTransferEncoding)); contentTransferEncoding));
}
} }
} }
if (!partFound)
{
InputStream bodyStream = fetchList.getLiteral(index);
imapMessage.parse(bodyStream);
}
} }
if (listener != null) if (listener != null)
@ -2531,7 +2525,7 @@ public class ImapStore extends Store
idling.set(true); idling.set(true);
doneSent.set(false); doneSent.set(false);
mConnection.setReadTimeout(IDLE_READ_TIMEOUT); mConnection.setReadTimeout(IDLE_READ_TIMEOUT);
untaggedResponses = executeSimpleCommand("IDLE", false, ImapFolderPusher.this); untaggedResponses = executeSimpleCommand(COMMAND_IDLE, false, ImapFolderPusher.this);
idling.set(false); idling.set(false);
} }