0.4.0 compatibility. 0.2.x no longer supported.

fork
Brian White 13 years ago
parent d9e705dea8
commit 5aaa70e68f

@ -10,7 +10,7 @@ If you are in need of this kind of extra functionality, check out andris9's [mim
Requirements Requirements
============ ============
* [node.js](http://nodejs.org/) -- tested with v0.2.4 * [node.js](http://nodejs.org/) -- v0.4.0 or newer
* An IMAP server -- tested with gmail * An IMAP server -- tested with gmail
@ -19,7 +19,7 @@ Example
This example fetches the 'date', 'from', 'to', 'subject' message headers and the message structure of all unread messages in the Inbox since May 20, 2010: This example fetches the 'date', 'from', 'to', 'subject' message headers and the message structure of all unread messages in the Inbox since May 20, 2010:
var ImapConnection = require('./imap').ImapConnection, sys = require('sys'), var ImapConnection = require('./imap').ImapConnection, util = require('util'),
imap = new ImapConnection({ imap = new ImapConnection({
username: 'mygmailname@gmail.com', username: 'mygmailname@gmail.com',
password: 'mygmailpassword', password: 'mygmailpassword',
@ -46,12 +46,12 @@ This example fetches the 'date', 'from', 'to', 'subject' message headers and the
function(results) { function(results) {
var fetch = imap.fetch(results, { request: { headers: ['from', 'to', 'subject', 'date'] } }); var fetch = imap.fetch(results, { request: { headers: ['from', 'to', 'subject', 'date'] } });
fetch.on('message', function(msg) { fetch.on('message', function(msg) {
console.log('Got message: ' + sys.inspect(msg, false, 5)); console.log('Got message: ' + util.inspect(msg, false, 5));
msg.on('data', function(chunk) { msg.on('data', function(chunk) {
console.log('Got message chunk of size ' + chunk.length); console.log('Got message chunk of size ' + chunk.length);
}); });
msg.on('end', function() { msg.on('end', function() {
console.log('Finished message: ' + sys.inspect(msg, false, 5)); console.log('Finished message: ' + util.inspect(msg, false, 5));
}); });
}); });
fetch.on('end', function() { fetch.on('end', function() {

@ -1,5 +1,13 @@
var sys = require('sys'), net = require('net'), EventEmitter = require('events').EventEmitter; var util = require('util'), net = require('net'),
var emptyFn = function() {}, CRLF = "\r\n", debug=emptyFn, STATES = { NOCONNECT: 0, NOAUTH: 1, AUTH: 2, BOXSELECTING: 3, BOXSELECTED: 4 }, BOX_ATTRIBS = ['NOINFERIORS', 'NOSELECT', 'MARKED', 'UNMARKED']; tls = require('tls'), EventEmitter = require('events').EventEmitter;
var emptyFn = function() {}, CRLF = "\r\n", debug=emptyFn,
STATES = {
NOCONNECT: 0,
NOAUTH: 1,
AUTH: 2,
BOXSELECTING: 3,
BOXSELECTED: 4
}, BOX_ATTRIBS = ['NOINFERIORS', 'NOSELECT', 'MARKED', 'UNMARKED'];
function ImapConnection (options) { function ImapConnection (options) {
if (!(this instanceof ImapConnection)) if (!(this instanceof ImapConnection))
@ -30,7 +38,16 @@ function ImapConnection (options) {
curExpected: 0, curExpected: 0,
curXferred: 0, curXferred: 0,
capabilities: [], capabilities: [],
box: { _uidnext: 0, _flags: [], _newKeywords: false, validity: 0, keywords: [], permFlags: [], name: null, messages: { total: 0, new: 0 }} box: {
_uidnext: 0,
_flags: [],
_newKeywords: false,
validity: 0,
keywords: [],
permFlags: [],
name: null,
messages: { total: 0, new: 0 }
}
}; };
this._options = extend(true, this._options, options); this._options = extend(true, this._options, options);
@ -39,7 +56,7 @@ function ImapConnection (options) {
this.delim = null; this.delim = null;
this.namespaces = { personal: [], other: [], shared: [] }; this.namespaces = { personal: [], other: [], shared: [] };
}; };
sys.inherits(ImapConnection, EventEmitter); util.inherits(ImapConnection, EventEmitter);
exports.ImapConnection = ImapConnection; exports.ImapConnection = ImapConnection;
ImapConnection.prototype.connect = function(loginCb) { ImapConnection.prototype.connect = function(loginCb) {
@ -70,30 +87,33 @@ ImapConnection.prototype.connect = function(loginCb) {
this._state.conn = net.createConnection(this._options.port, this._options.host); this._state.conn = net.createConnection(this._options.port, this._options.host);
this._state.tmrConn = setTimeout(this._fnTmrConn, this._options.connTimeout, loginCb);
this._state.conn.setKeepAlive(true);
if (this._options.secure) { if (this._options.secure) {
this._state.conn.setSecure(); // TODO: support STARTTLS
this._state.conn.cleartext = this._state.conn.setSecure();
this._state.conn.on('secure', function() { this._state.conn.on('secure', function() {
debug('Secure connection made.'); debug('Secure connection made.');
}); });
this._state.conn.cleartext.setEncoding('utf8');
} else {
this._state.conn.setEncoding('utf8');
this._state.conn.cleartext = this._state.conn;
} }
this._state.tmrConn = setTimeout(this._fnTmrConn, this._options.connTimeout, loginCb);
this._state.conn.setKeepAlive(true);
this._state.conn.setEncoding('utf8');
this._state.conn.on('connect', function() { this._state.conn.on('connect', function() {
clearTimeout(self._state.tmrConn); clearTimeout(self._state.tmrConn);
debug('Connected to host.'); debug('Connected to host.');
self._state.conn.write(''); self._state.conn.cleartext.write('');
self._state.status = STATES.NOAUTH; self._state.status = STATES.NOAUTH;
}); });
this._state.conn.on('ready', function() { this._state.conn.on('ready', function() {
fnInit(); fnInit();
}); });
this._state.conn.on('data', function(data) { this._state.conn.cleartext.on('data', function(data) {
var trailingCRLF = false, literalInfo, bypass = false; var trailingCRLF = false, literalInfo, bypass = false;
debug('<<RECEIVED>>: ' + sys.inspect(data)); debug('<<RECEIVED>>: ' + util.inspect(data));
if (self._state.curExpected === 0) { if (self._state.curExpected === 0) {
if (data.indexOf(CRLF) === -1) { if (data.indexOf(CRLF) === -1) {
@ -152,7 +172,7 @@ ImapConnection.prototype.connect = function(loginCb) {
if (data[0] === '*') { if (data[0] === '*') {
// found additional responses, so don't try splitting the proceeding // found additional responses, so don't try splitting the proceeding
// response(s) for better performance in case they have literals too // response(s) for better performance in case they have literals too
process.nextTick(function() { self._state.conn.emit('data', data); }); process.nextTick(function() { self._state.conn.cleartext.emit('data', data); });
return; return;
} }
} else if (self._state.curExpected === 0 } else if (self._state.curExpected === 0
@ -168,7 +188,7 @@ ImapConnection.prototype.connect = function(loginCb) {
curReq._msg = msg; curReq._msg = msg;
curReq._fetcher.emit('message', msg); curReq._fetcher.emit('message', msg);
curReq._msgtype = (type.indexOf('HEADER') === 0 ? 'headers' : 'body'); curReq._msgtype = (type.indexOf('HEADER') === 0 ? 'headers' : 'body');
self._state.conn.emit('data', data.substr(data.indexOf(CRLF)+2)); self._state.conn.cleartext.emit('data', data.substr(data.indexOf(CRLF)+2));
//} //}
return; return;
} }
@ -181,7 +201,7 @@ ImapConnection.prototype.connect = function(loginCb) {
if (data.length > 1) { if (data.length > 1) {
data.slice(1).forEach(function(line) { data.slice(1).forEach(function(line) {
process.nextTick(function() { process.nextTick(function() {
self._state.conn.emit('data', line + CRLF); self._state.conn.cleartext.emit('data', line + CRLF);
}); });
}); });
} }
@ -697,15 +717,15 @@ ImapConnection.prototype._send = function(cmdstr, cb, bypass) {
clearTimeout(this._state.tmrKeepalive); clearTimeout(this._state.tmrKeepalive);
this._state.isIdle = false; this._state.isIdle = false;
var cmd = (bypass ? cmdstr : this._state.requests[0].command); var cmd = (bypass ? cmdstr : this._state.requests[0].command);
this._state.conn.write('A' + ++this._state.curId + ' ' + cmd + CRLF); this._state.conn.cleartext.write('A' + ++this._state.curId + ' ' + cmd + CRLF);
debug('<<SENT>>: A' + this._state.curId + ' ' + cmd); debug('<<SENT>>: A' + this._state.curId + ' ' + cmd);
} }
}; };
function ImapMessage() {} function ImapMessage() {}
sys.inherits(ImapMessage, EventEmitter); util.inherits(ImapMessage, EventEmitter);
function ImapFetch() {} function ImapFetch() {}
sys.inherits(ImapFetch, EventEmitter); util.inherits(ImapFetch, EventEmitter);
/****** Utility Functions ******/ /****** Utility Functions ******/
@ -1354,4 +1374,41 @@ function extend() {
// Return the modified object // Return the modified object
return target; return target;
}; };
net.Stream.prototype.setSecure = function() {
var pair = tls.createSecurePair();
var cleartext = pipe(pair, this);
pair.on('secure', function() {
process.nextTick(function() { cleartext.socket.emit('secure'); });
});
cleartext._controlReleased = true;
return cleartext;
};
function pipe(pair, socket) {
pair.encrypted.pipe(socket);
socket.pipe(pair.encrypted);
pair.fd = socket.fd;
var cleartext = pair.cleartext;
cleartext.socket = socket;
cleartext.encrypted = pair.encrypted;
function onerror(e) {
if (cleartext._controlReleased)
cleartext.socket.emit('error', e);
}
function onclose() {
socket.removeListener('error', onerror);
socket.removeListener('close', onclose);
}
socket.on('error', onerror);
socket.on('close', onclose);
return cleartext;
}
Loading…
Cancel
Save