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.
fork
Andreas Fuchs 12 years ago
parent 867d6dfc4a
commit 7749d75207

@ -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 ';

Loading…
Cancel
Save