From 7f4c56903cf030199c60455bb7895a66c6887243 Mon Sep 17 00:00:00 2001 From: mguessan Date: Sun, 15 Sep 2013 17:43:46 +0000 Subject: [PATCH] IMAP: fix 538, send capabilities untagged response to avoid timeout on large message APPEND git-svn-id: http://svn.code.sf.net/p/davmail/code/trunk@2178 3d1905a2-6b24-0410-a738-b14d5a86fcbd --- .../davmail/exchange/MessageCreateThread.java | 80 +++++++++++++++++++ src/java/davmail/imap/ImapConnection.java | 7 +- 2 files changed, 82 insertions(+), 5 deletions(-) create mode 100644 src/java/davmail/exchange/MessageCreateThread.java diff --git a/src/java/davmail/exchange/MessageCreateThread.java b/src/java/davmail/exchange/MessageCreateThread.java new file mode 100644 index 00000000..a6a2c46d --- /dev/null +++ b/src/java/davmail/exchange/MessageCreateThread.java @@ -0,0 +1,80 @@ +package davmail.exchange; + +import davmail.Settings; +import org.apache.log4j.Logger; + +import javax.mail.internet.MimeMessage; +import java.io.IOException; +import java.io.OutputStream; +import java.net.SocketException; +import java.util.HashMap; + +/** + * Create message in a separate thread. + */ +public class MessageCreateThread extends Thread { + private static final Logger LOGGER = Logger.getLogger(MessageCreateThread.class); + + boolean isComplete = false; + ExchangeSession session; + String folderPath; + String messageName; + HashMap properties; + MimeMessage mimeMessage; + IOException exception; + + MessageCreateThread(String threadName, ExchangeSession session, String folderPath, String messageName, HashMap properties, MimeMessage mimeMessage) { + super(threadName + "-MessageCreate"); + setDaemon(true); + this.session = session; + this.folderPath = folderPath; + this.messageName = messageName; + this.properties = properties; + this.mimeMessage = mimeMessage; + } + + public void run() { + try { + session.createMessage(folderPath, messageName, properties, mimeMessage); + } catch (IOException e) { + exception = e; + } finally { + isComplete = true; + } + } + + /** + * Create message in a separate thread. + * + * @param folder current folder + * @param outputStream client connection + * @throws InterruptedException on error + * @throws IOException on error + */ + public static void createMessage(ExchangeSession session, String folderPath, String messageName, HashMap properties, MimeMessage mimeMessage, OutputStream outputStream, String capabilities) throws InterruptedException, IOException { + MessageCreateThread messageCreateThread = new MessageCreateThread(currentThread().getName(), session, folderPath, messageName, properties, mimeMessage); + messageCreateThread.start(); + while (!messageCreateThread.isComplete) { + messageCreateThread.join(20000); + if (!messageCreateThread.isComplete) { + if (Settings.getBooleanProperty("davmail.enableKeepAlive", false)) { + LOGGER.debug("Still loading message, send capabilities untagged response to avoid timeout"); + try { + LOGGER.debug("* "+capabilities); + outputStream.write(("* "+capabilities).getBytes()); + outputStream.write((char) 13); + outputStream.write((char) 10); + outputStream.flush(); + } catch (SocketException e) { + messageCreateThread.interrupt(); + throw e; + } + } + } + } + if (messageCreateThread.exception != null) { + throw messageCreateThread.exception; + } + + } +} diff --git a/src/java/davmail/imap/ImapConnection.java b/src/java/davmail/imap/ImapConnection.java index 96b0d911..83d5a446 100644 --- a/src/java/davmail/imap/ImapConnection.java +++ b/src/java/davmail/imap/ImapConnection.java @@ -28,10 +28,7 @@ import davmail.exception.DavMailException; import davmail.exception.HttpForbiddenException; import davmail.exception.HttpNotFoundException; import davmail.exception.InsufficientStorageException; -import davmail.exchange.ExchangeSession; -import davmail.exchange.ExchangeSessionFactory; -import davmail.exchange.FolderLoadThread; -import davmail.exchange.MessageLoadThread; +import davmail.exchange.*; import davmail.ui.tray.DavGatewayTray; import davmail.util.IOUtil; import davmail.util.StringUtil; @@ -517,7 +514,7 @@ public class ImapConnection extends AbstractConnection { String messageName = UUID.randomUUID().toString() + ".EML"; try { - session.createMessage(folderName, messageName, properties, mimeMessage); + MessageCreateThread.createMessage(session, folderName, messageName, properties, mimeMessage, os, capabilities); sendClient(commandId + " OK APPEND completed"); } catch (InsufficientStorageException e) { sendClient(commandId + " NO " + e.getMessage());