diff --git a/src/java/davmail/exchange/ExchangeSession.java b/src/java/davmail/exchange/ExchangeSession.java index 5006a24b..46bfcbfb 100644 --- a/src/java/davmail/exchange/ExchangeSession.java +++ b/src/java/davmail/exchange/ExchangeSession.java @@ -729,6 +729,8 @@ public abstract class ExchangeSession { IMAP_MESSAGE_ATTRIBUTES.add("deleted"); IMAP_MESSAGE_ATTRIBUTES.add("date"); IMAP_MESSAGE_ATTRIBUTES.add("lastmodified"); + // OSX IMAP requests content-class + IMAP_MESSAGE_ATTRIBUTES.add("contentclass"); } protected static final Set UID_MESSAGE_ATTRIBUTES = new HashSet(); @@ -1632,6 +1634,10 @@ public abstract class ExchangeSession { * Message uid. */ public String uid; + /** + * Message content class. + */ + public String contentClass; /** * Message IMAP uid, unique in folder (x0e230003). */ diff --git a/src/java/davmail/exchange/dav/DavExchangeSession.java b/src/java/davmail/exchange/dav/DavExchangeSession.java index 19001363..a5f779da 100644 --- a/src/java/davmail/exchange/dav/DavExchangeSession.java +++ b/src/java/davmail/exchange/dav/DavExchangeSession.java @@ -1996,6 +1996,7 @@ public class DavExchangeSession extends ExchangeSession { message.permanentUrl = getURLPropertyIfExists(properties, "permanenturl"); message.size = getIntPropertyIfExists(properties, "messageSize"); message.uid = getPropertyIfExists(properties, "uid"); + message.contentClass = getPropertyIfExists(properties, "contentclass"); message.imapUid = getLongPropertyIfExists(properties, "imapUid"); message.read = "1".equals(getPropertyIfExists(properties, "read")); message.junk = "1".equals(getPropertyIfExists(properties, "junk")); diff --git a/src/java/davmail/exchange/ews/EwsExchangeSession.java b/src/java/davmail/exchange/ews/EwsExchangeSession.java index 07f07d47..610a8df4 100644 --- a/src/java/davmail/exchange/ews/EwsExchangeSession.java +++ b/src/java/davmail/exchange/ews/EwsExchangeSession.java @@ -568,6 +568,7 @@ public class EwsExchangeSession extends ExchangeSession { message.size = response.getInt(Field.get("messageSize").getResponseName()); message.uid = response.get(Field.get("uid").getResponseName()); + message.contentClass = response.get(Field.get("contentclass").getResponseName()); message.imapUid = response.getLong(Field.get("imapUid").getResponseName()); message.read = response.getBoolean(Field.get("read").getResponseName()); message.junk = response.getBoolean(Field.get("junk").getResponseName()); diff --git a/src/java/davmail/imap/ImapConnection.java b/src/java/davmail/imap/ImapConnection.java index 5ff0619a..a5cd7ce3 100644 --- a/src/java/davmail/imap/ImapConnection.java +++ b/src/java/davmail/imap/ImapConnection.java @@ -418,7 +418,7 @@ public class ImapConnection extends AbstractConnection { session.moveMessage(message, targetName); } } - sendClient(commandId + " OK "+command+" completed"); + sendClient(commandId + " OK " + command + " completed"); } } catch (HttpException e) { sendClient(commandId + " NO " + e.getMessage()); @@ -753,8 +753,6 @@ public class ImapConnection extends AbstractConnection { InputStream partInputStream = null; OutputStream partOutputStream = null; - // load message - MimeMessage mimeMessage = message.getMimeMessage(); // try to parse message part index String partIndexString = StringUtil.getToken(param, "[", "]"); if ("".equals(partIndexString) || partIndexString == null) { @@ -764,16 +762,23 @@ public class ImapConnection extends AbstractConnection { } else if ("TEXT".equals(partIndexString)) { // write message without headers partOutputStream = new PartialOutputStream(baos, startIndex, maxSize); - partInputStream = mimeMessage.getRawInputStream(); + partInputStream = message.getMimeMessage().getRawInputStream(); } else if ("RFC822.HEADER".equals(param) || partIndexString.startsWith("HEADER")) { // Header requested fetch headers String[] requestedHeaders = getRequestedHeaders(partIndexString); if (requestedHeaders != null) { - Enumeration headerEnumeration = message.getMimeMessage().getMatchingHeaderLines(requestedHeaders); - while (headerEnumeration.hasMoreElements()) { - baos.write(((String) headerEnumeration.nextElement()).getBytes("UTF-8")); + // OSX Lion special flags request + if (requestedHeaders.length == 1 && "content-class".equals(requestedHeaders[0]) && message.contentClass != null) { + baos.write(message.contentClass.getBytes("UTF-8")); baos.write(13); baos.write(10); + } else { + Enumeration headerEnumeration = message.getMimeMessage().getMatchingHeaderLines(requestedHeaders); + while (headerEnumeration.hasMoreElements()) { + baos.write(((String) headerEnumeration.nextElement()).getBytes("UTF-8")); + baos.write(13); + baos.write(10); + } } } else { // write headers only @@ -781,7 +786,7 @@ public class ImapConnection extends AbstractConnection { partInputStream = message.getRawInputStream(); } } else { - MimePart bodyPart = mimeMessage; + MimePart bodyPart = message.getMimeMessage(); String[] partIndexStrings = partIndexString.split("\\."); for (String subPartIndexString : partIndexStrings) { // ignore MIME subpart index, will return full part diff --git a/src/test/davmail/imap/TestImap.java b/src/test/davmail/imap/TestImap.java index 07f3ac8f..5886e9de 100644 --- a/src/test/davmail/imap/TestImap.java +++ b/src/test/davmail/imap/TestImap.java @@ -363,5 +363,29 @@ public class TestImap extends AbstractImapTestCase { } + public void testDraftMessageMessageId() throws IOException, InterruptedException, MessagingException { + testCreateFolder(); + MimeMessage mimeMessage = new MimeMessage((Session) null); + mimeMessage.addHeader("to", Settings.getProperty("davmail.to")); + mimeMessage.setText("Test message"); + mimeMessage.setSubject("Test subject"); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + mimeMessage.writeTo(baos); + byte[] content = baos.toByteArray(); + writeLine(". APPEND testfolder (\\Seen \\Draft) {" + content.length + '}'); + assertEquals("+ send literal data", readLine()); + writeLine(new String(content)); + assertEquals(". OK APPEND completed", readFullAnswer(".")); + writeLine(". UID SEARCH UNDELETED (HEADER Message-ID "+mimeMessage.getMessageID().substring(1, mimeMessage.getMessageID().length()-1)+")"); + assertEquals(". OK SEARCH completed", readFullAnswer(".")); + + testDeleteFolder(); + } + + public void testFetchOSX() throws IOException { + testSelectInbox(); + writeLine(". FETCH 1:* (FLAGS UID BODY.PEEK[HEADER.FIELDS (content-class)])"); + assertEquals(". OK FETCH completed", readFullAnswer(".")); + } }