Example #1
0
        /// <summary>
        ///   This method is blocking.
        ///   The IDLE command may be used with any IMAP4 server implementation
        ///   that returns "IDLE" as one of the supported capabilities to the
        ///   CAPABILITY command.  If the server does not advertise the IDLE
        ///   capability, the client MUST NOT use the IDLE command and must poll
        ///   for mailbox updates.
        ///   http://tools.ietf.org/html/rfc2177
        /// </summary>
        public void StartIdle()
        {
            if (!ServerCapability.IsIdleSupported)
            {
                const string message = "Server does not support the idle command. Please check Capability.CanIdle before calling Idle.";
                throw new InvalidOperationException(message);
            }

            var command = new ImapCommand("IDLE");

            SendAndReceive(command);
            IsIdling = true;

            while (true)
            {
                // Need to set response timeout to 29 minutes, because the server will kick us after 30  if we do not re apply for IDLE.
                ResponseTimeout = TimeSpan.FromMinutes(29);
                var reader = new ImapResponseReader(this);
                try {
                    ReceiveIdleStatusUpdates(reader);
                }
                catch (TimeoutException) {
                    StopIdleAsync();
                }

                if (reader.IsCompleted)
                {
                    break;
                }
            }

            IsIdling = false;
        }
Example #2
0
        internal void CheckForStatusUpdates(ImapResponseReader reader)
        {
            StatusUpdateReceivedEventArgs e = null;

            while (true)
            {
                if (!reader.IsStatusUpdate)
                {
                    break;
                }

                if (e == null)
                {
                    e = new StatusUpdateReceivedEventArgs(SelectedMailbox);
                }

                e.MailboxInfo.InjectLine(reader.CurrentLine);
                reader.ReadNextLine();
                continue;
            }

            if (e != null)
            {
                InvokeStatusUpdateReceived(e);
            }
        }
Example #3
0
        /// <summary>
        ///   Receives a response from the server.
        /// </summary>
        /// <returns>Returns a response reader.</returns>
        public ImapResponseReader Receive(bool processStatusUpdatesAutomatically = true)
        {
            var reader = new ImapResponseReader(this);

            reader.ReadNextLine();
            if (processStatusUpdatesAutomatically)
            {
                CheckForStatusUpdates(reader);
            }
            return(reader);
        }
Example #4
0
        internal void ReceiveIdleStatusUpdates(ImapResponseReader reader)
        {
            reader.ReadNextLine();

            if (reader.IsCompleted)
            {
                return;
            }

            StopIdleAsync();

            var e = new StatusUpdateReceivedEventArgs(SelectedMailbox)
            {
                IsIdleUpdate = true
            };

            while (true)
            {
                if (reader.IsCompleted)
                {
                    InvokeStatusUpdateReceived(e);
                    break;
                }

                if (reader.IsStatusUpdate)
                {
                    e.MailboxInfo.InjectLine(reader.CurrentLine);
                }

                // We must check seperately for FETCH updates since we cannot include them into regular status update checks.
                // If included they would be processed as a status update and not as a FETCH response, thus corrupting the stack.
                // We can only check for this kind of update inside the IDLE loop, since we know here that no previous FETCH command has been issued and
                // it is therefor safe to process a FETCH update response.
                if (reader.CurrentLine.Contains("FETCH"))
                {
                    if (e.MailboxInfo.MessageStateChanges == null)
                    {
                        e.MailboxInfo.MessageStateChanges = new List <MessageState>();
                    }
                    var state = new MessageState();
                    state.InjectLine(reader.CurrentLine);
                    ((IList <MessageState>)e.MailboxInfo.MessageStateChanges).Add(state);
                }

                reader.ReadNextLine();
            }

            if (!e.IsIdleCancelled)
            {
                StartIdle();
            }
        }
        public static ImapServerCapability ReadCapabilities(this ImapResponseReader response)
        {
            var cap = new ImapServerCapability();

            while (true)
            {
                var values = response.CurrentLine.Split(Characters.Space);
                foreach (var value in values.Where(value => value != "*" && value != CommandStrings.Capability))
                {
                    cap.Store(value);
                }
                response.ReadNextLine();

                if (response.IsCompleted)
                {
                    break;
                }
            }

            return(cap);
        }
