GithubHelp home page GithubHelp logo

Comments (25)

arcseldon avatar arcseldon commented on June 20, 2024

This bug has hit me too, but different variation. The API service I call responds with HTTP Content-type response: application/json;charset=UTF-8

Inside your code, node-rest-client.js, you check for isJSON, by doing a character comparision that only supports lowercase against two values:

application/json;charset=utf-8
application/json

Hence this is causing my data to be returned as a String, and not as a parsed JSON object as expected.

Please can you update the function:

 "isJSON":function(content) {
       var result = false;
       for (var i=0; i<this.jsonctype.length;i++){
           result = this.jsonctype[i] === content;
           if (result) break;
       }
    return result;
},

To support "content" being parsed to lower case before doing the check comparison?

Thanks very much.

from node-rest-client.

arcseldon avatar arcseldon commented on June 20, 2024

Please take a look at this - http://stackoverflow.com/questions/7718476/are-http-headers-content-type-c-case-sensitive?rq=1 It is slightly unclear, but I believe the part that states - http://www.w3.org/TR/html4/charset.html#h-5.2.1 says "Names for character encodings are case-insensitive". Should mean UTF and utf would both be supported.

from node-rest-client.

aacerox avatar aacerox commented on June 20, 2024

Hi

you can customize the content/type returned by server passing it as a parameter in client initialization (parameter "mimetypes") please see https://github.com/aacerox/node-rest-client#options-parameters.

So you can set responses to be parsed as json, customizing json content-type header returned by server in the following way:

var options ={

    // customize different content-types for json or xml connections, separated by comma    
    mimetypes:{
        json:["application/json","application/json;odata=verbose;charset=utf-8"]
    }
};

var client = new Client(options)

Hope this help.

from node-rest-client.

arcseldon avatar arcseldon commented on June 20, 2024

Already had that in place, thanks for the suggestion:

    options = {
        mimetypes: {
            json: ["application/json", "application/json;charset=utf-8", "application/json;charset=UTF-8"]
        },
        user: config.api.username,
        password: config.api.password
    },
    client = new Client(options);

from node-rest-client.

arcseldon avatar arcseldon commented on June 20, 2024

