Misc minor changes + be less strict on non-selectable mailboxes

Closes #58
fork
Brian White 12 years ago
parent af0c191ec1
commit 7efda6cb9e

@ -85,31 +85,7 @@ util.inherits(ImapConnection, EventEmitter);
exports.ImapConnection = ImapConnection;
ImapConnection.prototype.connect = function(loginCb) {
var self = this,
fnInit = function() {
// First get pre-auth capabilities, including server-supported auth
// mechanisms
self._send('CAPABILITY', function() {
// Next, attempt to login
self._login(function(err, reentry) {
if (err) {
loginCb(err);
return;
}
// Next, get the list of available namespaces if supported (RFC2342)
if (!reentry && self._supports('NAMESPACE')) {
var fnMe = arguments.callee;
// Re-enter this function after we've obtained the available
// namespaces
self._send('NAMESPACE', function(e) { fnMe.call(this, e, true); });
return;
}
// Lastly, get the top-level mailbox hierarchy delimiter used by the
// server
self._send('LIST "" ""', loginCb);
});
});
};
var self = this;
this._reset();
@ -154,7 +130,28 @@ ImapConnection.prototype.connect = function(loginCb) {
self.emit('close', had_error);
});
this._state.conn.on('ready', fnInit);
this._state.conn.on('ready', function() {
// First get pre-auth capabilities, including server-supported auth
// mechanisms
self._send('CAPABILITY', function() {
// Next, attempt to login
var checkedNS = false;
self._login(function redo(err) {
if (err)
return loginCb(err);
// Next, get the list of available namespaces if supported (RFC2342)
if (!checkedNS && self._supports('NAMESPACE')) {
// Re-enter this function after we've obtained the available
// namespaces
checkedNS = true;
return self._send('NAMESPACE', redo);
}
// Lastly, get the top-level mailbox hierarchy delimiter used by the
// server
self._send('LIST "" ""', loginCb);
});
});
});
this._state.conn.cleartext.on('data', function(data) {
if (data.length === 0) return;
@ -268,12 +265,11 @@ ImapConnection.prototype.connect = function(loginCb) {
});
}
}
self._state.conn.cleartext.emit('data', data.slice(idxCRLF + 2));
return;
return self._state.conn.cleartext.emit('data', data.slice(idxCRLF + 2));
}
if (data.length === 0)
return;
if (data.length === 0) return;
var endsInCRLF = (data[data.length-2] === 13 && data[data.length-1] === 10);
data = utils.bufferSplit(data, CRLF);
@ -286,12 +282,12 @@ ImapConnection.prototype.connect = function(loginCb) {
b = new Buffer(needsCRLF ? line.length + 2 : line.length);
line.copy(b, 0, 0);
if (needsCRLF) {
b[b.length-2] = 13;
b[b.length-1] = 10;
b[b.length - 2] = 13;
b[b.length - 1] = 10;
}
self._state.conn.cleartext.emit('data', b);
});
})(data[i], i === len-1);
})(data[i], i === len - 1);
}
}
@ -303,17 +299,14 @@ ImapConnection.prototype.connect = function(loginCb) {
self._state.status = STATES.AUTH;
if (self._state.numCapRecvs === 0)
self._state.numCapRecvs = 1;
} else if (data[1] === 'NO' || data[1] === 'BAD' || data[1] === 'BYE') {
self._state.conn.end();
return;
}
} else if (data[1] === 'NO' || data[1] === 'BAD' || data[1] === 'BYE')
return self._state.conn.end();
if (!self._state.isReady) {
self._state.isReady = true;
self._state.conn.emit('ready');
}
// Restrict the type of server responses when unauthenticated
if (data[1] !== 'CAPABILITY' && data[1] !== 'ALERT')
return;
if (data[1] !== 'CAPABILITY' && data[1] !== 'ALERT') return;
}
switch (data[1]) {
case 'CAPABILITY':
@ -326,8 +319,9 @@ ImapConnection.prototype.connect = function(loginCb) {
break;
case 'FLAGS':
if (self._state.status === STATES.BOXSELECTING) {
self._state.box._flags = data[2].substr(1, data[2].length-2)
.split(' ').map(function(flag) {
self._state.box._flags = data[2].substr(1, data[2].length - 2)
.split(' ')
.map(function(flag) {
return flag.substr(1);
});
}
@ -371,10 +365,11 @@ ImapConnection.prototype.connect = function(loginCb) {
case 'LIST':
case 'XLIST':
var result;
if (self.delim === null
&& (result = /^\(\\No[sS]elect\) (.+?) .*$/.exec(data[2])))
if (self.delim === null &&
(result = /^\(\\No[sS]elect(?:[^)]*)\) (.+?) .*$/.exec(data[2])))
self.delim = (result[1] === 'NIL'
? false : result[1].substring(1, result[1].length-1));
? false
: result[1].substring(1, result[1].length - 1));
else if (self.delim !== null) {
if (self._state.requests[0].args.length === 0)
self._state.requests[0].args.push({});
@ -384,12 +379,14 @@ ImapConnection.prototype.connect = function(loginCb) {
return attrib.substr(1).toUpperCase();
}),
delim: (result[2] === 'NIL'
? false : result[2].substring(1, result[2].length-1)),
? false
: result[2].substring(1, result[2].length-1)),
children: null,
parent: null
},
name = result[3],
curChildren = self._state.requests[0].args[0];
if (name[0] === '"' && name[name.length-1] === '"')
name = name.substring(1, name.length - 1);
@ -727,7 +724,8 @@ ImapConnection.prototype._fetch = function(which, uids, options) {
headers: true,
body: false
}
}, toFetch, useParser = false, bodyRange = '', self = this;
}, toFetch, bodyRange, extensions, useParser, self = this;
if (typeof options !== 'object')
options = {};
utils.extend(true, opts, options);
@ -775,26 +773,38 @@ ImapConnection.prototype._fetch = function(which, uids, options) {
useParser = true;
}
var extensions = '';
// always fetch GMail-specific bits of information when on GMail
if (this._supports('X-GM-EXT-1'))
extensions = 'X-GM-THRID X-GM-MSGID X-GM-LABELS ';
this._send(which + 'FETCH ' + uids.join(',') + ' (' + extensions
+ 'UID FLAGS INTERNALDATE'
+ (opts.request.struct ? ' BODYSTRUCTURE' : '')
+ (typeof toFetch === 'string' ? ' BODY'
+ (!opts.markSeen ? '.PEEK' : '')
+ '[' + toFetch + ']' + bodyRange : '') + ')', function(e) {
var fetcher = self._state.requests[0]._fetcher;
if (e && fetcher)
fetcher.emit('error', e);
else if (e && !fetcher)
self.emit('error', e);
else if (fetcher)
fetcher.emit('end');
}
);
var cmd = which;
cmd += 'FETCH ';
cmd += uids.join(',');
cmd += ' (';
if (extensions)
cmd += extensions;
cmd += 'UID FLAGS INTERNALDATE';
if (toFetch !== undefined) {
cmd += ' BODY';
if (!opts.markSeen)
cmd += '.PEEK';
cmd += '[';
cmd += toFetch;
cmd += ']';
if (bodyRange)
cmd += bodyRange;
}
cmd += ')';
this._send(cmd, function(e) {
var fetcher = self._state.requests[0]._fetcher;
if (e && fetcher)
fetcher.emit('error', e);
else if (e && !fetcher)
self.emit('error', e);
else if (fetcher)
fetcher.emit('end');
});
var imapFetcher = new ImapFetch(),
req = this._state.requests[this._state.requests.length - 1];
req._fetcher = imapFetcher;

Loading…
Cancel
Save