diff --git a/docs/client.md b/docs/client.md index c267dab..7ff9f37 100644 --- a/docs/client.md +++ b/docs/client.md @@ -276,15 +276,15 @@ containing the following fields: |timeLimit |the maximum amount of time the server should take in responding, in seconds. Defaults to 10. Lots of servers will ignore this.| |paged |enable and/or configure automatic result paging| -Responses from the `search` method are an `EventEmitter` where you will get a -notification for each `searchEntry` that comes back from the server. You will -additionally be able to listen for a `searchReference`, `error` and `end` event. -Note that the `error` event will only be for client/TCP errors, not LDAP error -codes like the other APIs. You'll want to check the LDAP status code -(likely for `0`) on the `end` event to assert success. LDAP search results -can give you a lot of status codes, such as time or size exceeded, busy, -inappropriate matching, etc., which is why this method doesn't try to wrap up -the code matching. +Responses inside callback of the `search` method are an `EventEmitter` where you will get a notification for +each `searchEntry` that comes back from the server. You will additionally be able to listen for a `searchRequest` +, `searchReference`, `error` and `end` event. +`searchRequest` is emitted immediately after every `SearchRequest` is sent with a `SearchRequest` parameter. You can do operations +like `client.abandon` with `searchRequest.messageID` to abandon this search request. Note that the `error` event will +only be for client/TCP errors, not LDAP error codes like the other APIs. You'll want to check the LDAP status code +(likely for `0`) on the `end` event to assert success. LDAP search results can give you a lot of status codes, such as +time or size exceeded, busy, inappropriate matching, etc., which is why this method doesn't try to wrap up the code +matching. Example: @@ -298,6 +298,9 @@ const opts = { client.search('o=example', opts, (err, res) => { assert.ifError(err); + res.on('searchRequest', (searchRequest) => { + console.log('searchRequest: ', searchRequest.messageID); + }); res.on('searchEntry', (entry) => { console.log('entry: ' + JSON.stringify(entry.object)); }); diff --git a/lib/client/client.js b/lib/client/client.js index f54cf6a..b982c3a 100644 --- a/lib/client/client.js +++ b/lib/client/client.js @@ -1251,7 +1251,9 @@ Client.prototype._sendSocket = function _sendSocket (message, conn.end() } else if (emitter) { sentEmitter = true - return callback(null, emitter) + callback(null, emitter) + emitter.emit('searchRequest', message) + return } return false } diff --git a/lib/client/search_pager.js b/lib/client/search_pager.js index 83a77e9..cf4bfde 100644 --- a/lib/client/search_pager.js +++ b/lib/client/search_pager.js @@ -58,6 +58,7 @@ function SearchPager (opts) { this.started = false const emitter = new EventEmitter() + emitter.on('searchRequest', this.emit.bind(this, 'searchRequest')) emitter.on('searchEntry', this.emit.bind(this, 'searchEntry')) emitter.on('end', this._onEnd.bind(this)) emitter.on('error', this._onError.bind(this)) diff --git a/test/client.test.js b/test/client.test.js index 1b69454..7d27a86 100644 --- a/test/client.test.js +++ b/test/client.test.js @@ -777,14 +777,23 @@ tap.test('search paged', { timeout: 10000 }, function (t) { t.test('paged - no pauses', function (t2) { let countEntries = 0 let countPages = 0 + let currentSearchRequest = null t.context.client.search('cn=paged', { paged: { pageSize: 100 } }, function (err, res) { t2.error(err) res.on('searchEntry', entryListener) + res.on('searchRequest', (searchRequest) => { + t2.ok(searchRequest instanceof ldap.SearchRequest) + if (currentSearchRequest === null) { + t2.equal(countPages, 0) + } + currentSearchRequest = searchRequest + }) res.on('page', pageListener) res.on('error', (err) => t2.error(err)) - res.on('end', function () { + res.on('end', function (result) { t2.equal(countEntries, 1000) t2.equal(countPages, 10) + t2.equal(result.messageID, currentSearchRequest.messageID) t2.end() }) @@ -797,8 +806,11 @@ tap.test('search paged', { timeout: 10000 }, function (t) { countEntries += 1 } - function pageListener () { + function pageListener (result) { countPages += 1 + if (countPages < 10) { + t2.equal(result.messageID, currentSearchRequest.messageID) + } } }) })