Doesn't work. Neither does:

  args = {
            path: {"id": id},
            headers: {"Content-Type": "application/json", "Accept": ["application/json", "application/json;charset=utf-8", "application/json;charset=UTF-8"]}
        };
    client.get(config.api.baseUrl + "api/v1/myUrl/${id}", args, function (data, response) {
        // data is still a string... ie.
       console.log(typeof data)  // string
    }

from node-rest-client.

arcseldon avatar arcseldon commented on June 20, 2024

The "jsonctype" variable inside isJSON continues to only display two values:

application/json;charset=utf-8
application/json

and hence fails because UTF is in uppercase in the content-type response from server. Please can you explain how I can augment "jsonctype" to either be case insenstive, or load "application/json;charset=UTF-8" as another argument in its array of values.

from node-rest-client.

arcseldon avatar arcseldon commented on June 20, 2024

Will you re-open this issue ? I don't think it should be closed. Otherwise your client does not support Grails Applications correctly. In fact, there seems to be more weight behind capitalization than lowercase.

from node-rest-client.

arcseldon avatar arcseldon commented on June 20, 2024

For anyone else's benefit, here is hackish work-around:

 // this method a short-term work-around to a bug
 // inside node-rest-client not parsing content-type UTF rather than utf
 var parseJSON = function (data) {
     if(typeof data === 'string') {
         try {
             return JSON.parse(data);
         } catch (Error) {
             winston.error('Failed to parse JSON for supplied data input');
             // do nothing more
         }
     }
     return data;
   };

from node-rest-client.

kdekooter avatar kdekooter commented on June 20, 2024

I prefer @aacerox options customization - gives you full control and documents itself.

from node-rest-client.

aacerox avatar aacerox commented on June 20, 2024

@arcseldon I've tried by myself and mimetype options customization works properly so I think there are no reasons to reopen the issue, but if you want I'll try to help you debug the client.

Could you please enable debug mode in client by setting env variable DEBUG to true (export DEBUG=true or set DEBUG=true) then call the client passing it mymetype initialization paremeter (as you said you had done) and send me the result of your client invocation??

from node-rest-client.

arcseldon avatar arcseldon commented on June 20, 2024

Thanks for offering to take a look. Here is the DEBUG output as requested.

You will see that initially jsonctype is:

jsonctype:
[ 'application/json',
'application/json;charset=utf-8',
'application/json;charset=UTF-8' ],

(I need the uppercase UTF-8 declaration).

But further down in the trace, it is:

jsonctype: [ 'application/json', 'application/json;charset=utf-8' ],

And it is always just [ 'application/json', 'application/json;charset=utf-8’ ] inside isJSON function check when looking at the variable assignments in debugger.

(i have removed some time stamps and auth username/password info only)

Cheers,

[API CLIENT] -> ConnectManager { xmlctype: [ 'application/xml', 'application/xml;charset=utf-8' ],
jsonctype:
[ 'application/json',
'application/json;charset=utf-8',
'application/json;charset=UTF-8' ],
isXML: [Function],
isJSON: [Function],
isValidData: [Function],
handleEnd: [Function],
handleResponse: [Function],
proxy: [Function],
normal: [Function],
listeners: [Function],
removeAllListeners: [Function],
removeListener: [Function],
once: [Function],
on: [Function],
addListener: [Function],
emit: [Function],
setMaxListeners: [Function],
_events: { error: [Function] } }

[API CLIENT] -> ConnectManager { xmlctype: [ 'application/xml', 'application/xml;charset=utf-8' ],
jsonctype: [ 'application/json', 'application/json;charset=utf-8' ],
isXML: [Function],
isJSON: [Function],
isValidData: [Function],
handleEnd: [Function],
handleResponse: [Function],
proxy: [Function],
normal: [Function],
listeners: [Function],
removeAllListeners: [Function],
removeListener: [Function],
once: [Function],
on: [Function],
addListener: [Function],
emit: [Function],
setMaxListeners: [Function],
_events: { error: [ [Function], [Function] ] } }23:18:38 [API CLIENT] -> connect URL = http://localhost:8080/api/v1/agencies/1

[API CLIENT] -> options pre connect { host: 'localhost',
port: '8080',
path: '/api/v1/agencies/1',
protocol: 'http',
auth: '',
method: 'GET',
clientRequest: { domain: null, _events: {}, _maxListeners: 10 } }

[API CLIENT] -> args = { path: { id: 1 },
headers:
{ 'Content-Type': 'application/json',
Accept:
[ 'application/json',
'application/json;charset=utf-8',
'application/json;charset=UTF-8' ] } }
23:18:38 [API CLIENT] -> args.data = undefined
23:18:38 [API CLIENT] -> FINAL SELF object ====> { options:
{ mimetypes: { json: [Object] },
},
useProxy: false,
useProxyTunnel: false,
proxy: undefined,
connection: {},
mimetypes:
{ json:
[ 'application/json',
'application/json;charset=utf-8',
'application/json;charset=UTF-8' ] },
methods: {},
get: [Function],
post: [Function],
put: [Function],
delete: [Function],
patch: [Function],
registerMethod: [Function],
unregisterMethod: [Function] }

[API CLIENT] -> options pre connect { host: 'localhost',
port: '8080',
path: '/api/v1/agencies/1',
auth: '',
method: 'GET',
headers:
{ 'Content-Type': 'application/json',
Accept:
[ 'application/json',
'application/json;charset=utf-8',
'application/json;charset=UTF-8' ] } }

[API CLIENT] -> options data undefined

[API CLIENT] -> content-type: application/json;charset=UTF-8

[API CLIENT] -> content-encoding: undefined

[API CLIENT] -> not compressed

On 28 Apr 2014, at 23:07, Alejandro Alvarez Acero [email protected] wrote:

@arcseldon I've tried by myself and mimetype options customization works properly so I think there are no reasons to reopen the issue, but if you want I'll try to help you debug the client.

Could you please enable debug mode in client by setting env variable DEBUG to true (export DEBUG=true or set DEBUG=true) then call the client passing it mymetype initialization paremeter (as you said you had done) and send me the result of your client invocation??


Reply to this email directly or view it on GitHub.

from node-rest-client.

arcseldon avatar arcseldon commented on June 20, 2024

Find that debug at the end:

[API CLIENT] -> options data undefined

odd. Here is the Client setup code:

options = {
        mimetypes: {
            json: ["application/json", "application/json;charset=utf-8", "application/json;charset=UTF-8"]
        },
        user: config.api.username,
        password: config.api.password
    },
    client = new Client(options);

Presumably, that would be all that is required to ensure the options were setup?

On 28 Apr 2014, at 23:27, Richard Seldon [email protected] wrote:

Thanks for offering to take a look. Here is the DEBUG output as requested.

You will see that initially jsonctype is:

jsonctype:
[ 'application/json',
'application/json;charset=utf-8',
'application/json;charset=UTF-8' ],

(I need the uppercase UTF-8 declaration).

But further down in the trace, it is:

jsonctype: [ 'application/json', 'application/json;charset=utf-8' ],

And it is always just [ 'application/json', 'application/json;charset=utf-8’ ] inside isJSON function check when looking at the variable assignments in debugger.

(i have removed some time stamps and auth username/password info only)

Cheers,

[API CLIENT] -> ConnectManager { xmlctype: [ 'application/xml', 'application/xml;charset=utf-8' ],
jsonctype:
[ 'application/json',
'application/json;charset=utf-8',
'application/json;charset=UTF-8' ],
isXML: [Function],
isJSON: [Function],
isValidData: [Function],
handleEnd: [Function],
handleResponse: [Function],
proxy: [Function],
normal: [Function],
listeners: [Function],
removeAllListeners: [Function],
removeListener: [Function],
once: [Function],
on: [Function],
addListener: [Function],
emit: [Function],
setMaxListeners: [Function],
_events: { error: [Function] } }

[API CLIENT] -> ConnectManager { xmlctype: [ 'application/xml', 'application/xml;charset=utf-8' ],
jsonctype: [ 'application/json', 'application/json;charset=utf-8' ],
isXML: [Function],
isJSON: [Function],
isValidData: [Function],
handleEnd: [Function],
handleResponse: [Function],
proxy: [Function],
normal: [Function],
listeners: [Function],
removeAllListeners: [Function],
removeListener: [Function],
once: [Function],
on: [Function],
addListener: [Function],
emit: [Function],
setMaxListeners: [Function],
_events: { error: [ [Function], [Function] ] } }23:18:38 [API CLIENT] -> connect URL = http://localhost:8080/api/v1/agencies/1

[API CLIENT] -> options pre connect { host: 'localhost',
port: '8080',
path: '/api/v1/agencies/1',
protocol: 'http',
auth: '',
method: 'GET',
clientRequest: { domain: null, _events: {}, _maxListeners: 10 } }

[API CLIENT] -> args = { path: { id: 1 },
headers:
{ 'Content-Type': 'application/json',
Accept:
[ 'application/json',
'application/json;charset=utf-8',
'application/json;charset=UTF-8' ] } }
23:18:38 [API CLIENT] -> args.data = undefined
23:18:38 [API CLIENT] -> FINAL SELF object ====> { options:
{ mimetypes: { json: [Object] },
},
useProxy: false,
useProxyTunnel: false,
proxy: undefined,
connection: {},
mimetypes:
{ json:
[ 'application/json',
'application/json;charset=utf-8',
'application/json;charset=UTF-8' ] },
methods: {},
get: [Function],
post: [Function],
put: [Function],
delete: [Function],
patch: [Function],
registerMethod: [Function],
unregisterMethod: [Function] }

[API CLIENT] -> options pre connect { host: 'localhost',
port: '8080',
path: '/api/v1/agencies/1',
auth: '',
method: 'GET',
headers:
{ 'Content-Type': 'application/json',
Accept:
[ 'application/json',
'application/json;charset=utf-8',
'application/json;charset=UTF-8' ] } }

[API CLIENT] -> options data undefined

[API CLIENT] -> content-type: application/json;charset=UTF-8

[API CLIENT] -> content-encoding: undefined

[API CLIENT] -> not compressed

On 28 Apr 2014, at 23:07, Alejandro Alvarez Acero [email protected] wrote:

@arcseldon I've tried by myself and mimetype options customization works properly so I think there are no reasons to reopen the issue, but if you want I'll try to help you debug the client.

Could you please enable debug mode in client by setting env variable DEBUG to true (export DEBUG=true or set DEBUG=true) then call the client passing it mymetype initialization paremeter (as you said you had done) and send me the result of your client invocation??


Reply to this email directly or view it on GitHub.

from node-rest-client.

aacerox avatar aacerox commented on June 20, 2024

Hi
seems very strange that you have duplicated traces on "ConnectManager" (first one with your custom "content-types" and second with the default ?!?!? ) and "options pre connect" (in this case, always with your custom "content-types") when client pass over this traces just once.

If you don't mind we can do the following trying to find a solution:

  1. modify node-rest-client.js adding a debug in JSON content-type evaluation (line 291)
        "isJSON":function(content){
                     debug("JSON content", content);
                     debug("JSON jsonctype", this.jsonctype);
            var result = false;
            for (var i=0; i<this.jsonctype.length;i++){
                result = this.jsonctype[i] === content;
                if (result) break;
            }

            return result;
        },
  1. Modify client invocation in your code, and execute it again:
    options = {
            mimetypes: {
                json: ["application/json", "application/json;charset=utf-8", "application/json;charset=UTF-8"]
            },
            user: config.api.username,
            password: config.api.password
        }; // in your code this was a comma not a semicolon


        // use var keyword to declare variable.
        var client = new Client(options);

The "undefined" you have found in the traces doesn't have to be with our problem (it's realated to JSON data posted when use POST, PUT or PATCH)

from node-rest-client.

arcseldon avatar arcseldon commented on June 20, 2024

Hi Alejandro,

Thanks again for your support!

Will do as you suggest, here is a bit of code to make it clear what I am doing by way of calling. The comma you picked up is nothing I believe, I am just declaring a single ‘var’ at the top, then comma-separating out the rest - but will try your approach below anyhow:

set up code:

var mailSender = require('../../common/utilities/mail')(config),
options = {
mimetypes: {
json: ["application/json", "application/json;charset=utf-8", "application/json;charset=UTF-8"]
},
user: config.api.username,
password: config.api.password
},
client = new Client(options);

calling function itself:

var getAgencyById = function (id) {
var deferred = Q.defer(),
args = {
path: {"id": id},
headers: {"Content-Type": "application/json", "Accept": ["application/json", "application/json;charset=utf-8", "application/json;charset=UTF-8"]}
};
client.get(config.api.baseUrl + "api/v1/agencies/${id}", args, function (data, response) {
if(response.statusCode !== 200) {
return responseErrorHandler(data, response, deferred);
}
deferred.resolve(data);
}).on('error', function (err) {
return operationalErrorHandler(err, deferred);
});
return deferred.promise;
};

Mocha test with Chai:

describe('getAgencyById', function () {
it('should return an agency', function (done) {
var id = 1;
agencyApi.getAgencyById(id)
.then(function (agencyJson) {
should.exist(agencyJson);
assert.typeOf(agencyJson, 'string');
var agency = JSON.parse(agencyJson);
assert.typeOf(agency, 'Object');
agency.should.have.property('addressline2');
expect(agency.addressline2).to.equal(‘123 High Street');
done();
}, function (err) {
should.not.exist(err);
done();
});
});
});

I have about another 40-50 functions that all use the node-rest-client, all with accompanying functional tests that all pass - just this issue around not getting a JSON Object, versus a string representation. Not a show stopper but certainly be nice to solve it prior to going into PRD - this is a commercial, cloud solution.

Cheers,

On 29 Apr 2014, at 00:17, Alejandro Alvarez Acero [email protected] wrote:

Hi
seems very strange that you have duplicated traces on "ConnectManager" (first one with your custom "content-types" and second with the default ?!?!? ) and "options pre connect" (in this case, always with your custom "content-types") when client pass over this traces just once.

If you don't mind we can do the following trying to find a solution:

modify node-rest-client.js adding a debug in JSON content-type evaluation (line 291)
"isJSON":function(content){
debug("JSON content", content);
debug("JSON jsonctype", this.jsonctype);
var result = false;
for (var i=0; i<this.jsonctype.length;i++){
result = this.jsonctype[i] === content;
if (result) break;
}

        return result;
    },

Modify client invocation in your code, and execute it again:
options = {
mimetypes: {
json: ["application/json", "application/json;charset=utf-8", "application/json;charset=UTF-8"]
},
user: config.api.username,
password: config.api.password
}; // in your code this was a comma not a semicolon

    // use var keyword to declare variable.
    var client = new Client(options);

The "undefined" you have found in the traces doesn't have to be with our problem (it's realated to JSON data posted when use POST, PUT or PATCH)


Reply to this email directly or view it on GitHub.

from node-rest-client.

arcseldon avatar arcseldon commented on June 20, 2024

Ok, the results of those two line DEBUG Statements are as follows:

[API CLIENT] -> JSON content application/json;charset=UTF-8
[API CLIENT] -> JSON jsonctype [ 'application/json', 'application/json;charset=utf-8’ ]

Switching the var stuff around:

[API CLIENT] -> JSON content application/json;charset=UTF-8
[API CLIENT] -> JSON jsonctype [ 'application/json', 'application/json;charset=utf-8’ ]

Ie. no difference. Any thoughts?

On 29 Apr 2014, at 00:17, Alejandro Alvarez Acero [email protected] wrote:

Hi
seems very strange that you have duplicated traces on "ConnectManager" (first one with your custom "content-types" and second with the default ?!?!? ) and "options pre connect" (in this case, always with your custom "content-types") when client pass over this traces just once.

If you don't mind we can do the following trying to find a solution:

modify node-rest-client.js adding a debug in JSON content-type evaluation (line 291)
"isJSON":function(content){
debug("JSON content", content);
debug("JSON jsonctype", this.jsonctype);
var result = false;
for (var i=0; i<this.jsonctype.length;i++){
result = this.jsonctype[i] === content;
if (result) break;
}

        return result;
    },

Modify client invocation in your code, and execute it again:
options = {
mimetypes: {
json: ["application/json", "application/json;charset=utf-8", "application/json;charset=UTF-8"]
},
user: config.api.username,
password: config.api.password
}; // in your code this was a comma not a semicolon

    // use var keyword to declare variable.
    var client = new Client(options);

The "undefined" you have found in the traces doesn't have to be with our problem (it's realated to JSON data posted when use POST, PUT or PATCH)


Reply to this email directly or view it on GitHub.

from node-rest-client.

aacerox avatar aacerox commented on June 20, 2024

Hi
Tonight (here in Spain is 19:00, don't know where are you) I'm going to create a branch to add some extra debug functionalities to the client code, to see if we can catch what's going on.

If I understood right, in your code first you initialize the client as you describe in "set up code", then you use that client several times, and then comes the "problematic" function as you describe in "calling function itself", right?.

Maybe there's another client instantiation between first initialization and problematic function call, that reset "content-types" to its default values?

from node-rest-client.

arcseldon avatar arcseldon commented on June 20, 2024

Hi,

Couple of important European Champions League games for Spain over next couple of days! Hope it will be Real Madrid vs Chelsea in the final, but we shall see. Every team in the semi-finals still has a chance, and Chelsea are missing half their squad for the second round tie against Athletico.
You support a team?

Re. location - Am in Japan hence the strange timestamps you might be seeing - 2 am here atm.

Re code … lol

Am running two Specs in the same folder (ie. two files each with their own set of API tests).

Yes, sharing a Client object for each test, but not (deliberately) changing any options etc on that Client anywhere.

Am going to comment out all the tests in one file, and all tests except one in the other and see what happens now.

Give you the results shortly.

Again, thanks for the help.

On 29 Apr 2014, at 01:53, Alejandro Alvarez Acero [email protected] wrote:

Hi
Tonight (here in Spain is 19:00, don't know where are you) I'm going to create a branch to add some extra debug functionalities to the client code, to see if we can catch what's going on.

If I understood right, in your code first you initialize the client as you describe in "set up code", then you use that client several times, and then comes the "problematic" function as you describe in "calling function itself", right?.

Maybe there's another client instantiation between first initialization and problematic function call, that reset "content-types" to its default values?


Reply to this email directly or view it on GitHub.

from node-rest-client.

arcseldon avatar arcseldon commented on June 20, 2024

Ok, solved.

2:17:26 [API CLIENT] -> JSON content application/json;charset=UTF-8
2:17:28 [API CLIENT] -> JSON jsonctype [ 'application/json',
'application/json;charset=utf-8',
'application/json;charset=UTF-8’ ]

So, now it is present, and the test works:

describe('getAgencyById', function () {
it('should return an agency', function (done) {
var id = 1;
agencyApi.getAgencyById(id)
.then(function (agency) {
should.exist(agency);
assert.typeOf(agency, 'Object');
agency.should.have.property('addressline2');
done();
}, function (err) {
should.not.exist(err);
done();
});
});

I think Mocha must be concurrently running both test Spec files in a way that is causing the Client options object to be overwritten somehow.

Let me ask you this - if I create a Client object inside a Module ie.

module.exports = function (config) {

// create Client object here

// declare method(s) that internally reference the Client object (and can access it via closure)

return {
method: method
};

}

Is that Client object in global namespace??? I thought it would be encapsulated in something similar to a function scope, and therefore be unaffected by another module declaring a Client object of the same name …?

The only “other” explanation is somehow that your code is referencing the Options object in Global namespace, and subsequent invocations passing in a different Options object overwrite that one. Please discount this possibility if you know for a fact that definitely is not happening.

Cheers,

On 29 Apr 2014, at 01:53, Alejandro Alvarez Acero [email protected] wrote:

Hi
Tonight (here in Spain is 19:00, don't know where are you) I'm going to create a branch to add some extra debug functionalities to the client code, to see if we can catch what's going on.

If I understood right, in your code first you initialize the client as you describe in "set up code", then you use that client several times, and then comes the "problematic" function as you describe in "calling function itself", right?.

Maybe there's another client instantiation between first initialization and problematic function call, that reset "content-types" to its default values?


Reply to this email directly or view it on GitHub.

from node-rest-client.

arcseldon avatar arcseldon commented on June 20, 2024

Hi Alejandro,

Quick question, as this would affect the design of my API layer, and is directly related to this.

Is it possible to declare two different Client objects, each with their own Options and use these at the same time (both located inside their own application modules)? I just want confirmation that by design attributes such as Options do not get overwritten by each other - as the results of this bug appear to indicate. You are not altering prototype info etc are you that would basically update all object instances?

Secondly, please let me know, it is safe to reuse the Client object right? I am not defining a new one with each function API call, rather I am instantiating one per module (API file), and then reusing that between all methods in the same module - they all just make calls on it passing in their own args (without changing the Options object).

Would really appreciate clarfication on the above. Thanks very much.

from node-rest-client.

aacerox avatar aacerox commented on June 20, 2024

Hi
WOW Japan!!, a friend of mine has been there just a week ago and is delighted with the people and the country. And talking about football If you ask me, I prefer that Chelsea won't be a team in the final, I live in Madrid but support Atletico, as we say here AUPA ATLETI!!

My intention when I create node-rest-client was that you could instantiate different autonomous instances of the client that obviously do not share configuration parameters, and as you said, with the target that you could use one instance of the client through many invocations, with the restriction that once the client has been initialized you can't change it's initialization parameters and that's exactly how client works.

As you can see in the following example you can use the client in different modules or in different instances and none of them share configuration parameters. In the case of the module pattern, each module maintains its own local scope where client is declared, so instances of that client created in different modules should never share any information. Instantiating the client in the global scope acts the same way, each variable has its own reference to different instances of the client that do not share any information at all.

var Client = require('../lib/node-rest-client.js').Client;



// declare as different instances
var client1 = new Client({                      
                            mimetypes:{
                                json:["application/json;charset=UTF-8;client1"],
                                xml:["application/xml;charset=UTF-8;client1"]
                            }
                    }),
                client2 = new Client({                      
                            mimetypes:{
                                json:["application/json;charset=utf-8;client2"],
                                xml:["application/xml;charset=utf-8;client2"]
                            }
                    });


// declare clent inside different module scopes
module.exports.moduleA=function(config){
    var client = new Client({                       
                            mimetypes:{
                                json:["application/json;charset=UTF-8"],
                                xml:["application/xml;charset=UTF-8"]
                            }
                    });

    return {
        "options":function(){return client.options}
    };
};



module.exports.moduleB=function(config){
    var client = new Client({                       
                            mimetypes:{
                                json:["application/json;charset=utf-8"],
                                xml:["application/xml;charset=utf-8"]
                            }
                    });

    return {
        "options":function(){return client.options}
    };
};

var modA = new module.exports.moduleA(),
    modB = new module.exports.moduleB();


console.log("================= module example =======================");
console.log("moduleA options",modA.options());
console.log("moduleB options",modB.options());

console.log("================= instance example =======================");
console.log("client1 options", client1.options);
console.log("client2 options", client2.options);

Maybe there's one place in your code where one previously declared global client var is reassigned inadvertently with another one overwriting first one. To check this you can create hashcodes for each client instance and check if the client is overwritten somewhere:

client1.hashcode = new Date().getTime() + 17;
client2.hashcode = new Date().getTime() + 31;

Hope you find a solution soon.

Best regards from Spain.

from node-rest-client.

arcseldon avatar arcseldon commented on June 20, 2024

Hi,

Lol - you had to be an Atletico supporter. Well the good news is that you are football supporter! Best of luck, Atletico are having a great season, a lot is being said of the Manager. Hope you win the league, but Chelsea win the ECL. Mind you, think Atletico are favourites to progress to the final - Chelsea got no away goal advantage and most of the best players cannot play either through injury or card penalties. But with Mourinho you never know..

Thanks for the detailed reply - that answered precisely what I was asking about and left no doubts about intended behaviour. Please add that to your official documentation on home page - it is really useful info!

Ok, so I put in hash codes, and yes, definitely each client instantiated (one per Spec) is keeping its own Client (the hash codes always match up). Also, inspecting the debug properties at runtime, I can see that the Options for each is also correctly assigned.

However, alas, the isJSON values is still wrong - it overwrites the jsonctype with whatever Spec gets executed (Client created) last.

In other words, you definitely have a bug in your application. this.jsonctype is NOT reading the Options.mimetypes.json values from the currently executing Client. It is somehow referencing whatever the Options.mimetypes.json value was for the last executed instantiation of Client.

Don’t have time to debug your code right now, as what I need is working on the basis that ALL my Clients have the same mime type values (they do now) - and I have to get a release done by tomorrow. But if I get some downtime, be happy to debug and determine where your code contains this bug.

It is NOT in my client code, if the information you provided below is the expected behaviour.

Good evening from Tokyo, Japan :)

On 29 Apr 2014, at 07:05, Alejandro Alvarez Acero [email protected] wrote:

Hi
WOW Japan!!, a friend of mine has been there just a week ago and is delighted with the people and the country. And talking about football If you ask me, I prefer that Chelsea won't be a team in the final, I live in Madrid but support Atletico, as we say here AUPA ATLETI!!

My intention when I create node-rest-client was that you could instantiate different autonomous instances of the client that obviously do not share configuration parameters, and as you said, with the target that you could use one instance of the client through many invocations, with the restriction that once the client has been initialized you can't change it's initialization parameters and that's exactly how client works.

As you can see in the following example you can use the client in different modules or in different instances and none of them share configuration parameters. In the case of the module pattern, each module maintains its own local scope where client is declared, so instances of that client created in different modules should never share any information. Instantiating the client in the global scope acts the same way, each variable has its own reference to different instances of the client that do not share any information at all.

var Client = require('../lib/node-rest-client.js').Client;

// declare as different instances
var client1 = new Client({
mimetypes:{
json:["application/json;charset=UTF-8;client1"],
xml:["application/xml;charset=UTF-8;client1"]
}
}),
client2 = new Client({
mimetypes:{
json:["application/json;charset=utf-8;client2"],
xml:["application/xml;charset=utf-8;client2"]
}
});

// declare clent inside different module scopes
module.exports.moduleA=function(config){
var client = new Client({
mimetypes:{
json:["application/json;charset=UTF-8"],
xml:["application/xml;charset=UTF-8"]
}
});

return {
    "options":function(){return client.options}
};

};

module.exports.moduleB=function(config){
var client = new Client({
mimetypes:{
json:["application/json;charset=utf-8"],
xml:["application/xml;charset=utf-8"]
}
});

return {
    "options":function(){return client.options}
};

};

var modA = new module.exports.moduleA(),
modB = new module.exports.moduleB();

console.log("================= module example =======================");
console.log("moduleA options",modA.options());
console.log("moduleB options",modB.options());

console.log("================= instance example =======================");
console.log("client1 options", client1.options);
console.log("client2 options", client2.options);
Maybe there's one place in your code where one previously declared global client var is reassigned inadvertently with another one overwriting first one. To check this you can create hashcodes for each client instance and check if the client is overwritten somewhere:

client1.hashcode = new Date().getTime() + 17;
client2.hashcode = new Date().getTime() + 31;
Hope you find a solution soon.

Best regards from Spain.


Reply to this email directly or view it on GitHub.

from node-rest-client.

OakRaven avatar OakRaven commented on June 20, 2024

I understand this issue has been closed, but I would like to ask one small question. First, I think the options literal is a great way to customize mapping options for JSON mime types. How ever, I think that we could reduce how often we need to use custom options by making the content-type comparison case insensitive.

What is wrong with the following amendment to the isJSON() method:

    "isJSON":function(content){
        var result = false;
        for (var i=0; i<this.jsonctype.length;i++){
            result = this.jsonctype[i].toLowerCase() === content.toLowerCase();
            if (result) break;
        }

        return result;
    },

I'm writing a cookbook for Packt and I wanted to include the node-rest-client (best I've seen while doing my research). I want to make a call to an open source web service that returns JSON, however it's coming back with a content-type of "application/json;charset=UTF-8".

I can include the mimetypes option for Client, but it seems like a case-insensitive match might prevent a large number of unnecessary overrides in the first place.

I was just wondering why a case-insensitive comparison wasn't used.

Thanks for the awesome work!

from node-rest-client.

arcseldon avatar arcseldon commented on June 20, 2024

Best of luck with the cookbook. Will look out for that when it gets published

Just wish to add that node-rest-client has been an excellent choice, and would fully support your decision to include it based on practical usage.

The ‘issue’ around isJSON options has been the only small discrepancy - everything else has been out of the box.

On 25 May 2014, at 06:37, @WebCoding4Fun [email protected] wrote:

I understand this issue has been closed, but I would like to ask one small question. First, I think the options literal is a great way to customize mapping options for JSON mime types. How ever, I think that we could reduce how often we need to use custom options by making the content-type comparison case insensitive.

What is wrong with the following amendment to the isJSON() method:

"isJSON":function(content){
    var result = false;
    for (var i=0; i<this.jsonctype.length;i++){
        result = this.jsonctype[i].toLowerCase() === content.toLowerCase();
        if (result) break;
    }

    return result;
},

I'm writing a cookbook for Packt and I wanted to include the node-rest-client (best I've seen while doing my research). I want to make a call to an open source web service that returns JSON, however it's coming back with a content-type of "application/json;charset=UTF-8".

I can include the mimetypes option for Client, but it seems like a case-insensitive match might prevent a large number of unnecessary overrides in the first place.

I was just wondering why a case-insensitive comparison wasn't used.

Thanks for the awesome work!


Reply to this email directly or view it on GitHub.

from node-rest-client.

aacerox avatar aacerox commented on June 20, 2024

Hi OakRaven

First of all thanks for your support. You're right, I didn't notice at all that the comparision was done in a case sensitive manner.

Tonight I'll modify the code to make a case INsensitive comparision in both "isJSON" method and "isXML" method.

Thanks for your help.

from node-rest-client.

sherpya avatar sherpya commented on June 20, 2024

what about different charset?
application/json;charset=ISO-8859-1,

I think you should parse the header and keep the charset or maybe convert to utf8, like this module https://www.npmjs.com/package/content-type

from node-rest-client.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.