I'm creating a client with "timeout" option to be able to authenticate a user with the backup LDAP server if the main LDAP server is unavailable, but it doesn't work, the timeout is not triggered.
Wondering if that is a known bug, or can you please provide a working example with timeout option?
same for me +1
const ldap = require('ldapjs');
const client = ldap.createClient({
url: 'ldap://myldapserver.com:389’,
timeout: 1000, // Milliseconds client should let operations live for before timing out (Default: Infinity)
connectTimeout: 1000, // Milliseconds client should wait before timing out on TCP connections (Default: OS default)
});
client.on('error', (err) => {
reject(err);
});
client.on('timeout', (err) => {
reject(err);
});
client.on('connectTimeout', (err) => {
reject(err);
});
Is this still an issue? Or have you figured out how to make it work?
no, I haven’t figure out how to use it.
I can't make this work either. Even though timeout and connectionTimeout has been set, there is no timeout and the request takes forever. This is a quite serious problem for the API I'm building.
Can you provide a minimal failing example?
@jsumners "curl localhost:3000/working" will return saying it cannot connect immediately, but that seems to have to do with the address being set to 0.0.0.0. Using "curl localhost:3000/notworking" will not return at all (or at least not as long as I waited) - I expect that it should abort the connection attempt after the specified connectionTimeout. I hope this helps in finding the problem (or at least inform me on what I'm doing incorrect). :-)
const express = require('express');
const ldap = require('ldapjs');
const app = express();
const port = 3000;
app.get('/working', async (req, res) => {
try {
await createClient('ldap://0.0.0.0:389');
res.send('ok');
} catch (err) {
res.send('fail');
}
});
app.get('/notworking', async (req, res) => {
try {
await createClient('ldap://10.10.10.10:389');
res.send('ok');
} catch (err) {
res.send('fail');
}
});
app.listen(port, () => console.log('Test with "curl localhost:3000/working" and "curl localhost:3000/notworking"'));
const createClient = url =>
new Promise((resolve, reject) => {
const client = ldap.createClient({
url,
timeout: 1000,
connectTimeout: 1000,
});
client.once('error', () => {
reject('fail');
});
client.on('connect', () => {
resolve(client);
});
});
const ldap = require('ldapjs'); const client = ldap.createClient({ url: 'ldap://myldapserver.com:389’, timeout: 1000, // Milliseconds client should let operations live for before timing out (Default: Infinity) connectTimeout: 1000, // Milliseconds client should wait before timing out on TCP connections (Default: OS default) }); client.on('error', (err) => { reject(err); }); client.on('timeout', (err) => { reject(err); }); client.on('connectTimeout', (err) => { reject(err); });That's how we solved it. Thank you.
I am not sure how to write an integration test for this. The code in question is: https://github.com/ldapjs/node-ldapjs/blob/0ccbec6adba0d90bb485ee2869a18df6ca4d53d7/lib/client/client.js#L799-L836
Basically, the onConnect event is used to determine when a socket has been able to _initiate_ TCP handshake with the desired server but is unable to transmit any further data in the specified time. Attempting to connect to a localhost host server prevents this scenario from occurring.
The timeout event is used to track individual LDAP messages and the length of time it takes them to complete -- https://github.com/ldapjs/node-ldapjs/blob/0ccbec6adba0d90bb485ee2869a18df6ca4d53d7/lib/client/client.js#L1237-L1240
Again, this is pretty much impossible to "break" on a localhost connection.
So, as I understand this issue, the resolution is to use the connectTimeout option to handle situations where the client cannot connect to the server. Once a connection has been established, the value of the timeout option will govern things like the client.search method.
Most helpful comment