Comparing version 0.2.7 to 0.2.8
@@ -145,2 +145,3 @@ // Copyright 2011 Mark Cavage, Inc. All rights reserved. | ||
this.connection = null; | ||
this.connect(); | ||
@@ -156,4 +157,5 @@ } | ||
* | ||
* @param {Function} callback invoked when `connect()` is done. | ||
*/ | ||
Client.prototype.connect = function() { | ||
Client.prototype.connect = function(callback) { | ||
if (this.connection) | ||
@@ -163,8 +165,30 @@ return; | ||
var self = this; | ||
this.connection = this._newConnection(); | ||
this.connection.on('end', function() { | ||
delete self.connection; | ||
var connection = this.connection = this._newConnection(); | ||
function reconnect() { | ||
self.connection = null; | ||
if (self.reconnect) | ||
setTimeout(function() { self.connect(); }, self.reconnect); | ||
} | ||
this.connection.on('close', function(had_err) { | ||
self.emit('close', had_err); | ||
reconnect(); | ||
}); | ||
this.connection.on('connect', function() { | ||
if (self._bindDN && self._credentials) | ||
return self.bind(self._bindDN, self._credentials, function(err) { | ||
if (err) | ||
c.end(); | ||
self.emit('connect') | ||
}); | ||
self.emit('connect') | ||
}); | ||
}; | ||
/** | ||
@@ -194,6 +218,7 @@ * Performs a simple authentication against the server. | ||
this.connect(); | ||
var self = this; | ||
var req = new BindRequest({ | ||
name: (typeof(name) === 'string') ? dn.parse(name) : name, | ||
name: name, | ||
authentication: 'Simple', | ||
@@ -617,3 +642,21 @@ credentials: credentials, | ||
var res = new EventEmitter(); | ||
// This is some whacky logic to account for the connection not being | ||
// reconnected, and having thrown an error like "NotWriteable". Because | ||
// the event emitter logic will never block, we'll end up returning from | ||
// the event.on('error'), rather than "normally". | ||
var self = this; | ||
var done = false; | ||
function errorIfNoConn(err) { | ||
if (done) | ||
return; | ||
done = true; | ||
return callback(err); | ||
} | ||
res.once('error', errorIfNoConn); | ||
this._send(req, [errors.LDAP_SUCCESS], res); | ||
done = true; | ||
res.removeListener('error', errorIfNoConn); | ||
return callback(null, res); | ||
@@ -643,2 +686,5 @@ }; | ||
if (!this.connect) | ||
return callback(); | ||
var req = new UnbindRequest(); | ||
@@ -655,6 +701,10 @@ return self._send(req, 'unbind', callback); | ||
var conn = this.connection || connection; | ||
var conn = connection || this.connection; | ||
var self = this; | ||
if (!conn) { | ||
function closedConn() { | ||
if (conn) | ||
conn.destroy(); | ||
if (typeof(callback) === 'function') | ||
@@ -666,2 +716,5 @@ return callback(new ConnectionError('no connection')); | ||
if (!conn) | ||
return closedConn(); | ||
// Now set up the callback in the messages table | ||
@@ -691,3 +744,2 @@ message.messageID = conn.ldap.nextMessageID; | ||
callback.emit('end', res); | ||
} else if (res instanceof SearchEntry) { | ||
@@ -702,4 +754,7 @@ assert.ok(callback instanceof EventEmitter); | ||
} else if (res instanceof Error) { | ||
return callback(res); | ||
if (typeof(callback) === 'function') | ||
return callback(res); | ||
assert.ok(callback instanceof EventEmitter); | ||
callback.emit('error', res); | ||
} else { | ||
@@ -736,3 +791,9 @@ delete conn.ldap.messages[message.messageID]; | ||
} | ||
return conn.write(message.toBer(), _writeCb); | ||
try { | ||
return conn.write(message.toBer(), _writeCb); | ||
} catch (e) { | ||
conn.end(); | ||
return closedConn(); | ||
} | ||
}; | ||
@@ -748,3 +809,13 @@ | ||
if (this.secure) { | ||
c = tls.connect(connectOpts.port, connectOpts.host); | ||
c = tls.connect(connectOpts.port, connectOpts.host, function() { | ||
if (log.isTraceEnabled()) | ||
log.trace('%s connect event', c.ldap.id); | ||
c.ldap.connected = true; | ||
c.ldap.id += ':' + c.fd; | ||
c.emit('connect', true); | ||
}); | ||
c.setKeepAlive = function(enable, delay) { | ||
return c.socket.setKeepAlive(enable, delay); | ||
}; | ||
} else { | ||
@@ -773,29 +844,17 @@ c = net.createConnection(connectOpts.port, connectOpts.host); | ||
c.on('connect', function() { | ||
if (log.isTraceEnabled()) | ||
log.trace('%s connect event', c.ldap.id); c.ldap.connected = true; | ||
c.ldap.id += ':' + c.fd; | ||
self.emit('connect', c.ldap.id); | ||
if (log.isTraceEnabled()) | ||
log.trace('%s connect event', c.ldap.id); | ||
if (self._bindDN && self._credentials) { // reconnect case | ||
self.bind(self._bindDN, self._credentials, [], function(err) { | ||
if (err) { | ||
log.trace('%s error rebinding: %s', c.ldap.id, err.stack); | ||
return c.end(); | ||
} | ||
self.connection = c; | ||
}, c); | ||
} else { | ||
self.connection = c; | ||
} | ||
}); | ||
c.on('end', function() { | ||
self.emit('end'); | ||
if (log.isTraceEnabled()) | ||
log.trace('%s end event', c.ldap.id); | ||
c.end(); | ||
}); | ||
c.addListener('close', function(had_err) { | ||
self.emit('close', had_err); | ||
c.on('close', function(had_err) { | ||
if (log.isTraceEnabled()) | ||
@@ -824,22 +883,15 @@ log.trace('%s close event had_err=%s', c.ldap.id, had_err ? 'yes' : 'no'); | ||
} | ||
delete c.ldap; | ||
delete c.parser; | ||
}); | ||
delete c.ldap; | ||
if (self.reconnect) { | ||
self.connection = null; | ||
setTimeout(function() { | ||
delete c.unbindMessageID; | ||
self._newConnection(); | ||
}, self.reconnect); | ||
} | ||
}); | ||
c.on('error', function(err) { | ||
if (log.isTraceEnabled()) | ||
log.trace('%s error event=%s', c.ldap.id, err ? err.stack : '?'); | ||
if (self.listeners('error').length) | ||
self.emit('error', err); | ||
if (log.isTraceEnabled()) | ||
log.trace('%s error event=%s', c.ldap.id, err ? err.stack : '?'); | ||
c.end(); | ||
@@ -849,3 +901,2 @@ }); | ||
c.on('timeout', function() { | ||
self.emit('timeout'); | ||
if (log.isTraceEnabled()) | ||
@@ -860,2 +911,3 @@ log.trace('%s timeout event=%s', c.ldap.id); | ||
log.trace('%s data event: %s', c.ldap.id, util.inspect(data)); | ||
c.parser.write(data); | ||
@@ -867,4 +919,4 @@ }); | ||
message.connection = c; | ||
var callback = c.ldap.messages[message.messageID]; | ||
var callback = c.ldap.messages[message.messageID]; | ||
if (!callback) { | ||
@@ -871,0 +923,0 @@ log.error('%s: unsolicited message: %j', c.ldap.id, message.json); |
@@ -27,11 +27,6 @@ // Copyright 2011 Mark Cavage, Inc. All rights reserved. | ||
function BindRequest(options) { | ||
if (options) { | ||
if (typeof(options) !== 'object') | ||
throw new TypeError('options must be an object'); | ||
if (options.name && !(options.name instanceof dn.DN)) | ||
throw new TypeError('options.entry must be a DN'); | ||
if (options && typeof(options) !== 'object') | ||
throw new TypeError('options must be an object'); | ||
} else { | ||
options = {}; | ||
} | ||
options = options || {}; | ||
@@ -38,0 +33,0 @@ options.protocolOp = Protocol.LDAP_REQ_BIND; |
@@ -6,3 +6,3 @@ { | ||
"description": "LDAP client and server APIs", | ||
"version": "0.2.7", | ||
"version": "0.2.8", | ||
"repository": { | ||
@@ -9,0 +9,0 @@ "type": "git", |
@@ -569,15 +569,12 @@ // Copyright 2011 Mark Cavage, Inc. All rights reserved. | ||
test('unbind and reconnect (GH-30)', function(t) { | ||
test('unbind (GH-30)', function(t) { | ||
client.unbind(function(err) { | ||
t.ifError(err); | ||
client.once('connect', function() { | ||
t.end(); | ||
}); | ||
client.connect(); | ||
t.end(); | ||
}); | ||
}); | ||
test('shutdown', function(t) { | ||
client.unbind(function(err) { | ||
t.ifError(err); | ||
server.on('close', function() { | ||
@@ -584,0 +581,0 @@ t.end(); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
444042
9376
4