Connection: add 'update' event for unsolicited, untagged FETCH responses

fork
mscdex 11 years ago
parent f59e1239b1
commit f942ede18a

@ -325,6 +325,8 @@ Connection Events
* **deleted**(< _integer_ >seqno) - Emitted when a message is deleted from another IMAP connection's session. `seqno` is the sequence number (instead of the unique UID) of the message that was deleted. If you are caching sequence numbers, all sequence numbers higher than this value **MUST** be decremented by 1 in order to stay synchronized with the server and to keep correct continuity. * **deleted**(< _integer_ >seqno) - Emitted when a message is deleted from another IMAP connection's session. `seqno` is the sequence number (instead of the unique UID) of the message that was deleted. If you are caching sequence numbers, all sequence numbers higher than this value **MUST** be decremented by 1 in order to stay synchronized with the server and to keep correct continuity.
* **update**(< _integer_ >seqno, < _object_ >info) - Emitted when message metadata (e.g. flags) changes externally.
* **error**(< _Error_ >err) - Emitted when an error occurs. The 'source' property will be set to indicate where the error originated from. * **error**(< _Error_ >err) - Emitted when an error occurs. The 'source' property will be set to indicate where the error originated from.
* **close**(< _boolean_ >hadError) - Emitted when the connection has completely closed. * **close**(< _boolean_ >hadError) - Emitted when the connection has completely closed.

@ -1073,73 +1073,80 @@ Connection.prototype._resUntagged = function(info) {
box.uidvalidity = attrs.uidvalidity; box.uidvalidity = attrs.uidvalidity;
} }
this._curReq.cbargs.push(box); this._curReq.cbargs.push(box);
} else if (type === 'fetch') { } else if (type === 'fetch') {
var msg = this._curReq.fetchCache[info.num], if (/^(?:UID )?FETCH/.test(this._curReq.fullcmd)) {
keys = Object.keys(info.text), // FETCH response sent as result of FETCH request
keyslen = keys.length, var msg = this._curReq.fetchCache[info.num],
toget, msgEmitter, j; keys = Object.keys(info.text),
keyslen = keys.length,
toget, msgEmitter, j;
if (msg === undefined) {
// simple case -- no bodies were streamed
toget = this._curReq.fetching.slice(0);
if (toget.length === 0)
return;
msgEmitter = new EventEmitter();
attrs = {};
this._curReq.bodyEmitter.emit('message', msgEmitter, info.num);
} else {
toget = msg.toget;
msgEmitter = msg.msgEmitter;
attrs = msg.attrs;
}
if (msg === undefined) { i = toget.length;
// simple case -- no bodies were streamed if (i === 0) {
toget = this._curReq.fetching.slice(0); if (msg && !msg.ended) {
if (toget.length === 0) msg.ended = true;
process.nextTick(function() {
msgEmitter.emit('end');
});
}
return; return;
msgEmitter = new EventEmitter();
attrs = {};
this._curReq.bodyEmitter.emit('message', msgEmitter, info.num);
} else {
toget = msg.toget;
msgEmitter = msg.msgEmitter;
attrs = msg.attrs;
}
i = toget.length;
if (i === 0) {
if (msg && !msg.ended) {
msg.ended = true;
process.nextTick(function() {
msgEmitter.emit('end');
});
} }
return;
}
if (keyslen > 0) { if (keyslen > 0) {
while (--i >= 0) { while (--i >= 0) {
j = keyslen; j = keyslen;
while (--j >= 0) { while (--j >= 0) {
if (keys[j].toUpperCase() === toget[i]) { if (keys[j].toUpperCase() === toget[i]) {
if (!RE_BODYPART.test(toget[i])) { if (!RE_BODYPART.test(toget[i])) {
if (toget[i] === 'X-GM-LABELS') { if (toget[i] === 'X-GM-LABELS') {
var labels = info.text[keys[j]]; var labels = info.text[keys[j]];
for (var k = 0, lenk = labels.length; k < lenk; ++k) for (var k = 0, lenk = labels.length; k < lenk; ++k)
labels[k] = (''+labels[k]).replace(RE_ESCAPE, '\\'); labels[k] = (''+labels[k]).replace(RE_ESCAPE, '\\');
}
attrs[FETCH_ATTR_MAP[toget[i]]] = info.text[keys[j]];
} }
attrs[FETCH_ATTR_MAP[toget[i]]] = info.text[keys[j]]; toget.splice(i, 1);
break;
} }
toget.splice(i, 1);
break;
} }
} }
} }
}
if (toget.length === 0) { if (toget.length === 0) {
if (msg) if (msg)
msg.ended = true; msg.ended = true;
process.nextTick(function() { process.nextTick(function() {
msgEmitter.emit('attributes', attrs); msgEmitter.emit('attributes', attrs);
msgEmitter.emit('end'); msgEmitter.emit('end');
}); });
} else if (msg === undefined) { } else if (msg === undefined) {
this._curReq.fetchCache[info.num] = { this._curReq.fetchCache[info.num] = {
msgEmitter: msgEmitter, msgEmitter: msgEmitter,
toget: toget, toget: toget,
attrs: attrs, attrs: attrs,
ended: false ended: false
}; };
}
} else {
// FETCH response sent as result of STORE request or sent unilaterally,
// treat them as the same for now for simplicity
this.emit('update', info.num, info.text);
} }
} }
}; };

Loading…
Cancel
Save