From 7749d7520791cc1a4b48b86731924a55c3e7e5ae Mon Sep 17 00:00:00 2001 From: Andreas Fuchs Date: Fri, 21 Sep 2012 22:09:01 -0700 Subject: [PATCH] Fix IDLE for very fast connections When issuing commands in rapid succession, it was possible for node-imap to send multiple "DONE" commands. This resulted in wedged state when the server dropped out of IDLE and then didn't know what to do with the second DONE command. This change adds a safeguard that ensures _send never sends more than one DONE, and queues (non-DONE/IDLE) commands up for when the server was able to acknowledge. --- lib/imap.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/lib/imap.js b/lib/imap.js index 4bf4928..a41acca 100644 --- a/lib/imap.js +++ b/lib/imap.js @@ -27,7 +27,8 @@ var CRLF = '\r\n', // extension constants var IDLE_NONE = 1, IDLE_WAIT = 2, - IDLE_READY = 3; + IDLE_READY = 3, + IDLE_DONE = 4; function ImapConnection (options) { if (!(this instanceof ImapConnection)) @@ -1209,16 +1210,18 @@ ImapConnection.prototype._send = function(cmdstr, cb, bypass) { cbargs: [] }); } - if (this._state.ext.idle.state === IDLE_WAIT) + if (this._state.ext.idle.state === IDLE_WAIT || + (this._state.ext.idle.state == IDLE_DONE && cmdstr !== 'DONE')) return; if ((cmdstr === undefined && this._state.requests.length) || this._state.requests.length === 1 || bypass) { var prefix = '', cmd = (bypass ? cmdstr : this._state.requests[0].cmdstr); clearTimeout(this._state.tmrKeepalive); - if (this._state.ext.idle.state === IDLE_READY && cmd !== 'DONE') + if (this._state.ext.idle.state === IDLE_READY && cmd !== 'DONE') { + this._state.ext.idle.state = IDLE_DONE; return this._send('DONE', undefined, true); - else if (cmd === 'IDLE') { + } else if (cmd === 'IDLE') { // we use a different prefix to differentiate and disregard the tagged // response the server will send us when we issue DONE prefix = 'IDLE ';