/// <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; }
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); } }
/// <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); }
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); }
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(); } }
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); } }
/// <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; }
/// <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; }