client-side support for paged search

Re-applied paged search work by thomasv, without introducing logging
changes.
This commit is contained in:
Jason Pincin 2012-09-19 16:39:31 -04:00
parent 1531d89e36
commit 4de2aa3ed2
2 changed files with 61 additions and 0 deletions

View File

@ -37,6 +37,7 @@ var opts = {
'control': Array,
'password': String,
'persistent': Boolean,
'paged': Number,
'scope': String,
'timeout': Number,
'url': url
@ -49,6 +50,7 @@ var shortOpts = {
'D': ['--binddn'],
'w': ['--password'],
'p': ['--persistent'],
'g': ['--paged'],
's': ['--scope'],
't': ['--timeout'],
'u': ['--url']
@ -166,6 +168,10 @@ client.bind(parsed.binddn, parsed.password, function(err, res) {
});
controls.push(pCtrl);
}
if (parsed.paged) {
var ctrl = new ldap.PagedResultsControl({ value: { size: parsed.paged } });
controls.push(ctrl);
}
var req = {
scope: parsed.scope || 'sub',
filter: parsed.argv.remain[0],

View File

@ -10,6 +10,7 @@ var assert = require('assert-plus');
var Attribute = require('../attribute');
var Change = require('../change');
var Control = require('../controls/index').Control;
var PagedResultsControl = require('../controls/index').PagedResultsControl;
var Protocol = require('../protocol');
var dn = require('../dn');
var errors = require('../errors');
@ -770,6 +771,57 @@ Client.prototype._send = function _send(message, expect, emitter, callback) {
return callback(null, obj);
} // end function _done(event, obj)
function _continuePagedSearch(msg) {
// this function looks for a paged control in the response msg
// and continue searching or not according to RFC 2696 - http://www.ietf.org/rfc/rfc2696.txt
if (util.isArray(msg.controls) && msg.controls.length > 0) {
log.trace('message has %d controls', msg.controls.length);
for (var i=0; i<msg.controls.length; i++) {
var resControl = msg.controls[i];
// check paged control in response
if (resControl instanceof PagedResultsControl) {
log.debug('paged search: end of page');
if (resControl.value.cookie && resControl.value.cookie.length > 0) {
log.trace('paged search: received cookie in response');
if (util.isArray(message.controls) && message.controls.length > 0) {
for (var j=0; j<message.controls.length; j++) {
var reqControl = message.controls[j];
if (reqControl instanceof PagedResultsControl) {
// update request cookie and re-send
reqControl.value.cookie = resControl.value.cookie;
try {
log.debug('paged search: continuing');
conn.write(message.toBer());
return true;
} catch (e) {
if (timer)
clearTimeout(timer);
log.trace({err: e}, 'Error writing message to socket');
callback(e);
return false;
}
}
}
}
}
else {
log.debug('paged search done');
}
}
}
}
// not a paged search or all pages received
return false;
} // end function _continuePagedSearch(msg)
function messageCallback(msg) {
if (timer)
clearTimeout(timer);
@ -784,6 +836,9 @@ Client.prototype._send = function _send(message, expect, emitter, callback) {
var event = msg.constructor.name;
event = event[0].toLowerCase() + event.slice(1);
return _done(event, msg);
} else if (_continuePagedSearch(msg)) {
// page search continued, just return for now
return;
} else {
delete conn.ldap.messages[message.messageID];