diff --git a/app/src/main/java/eu/faircode/email/ActivityEML.java b/app/src/main/java/eu/faircode/email/ActivityEML.java index 510d2ab0c2..e3d4a90750 100644 --- a/app/src/main/java/eu/faircode/email/ActivityEML.java +++ b/app/src/main/java/eu/faircode/email/ActivityEML.java @@ -134,7 +134,7 @@ public class ActivityEML extends ActivityBase { result.from = MessageHelper.formatAddresses(helper.getFrom()); result.to = MessageHelper.formatAddresses(helper.getTo()); result.subject = helper.getSubject(); - result.parts = helper.getMessageParts(); + result.parts = helper.getMessageParts(context); String html = result.parts.getHtml(context); if (html != null) { diff --git a/app/src/main/java/eu/faircode/email/Core.java b/app/src/main/java/eu/faircode/email/Core.java index fc904fd83e..1b6343846e 100644 --- a/app/src/main/java/eu/faircode/email/Core.java +++ b/app/src/main/java/eu/faircode/email/Core.java @@ -1100,7 +1100,7 @@ class Core { throw new MessageRemovedException(); MessageHelper helper = new MessageHelper((MimeMessage) imessage); - MessageHelper.MessageParts parts = helper.getMessageParts(); + MessageHelper.MessageParts parts = helper.getMessageParts(context); String body = parts.getHtml(context); Helper.writeText(message.getFile(context), body); db.message().setMessageContent(message.id, @@ -1132,7 +1132,7 @@ class Core { // Get message parts MessageHelper helper = new MessageHelper((MimeMessage) imessage); - MessageHelper.MessageParts parts = helper.getMessageParts(); + MessageHelper.MessageParts parts = helper.getMessageParts(context); // Download attachment parts.downloadAttachment(context, attachment); @@ -1467,7 +1467,7 @@ class Core { Log.i(folder.name + " POP sync=" + msgid); String authentication = helper.getAuthentication(); - MessageHelper.MessageParts parts = helper.getMessageParts(); + MessageHelper.MessageParts parts = helper.getMessageParts(context); EntityMessage message = new EntityMessage(); message.account = folder.account; @@ -1980,49 +1980,6 @@ class Core { long uid = ifolder.getUID(imessage); - try { - return _synchronizeMessage(context, account, folder, uid, istore, imessage, browsed, download, rules, state); - } catch (MessagingException ex) { - // https://javaee.github.io/javamail/FAQ#imapserverbug - if (MessageHelper.retryRaw(ex)) - try { - Log.w(folder.name + " " + ex.getMessage()); - - Log.i(folder.name + " fetching raw message uid=" + uid); - File file = File.createTempFile("serverbug." + folder.id, "." + uid, context.getCacheDir()); - try (OutputStream os = new BufferedOutputStream(new FileOutputStream(file))) { - imessage.writeTo(os); - } - - Properties props = MessageHelper.getSessionProperties(); - Session isession = Session.getInstance(props, null); - - Log.i(folder.name + " decoding again uid=" + uid); - try (InputStream is = new BufferedInputStream(new FileInputStream(file))) { - imessage = new MimeMessageEx(isession, is, imessage); - } - - file.delete(); - - Log.i(folder.name + " synchronizing again uid=" + uid); - return _synchronizeMessage(context, account, folder, uid, istore, imessage, browsed, download, rules, state); - } catch (MessagingException ex1) { - if (MessageHelper.retryRaw(ex1)) - Log.e(ex1); - throw ex1; - } - - throw ex; - } - } - - private static EntityMessage _synchronizeMessage( - Context context, - EntityAccount account, EntityFolder folder, long uid, - IMAPStore istore, MimeMessage imessage, - boolean browsed, boolean download, - List rules, State state) throws MessagingException, IOException { - if (imessage.isExpunged()) { Log.i(folder.name + " expunged uid=" + uid); throw new MessageRemovedException("Expunged"); @@ -2086,7 +2043,7 @@ class Core { if (message == null) { String authentication = helper.getAuthentication(); - MessageHelper.MessageParts parts = helper.getMessageParts(); + MessageHelper.MessageParts parts = helper.getMessageParts(context); message = new EntityMessage(); message.account = folder.account; @@ -2553,7 +2510,7 @@ class Core { //ifolder.fetch(new Message[]{imessage}, fp); MessageHelper helper = new MessageHelper(imessage); - MessageHelper.MessageParts parts = helper.getMessageParts(); + MessageHelper.MessageParts parts = helper.getMessageParts(context); if (!message.content) { if (state.getNetworkState().isUnmetered() || diff --git a/app/src/main/java/eu/faircode/email/FragmentMessages.java b/app/src/main/java/eu/faircode/email/FragmentMessages.java index 2b426ad68d..c43eaad16a 100644 --- a/app/src/main/java/eu/faircode/email/FragmentMessages.java +++ b/app/src/main/java/eu/faircode/email/FragmentMessages.java @@ -4206,7 +4206,7 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences. try (InputStream fis = new FileInputStream(plain)) { MimeMessage imessage = new MimeMessage(isession, fis); MessageHelper helper = new MessageHelper(imessage); - parts = helper.getMessageParts(); + parts = helper.getMessageParts(context); } try { diff --git a/app/src/main/java/eu/faircode/email/MessageHelper.java b/app/src/main/java/eu/faircode/email/MessageHelper.java index 6790bceb30..d9eb7f7c24 100644 --- a/app/src/main/java/eu/faircode/email/MessageHelper.java +++ b/app/src/main/java/eu/faircode/email/MessageHelper.java @@ -29,8 +29,11 @@ import com.sun.mail.util.MessageRemovedIOException; import org.jsoup.nodes.Document; +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; import java.io.BufferedReader; import java.io.File; +import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FileReader; import java.io.IOException; @@ -1231,9 +1234,34 @@ public class MessageHelper { EntityAttachment attachment; } - MessageParts getMessageParts() throws IOException, MessagingException { + MessageParts getMessageParts(Context context) throws IOException, MessagingException { MessageParts parts = new MessageParts(); + try { + imessage.getContentType(); + } catch (MessagingException ex) { + // https://javaee.github.io/javamail/FAQ#imapserverbug + if ("Failed to load IMAP envelope".equals(ex.getMessage()) || + "Unable to load BODYSTRUCTURE".equals(ex.getMessage())) { + Log.w("Fetching raw message"); + File file = File.createTempFile("serverbug", null, context.getCacheDir()); + try (OutputStream os = new BufferedOutputStream(new FileOutputStream(file))) { + imessage.writeTo(os); + } + + Properties props = MessageHelper.getSessionProperties(); + Session isession = Session.getInstance(props, null); + + Log.w("Decoding raw message"); + try (InputStream is = new BufferedInputStream(new FileInputStream(file))) { + imessage = new MimeMessageEx(isession, is, imessage); + } + + file.delete(); + } else + throw ex; + } + try { if (imessage.isMimeType("multipart/signed")) { Multipart multipart = (Multipart) imessage.getContent(); @@ -1392,18 +1420,11 @@ public class MessageHelper { } catch (FolderClosedException ex) { throw ex; } catch (MessagingException ex) { - if (retryRaw(ex)) - throw ex; Log.w(ex); parts.warnings.add(Helper.formatThrowable(ex, false)); } } - static boolean retryRaw(MessagingException ex) { - return ("Failed to load IMAP envelope".equals(ex.getMessage()) || - "Unable to load BODYSTRUCTURE".equals(ex.getMessage())); - } - static String sanitizeKeyword(String keyword) { // https://tools.ietf.org/html/rfc3501 StringBuilder sb = new StringBuilder(); diff --git a/app/src/main/java/eu/faircode/email/ServiceSend.java b/app/src/main/java/eu/faircode/email/ServiceSend.java index fff03e78e1..9a23f06476 100644 --- a/app/src/main/java/eu/faircode/email/ServiceSend.java +++ b/app/src/main/java/eu/faircode/email/ServiceSend.java @@ -413,7 +413,7 @@ public class ServiceSend extends ServiceBase { if (sid != null) { MessageHelper helper = new MessageHelper(imessage); - MessageHelper.MessageParts parts = helper.getMessageParts(); + MessageHelper.MessageParts parts = helper.getMessageParts(this); String body = parts.getHtml(this); Helper.writeText(EntityMessage.getFile(this, sid), body); db.message().setMessageContent(message.id,