Node-ldapjs: Client timeout doesn't work

Created on 12 Jul 2018  Â·  9Comments  Â·  Source: ldapjs/node-ldapjs

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?

Most helpful comment

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);
});

All 9 comments

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.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

lmusat picture lmusat  Â·  5Comments

narendrachoudhary picture narendrachoudhary  Â·  7Comments

abarik1981 picture abarik1981  Â·  4Comments

randomsock picture randomsock  Â·  7Comments

JohnPolansky picture JohnPolansky  Â·  3Comments