SamDecrock / node-http-ntlm

Node.js module to authenticate using HTTP NTLM
MIT License
192 stars 89 forks source link

Does not support concurrent requests #5

Closed slimnate closed 1 year ago

slimnate commented 10 years ago

I am writing a node app that caches data from several different sharepoint collections, but problems occur when you perform simultaneous requests (I have each data endpoint caching concurrently). It seems as though the last request overrides any requests that have not yet completed. All requests will complete and call their callback function, but each callback contains the data from the last request made.

When running each request after the previous has returned, the issue does not arise, it is only when there are multiple requests made at a time.

var request = require('node-http-ntlm');
var urls = [
    'url1', //Returns 'data1'
    'ur2', //Returns 'data2'
    'url3' //Returns 'data3'
];
var opt, i;
for(i in urls){
    opt = {
        url: urls[i],
        //..credentials
    }
    request.get(opt, function(err, res){
        if(err){
            console.info(err);
        }else{
            console.info(res);
        }
    });
}

Should print (in no particular order, depending on which requests return first):

data1
data2
data3

actual output is

data3
data3
data3
slimnate commented 10 years ago

The problem was in my code, not yours. Closed.

larnera commented 8 years ago

Hi. I appreciate that this was closed two years ago but I am having the exact same issue as you @NathanSTG , I'm also even experiencing this issue when using SharePoint, just like you did.

What did you do to fix this? - if you can remember that is.

I'm having to make all call one after the other at the moment which kind of go against the strengths of using node.js in the first place.

Btw @SamDecrock - this is an awesome module! - thanks for providing this.

Many thanks

SamDecrock commented 8 years ago

@larnera Can you show me your code? Maybe I can help.

larnera commented 8 years ago

Thanks Sam. Appreciate it. I've quickly knocked up an example below.

if I call either getTopImage(), getTopAnnouncement() or getFormDigest() on their own, i get the desired results for that request.

If I call them all at the same time (in the example below) then all of them will show the same response or will fail completely. Similar to to what @NathanSTG had.

What I've been doing up to now to get around this is to call the next request in the callback - but this isn't ideal.

Any help would be great !

var httpntlm = require('httpntlm');
var merge = require('merge');

var host = 'https://www.SHAREPOINT.com/sites/games';

ntlmCreds = {
    username: 'MYUSERID',
    password: 'MYPASSWORD',
    domain: 'MYDOMAIN'
}

getTopImage();
getTopAnnouncement();
getFormDigest();

// Request 1 - return top announcement from list
function getTopAnnouncement() {
    var httpntlmConfig = merge(ntlmCreds, {
        url: host + "/_api/web/lists/getbytitle('Announcements')/items",
        headers: {
            "content-type": "application/json;odata=verbose",
            "Accept": "application/json;odata=verbose"
        }
    })

    httpntlm.get(httpntlmConfig, function (err, response) {
        if (err) {
            if (err) return console.log(err);
        } else {

            var spData = JSON.parse(response.body);
            console.log(spData.d.results[0]);
        }
    })
}

// Request 2 - get form digest
function getFormDigest() {
    var httpntlmConfig = merge(ntlmCreds, {
        url: host + "/_api/contextinfo",
        headers: {
            "content-type": "application/json;odata=verbose",
            "Accept": "application/json;odata=verbose"
        }
    })

    httpntlm.post(httpntlmConfig, function (err, response) {
        if (err) {
            if (err) return console.log(err);
        } else {
            console.log(response.body);
        }
    })
}

// Request 3 - return top image from list
function getTopImage() {
    var httpntlmConfig = merge(ntlmCreds, {
        url: host + "/_api/web/lists/getbytitle('Images')/items",
        headers: {
            "content-type": "application/json;odata=verbose",
            "Accept": "application/json;odata=verbose"
        }
    })

    httpntlm.get(httpntlmConfig, function (err, response) {
        if (err) {
            if (err) return console.log(err);
        } else {
            var spData = JSON.parse(response.body);
            console.log(spData.d.results[0]);
        }
    })
}
larnera commented 8 years ago

Sorry @SamDecrock, any thoughts on the above?

SamDecrock commented 7 years ago

I'm using setImmediate() in my code. This means that requests can be interrupted by other events. I suppose the server can't handle 3 concurrent authentications from the same client.

I suppose you don't really want to authenticate 3 times. Can't you authenticate once and the use the received cookies to stay in the session.

SamDecrock commented 1 year ago

Try passing in your own http agent, see https://github.com/SamDecrock/node-http-ntlm/issues/66