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.
* **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.
* **close**(< _boolean_ >hadError) - Emitted when the connection has completely closed.

@ -1073,73 +1073,80 @@ Connection.prototype._resUntagged = function(info) {
box.uidvalidity = attrs.uidvalidity;
}
this._curReq.cbargs.push(box);
} else if (type === 'fetch') {
var msg = this._curReq.fetchCache[info.num],
keys = Object.keys(info.text),
keyslen = keys.length,
toget, msgEmitter, j;
} else if (type === 'fetch') {
if (/^(?:UID )?FETCH/.test(this._curReq.fullcmd)) {
// FETCH response sent as result of FETCH request
var msg = this._curReq.fetchCache[info.num],
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) {
// simple case -- no bodies were streamed
toget = this._curReq.fetching.slice(0);
if (toget.length === 0)
i = toget.length;
if (i === 0) {
if (msg && !msg.ended) {
msg.ended = true;
process.nextTick(function() {
msgEmitter.emit('end');
});
}
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) {
while (--i >= 0) {
j = keyslen;
while (--j >= 0) {
if (keys[j].toUpperCase() === toget[i]) {
if (!RE_BODYPART.test(toget[i])) {
if (toget[i] === 'X-GM-LABELS') {
var labels = info.text[keys[j]];
for (var k = 0, lenk = labels.length; k < lenk; ++k)
labels[k] = (''+labels[k]).replace(RE_ESCAPE, '\\');
if (keyslen > 0) {
while (--i >= 0) {
j = keyslen;
while (--j >= 0) {
if (keys[j].toUpperCase() === toget[i]) {
if (!RE_BODYPART.test(toget[i])) {
if (toget[i] === 'X-GM-LABELS') {
var labels = info.text[keys[j]];
for (var k = 0, lenk = labels.length; k < lenk; ++k)
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 (msg)
msg.ended = true;
process.nextTick(function() {
msgEmitter.emit('attributes', attrs);
msgEmitter.emit('end');
});
} else if (msg === undefined) {
this._curReq.fetchCache[info.num] = {
msgEmitter: msgEmitter,
toget: toget,
attrs: attrs,
ended: false
};
if (toget.length === 0) {
if (msg)
msg.ended = true;
process.nextTick(function() {
msgEmitter.emit('attributes', attrs);
msgEmitter.emit('end');
});
} else if (msg === undefined) {
this._curReq.fetchCache[info.num] = {
msgEmitter: msgEmitter,
toget: toget,
attrs: attrs,
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