Example #6
0
        internal void ReceiveIdleStatusUpdates(ImapResponseReader reader)
        {
            reader.ReadNextLine();

            if (reader.IsCompleted) {
                return;
            }

            StopIdleAsync();

            var e = new StatusUpdateReceivedEventArgs(SelectedMailbox) {IsIdleUpdate = true};
            while (true) {
                if (reader.IsCompleted) {
                    InvokeStatusUpdateReceived(e);
                    break;
                }

                if (reader.IsStatusUpdate) {
                    e.MailboxInfo.InjectLine(reader.CurrentLine);
                }

                // We must check seperately for FETCH updates since we cannot include them into regular status update checks.
                // If included they would be processed as a status update and not as a FETCH response, thus corrupting the stack.
                // We can only check for this kind of update inside the IDLE loop, since we know here that no previous FETCH command has been issued and
                // it is therefor safe to process a FETCH update response.
                if (reader.CurrentLine.Contains("FETCH")) {
                    if (e.MailboxInfo.MessageStateChanges == null) {
                        e.MailboxInfo.MessageStateChanges = new List<MessageState>();
                    }
                    var state = new MessageState();
                    state.InjectLine(reader.CurrentLine);
                    ((IList<MessageState>) e.MailboxInfo.MessageStateChanges).Add(state);
                }

                reader.ReadNextLine();
            }

            if (!e.IsIdleCancelled) {
                StartIdle();
            }
        }
Example #7
0
        internal void CheckForStatusUpdates(ImapResponseReader reader)
        {
            StatusUpdateReceivedEventArgs e = null;
            while (true) {
                if (!reader.IsStatusUpdate) {
                    break;
                }

                if (e == null) {
                    e = new StatusUpdateReceivedEventArgs(SelectedMailbox);
                }

                e.MailboxInfo.InjectLine(reader.CurrentLine);
                reader.ReadNextLine();
                continue;
            }

            if (e != null) {
                InvokeStatusUpdateReceived(e);
            }
        }
Example #8
0
        /// <summary>
        ///   This method is blocking.
        ///   The IDLE command may be used with any IMAP4 server implementation
        ///   that returns "IDLE" as one of the supported capabilities to the
        ///   CAPABILITY command.  If the server does not advertise the IDLE
        ///   capability, the client MUST NOT use the IDLE command and must poll
        ///   for mailbox updates.
        ///   http://tools.ietf.org/html/rfc2177
        /// </summary>
        public void StartIdle()
        {
            if (!ServerCapability.IsIdleSupported) {
                const string message = "Server does not support the idle command. Please check Capability.CanIdle before calling Idle.";
                throw new InvalidOperationException(message);
            }

            var command = new ImapCommand("IDLE");
            SendAndReceive(command);
            IsIdling = true;

            while (true) {
                // Need to set response timeout to 29 minutes, because the server will kick us after 30  if we do not re apply for IDLE.
                ResponseTimeout = TimeSpan.FromMinutes(29);
                var reader = new ImapResponseReader(this);
                try {
                    ReceiveIdleStatusUpdates(reader);
                }
                catch (TimeoutException) {
                    StopIdleAsync();
                }

                if (reader.IsCompleted) {
                    break;
                }
            }

            IsIdling = false;
        }
Example #9
0
 /// <summary>
 ///   Receives a response from the server.
 /// </summary>
 /// <returns>Returns a response reader.</returns>
 public ImapResponseReader Receive(bool processStatusUpdatesAutomatically = true)
 {
     var reader = new ImapResponseReader(this);
     reader.ReadNextLine();
     if (processStatusUpdatesAutomatically) {
         CheckForStatusUpdates(reader);
     }
     return reader;
 }