View Javadoc
1   package davmail.exchange;
2   
3   import davmail.Settings;
4   import org.apache.log4j.Logger;
5   
6   import javax.mail.MessagingException;
7   import java.io.IOException;
8   import java.io.OutputStream;
9   import java.net.SocketException;
10  
11  /**
12   * Message load thread.
13   * Used to avoid timeouts over POP and IMAP
14   */
15  public class MessageLoadThread extends Thread {
16      private static final Logger LOGGER = Logger.getLogger(MessageLoadThread.class);
17  
18      protected boolean isComplete = false;
19      protected ExchangeSession.Message message;
20      protected IOException ioException;
21      protected MessagingException messagingException;
22  
23      protected MessageLoadThread(String threadName, ExchangeSession.Message message) {
24          super(threadName + "-LoadMessage");
25          setDaemon(true);
26          this.message = message;
27      }
28  
29      public void run() {
30          try {
31              message.loadMimeMessage();
32          } catch (IOException e) {
33              ioException = e;
34          } catch (MessagingException e) {
35              messagingException = e;
36          } finally {
37              isComplete = true;
38          }
39      }
40  
41      /**
42       * Load mime message in a separate thread if over 1MB.
43       * Send a space character every ten seconds to avoid client timeouts
44       *
45       * @param message      message
46       * @param outputStream output stream
47       * @throws IOException        on error
48       * @throws MessagingException on error
49       */
50      public static void loadMimeMessage(ExchangeSession.Message message, OutputStream outputStream) throws IOException, MessagingException {
51          if (message.size < 1024 * 1024) {
52              message.loadMimeMessage();
53          } else {
54              LOGGER.debug("Load large message " + (message.size / 1024) + "KB uid " + message.getUid() + " imapUid " + message.getImapUid() + " in a separate thread");
55                  MessageLoadThread messageLoadThread = new MessageLoadThread(currentThread().getName(), message);
56                  messageLoadThread.start();
57                  while (!messageLoadThread.isComplete) {
58                      try {
59                          messageLoadThread.join(10000);
60                      } catch (InterruptedException e) {
61                          LOGGER.warn("Thread interrupted", e);
62                          Thread.currentThread().interrupt();
63                      }
64                      LOGGER.debug("Still loading uid " + message.getUid() + " imapUid " + message.getImapUid());
65                      if (Settings.getBooleanProperty("davmail.enableKeepAlive", false)) {
66                          try {
67                              outputStream.write(' ');
68                              outputStream.flush();
69                          } catch (SocketException e) {
70                              // client closed connection, stop thread
71                              message.dropMimeMessage();
72                              messageLoadThread.interrupt();
73                              throw e;
74                          }
75                      }
76                  }
77                  if (messageLoadThread.ioException != null) {
78                      throw messageLoadThread.ioException;
79                  }
80                  if (messageLoadThread.messagingException != null) {
81                      throw messageLoadThread.messagingException;
82                  }
83          }
84      }
85  }