This project is read-only.

ImapX freezes after idling for a while

Topics: Help requests, Issues
Jan 5, 2015 at 2:53 PM
At first: youre doing a great job with ImapX!!

But I've got a little problem using the idle-function:

I wrote this code to shut down everything (UserIdle is a bool I set true when calling the StartIdle-function)
                if (UserClient.IsConnected)
                {
                    if (UserClient.IsAuthenticated)
                    {
                        if (UserIdle)
                        {
                            UserClient.Folders.Inbox.StopIdling();
                        }
                        UserClient.Logout();
                    }
                    UserClient.Disconnect();
                }
This works fine when I stop idling after a short time. But after a 'long' time (>2min) it freezes without any exception.

Here is an extrat from the debug-file when it works fine:
* OK [CLOSED] Previous mailbox closed.
* FLAGS (\Answered \Flagged \Deleted \Seen \Draft $Forwarded)
* OK [PERMANENTFLAGS (\Answered \Flagged \Deleted \Seen \Draft $Forwarded \*)] Flags permitted.
* 228 EXISTS
* 0 RECENT
* OK [UIDVALIDITY 1387877077] UIDs valid
* OK [UIDNEXT 953] Predicted next UID
* OK [HIGHESTMODSEQ 3120] Highest
IMAPX13 OK [READ-WRITE] Select completed (0.000 secs).
IMAPX14 IDLE

 idling
DONE

MAPX14 OK Idle completed.
IMAPX16 LOGOUT

* BYE Logging out
IMAPX16 OK Logout completed.
And when it freezes:
* OK [CLOSED] Previous mailbox closed.
* FLAGS (\Answered \Flagged \Deleted \Seen \Draft $Forwarded)
* OK [PERMANENTFLAGS (\Answered \Flagged \Deleted \Seen \Draft $Forwarded \*)] Flags permitted.
* 228 EXISTS
* 0 RECENT
* OK [UIDVALIDITY 1387877077] UIDs valid
* OK [UIDNEXT 953] Predicted next UID
* OK [HIGHESTMODSEQ 3120] Highest
IMAPX13 OK [READ-WRITE] Select completed (0.000 secs).
IMAPX14 IDLE

 idling
 OK Still here
IMAPX15 LOGOUT

* OK Still here
* OK Still here
IMAPX14 BAD Expected DONE.
Sorry if I did something really dumb ^^

thanks in advance
emuuu
Feb 17, 2015 at 4:38 PM
Edited Feb 17, 2015 at 4:40 PM
Hi,
this seems to be a problem, when the server sends "OK still here" during idling.

ImapX "thinks" that Idling has stopped, if the server sends somethink with "OK" during idling.

You can change the source code in ImapBase.cs in the WaitForIdleServerEvents() function as follows:

from:
if (tmp.ToUpper().Contains("OK"))
{
    _idleState = IdleState.Off;
    // unblock the processing thread, it will end itself because _idleState is Off
    _idleEventsResetEvent.Set();
    return;
}
to:
if (tmp.ToUpper().Contains("OK IDLE COMPLETED"))
{
    _idleState = IdleState.Off;
    // unblock the processing thread, it will end itself because _idleState is Off
    _idleEventsResetEvent.Set();
    return;
}
Hope this helps,
Michael
Coordinator
Feb 20, 2015 at 6:20 PM
Hi Michael,

thank you! I included your fix in the latest source code.

Greets,

Pavel
Mar 3, 2015 at 9:19 AM
Hi Pavel,
i've also implemented STARTTLS negotiation. I can post the code snipped for your review, if you are interested.

Greets,
Michael
Mar 3, 2015 at 1:34 PM
Just a warning here, but you can't rely on using tmp.ToUpper().Contains("OK IDLE COMPLETED") to work. The problem is that everything after the "OK" is server-dependent.

Here's what Section 7.1.1 of rfc3501 has to say:
7.1.1.  OK Response

   Contents:   OPTIONAL response code
               human-readable text

      The OK response indicates an information message from the server.
      When tagged, it indicates successful completion of the associated
      command.  The human-readable text MAY be presented to the user as
      an information message.  The untagged form indicates an
      information-only message; the nature of the information MAY be
      indicated by a response code.
And this is the formal grammar:
resp-cond-state = ("OK" / "NO" / "BAD") SP resp-text
                    ; Status condition
resp-text       = ["[" resp-text-code "]" SP] text
This means that the "IDLE COMPLETED" part of the string you are matching against is the text component of the response, which is meant as "human readable text".

The proper way to solve this is to not match against the OK until a DONE command has been sent.

Hope that helps.