Example #1
0
  boolean idle(final ImapRequest req, final boolean begin) throws IOException {
    if (begin == ImapHandler.IDLE_STOP) {
      // check state -- don't want to send DONE if we're somehow not in IDLE
      ImapHandler handler = mHandler;
      if (handler == null) throw new IOException("proxy connection already closed");
      Thread idle = mIdleThread;
      if (idle == null)
        throw new IOException("bad proxy state: no IDLE thread active when attempting DONE");
      // send the DONE, which elicits the tagged response that causes the IDLE thread (below) to
      // exit
      writeRequest(req.toByteArray());
      // make sure that the idle thread actually exits; otherwise we're in a bad place and we must
      // kill the whole session
      mIdleThread = null;
      try {
        idle.join(5 * Constants.MILLIS_PER_SECOND);
      } catch (InterruptedException ie) {
      }
      if (idle.isAlive()) handler.dropConnection(false);
    } else {
      final ImapHandler handler = mHandler;
      final ImapConnection conn = mConnection;
      if (conn == null) throw new IOException("proxy connection already closed");

      ImapConfig config = conn.getImapConfig();
      final int oldTimeout =
          config != null ? config.getReadTimeout() : LC.javamail_imap_timeout.intValue();
      // necessary because of subsequent race condition with req.cleanup()
      final byte[] payload = req.toByteArray();

      mIdleThread =
          new Thread() {
            @Override
            public void run() {
              boolean success = false;
              try {
                // the standard aggressive read timeout is inappropriate for IDLE
                conn.setReadTimeout(mHandler.getConfig().getAuthenticatedMaxIdleSeconds());
                // send the IDLE command; this call waits until the subsequent DONE is acknowledged
                boolean ok = proxyCommand(req.getTag(), payload, true, true);
                // restore the old read timeout
                conn.setReadTimeout(oldTimeout);
                // don't set <code>success</code> until we're past things that can throw
                // IOExceptions
                success = ok;
              } catch (IOException e) {
                ZimbraLog.imap.warn("error encountered during IDLE; dropping connection", e);
              }
              if (!success) handler.dropConnection();
            }
          };
      mIdleThread.setName("Imap-Idle-Proxy-" + Thread.currentThread().getName());
      mIdleThread.start();
    }
    return true;
  }
Example #2
0
 /**
  * Proxies the request to the remote server and writes all tagged and untagged responses back to
  * the handler's output stream.
  *
  * @return <tt>true</tt> in all cases.
  */
 boolean proxy(final ImapRequest req) throws IOException {
   proxyCommand(req.getTag(), req.toByteArray(), true, false);
   return true;
 }