peter-murray / node-hue-api

Node.js Library for interacting with the Philips Hue Bridge and Lights
Apache License 2.0
1.19k stars 145 forks source link

Can't connect to my Bridge, both nupnpSearch and upnpSearch return (different) errors #51

Closed cascornelissen closed 9 years ago

cascornelissen commented 9 years ago

When I run this code:

var hue = require("node-hue-api"),
    timeout = 200;

var displayBridges = function(bridge) {
    console.log("Hue Bridges Found: " + JSON.stringify(bridge));
};

hue.nupnpSearch().then(displayBridges).done();
hue.upnpSearch(timeout).then(displayBridges).done();

I get the following errors for the nupnpSearch:

XMLHttpRequest cannot load https://www.meethue.com/api/nupnp. A wildcard '*' cannot be used in the 'Access-Control-Allow-Origin' header when the credentials flag is true. Origin 'http://localhost:3000' is therefore not allowed access.
Uncaught TypeError: Cannot convert undefined or null to object
Uncaught Error: Network error

and these for the upnpSearch:

Uncaught TypeError: dgram.createSocket is not a function

But when I go to https://www.meethue.com/api/nupnp in my browser I get a JSON object containing an id and an internalipaddress, which seems right as http://192.168.2.2/ shows a Philips Hue page on my network...

I'm using this in an Angular project (although it results in the same errors when I completely remove Angular) in combination with Browserify on a XAMPP stack.

Any ideas on what's causing these erros and how to get either (or both, preferably) of these working on my end?

Version information node-hue-api: 1.0.5 Hue Bridge: latest I guess, I can't update it

peter-murray commented 9 years ago

The XMLHttpRequest is a CORS error. You are trying to access a website from another website or domain, look here for more details, https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS.

As for the dgram.createSocket, this is a Node.js module function. It does IO and is not one of the directly supported libraries in browserify. It may be possible to swap that out with a compatible library for a browser, like dgram-browserify, but I would have to look deeper into that. Considering it is not the API preferred approach, I don't think it's worth it.

I would suggest you look deeper into the CORS documentation link to see if you can narrow down you particular use case and whether or not there is something you can do about it.

If you get nowhere with that and can provide me with some source code example as to recreating the issue, then I would be able to look further into it.

cascornelissen commented 9 years ago

I'm sorry for the late reply. My motherboard failed the day after I opened this issue so I couldn't investigate further.

I tried to request the details via jQuery AJAX and got the correct response:

$.ajax({
    url: 'https://www.meethue.com/api/nupnp'
}).always(function(r) {
    console.log(r);
});

returns

[
    {
        id: "001788fffe158d63",
        internalipaddress: "192.168.2.2"
    }
]

I'll start investigating it further now but if you have any ideas I'd love to hear them :smiley:

cascornelissen commented 9 years ago

After checking the differences in network requests using Chrome devtools I noticed these differences:

My jQuery AJAX request has the request header accept: */* while the request made by node-hue-api has accept: application/json (as set in commands/traits/tApiMethod.js). When removing the || "application/json" from line 45 in that file I get the exact same request header as my jQuery AJAX request, so this isn't it.

The only other difference in requests is that the node-hue-api also has the cache-control: max-age=0 request header set.

Although I'm quite sure this is not what's causing it I'm still sharing it with you as it might give you something to think about.


I then changed my AJAX request to

$.ajax({
    url: 'https://www.meethue.com/api/nupnp',
    headers: {
        'accept': 'application/json',
        'cache-control': 'max-age=0'
    }
}).always(function(r) {
    console.log(r);
});

which returns the following error:

XMLHttpRequest cannot load https://www.meethue.com/api/nupnp. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access.

And I'm pretty sure that error is being caused by the cache-control header because the request returns the correct object when I remove that request header.

No idea if this is what's causing it again, but it might help!

peter-murray commented 9 years ago

This is still a CORs issue. It has nothing to do with the headers that you have indicated. You are trying to access a website from another domain, and the meet hue.com/api/nupnp is not supporting your source address from your website.

cascornelissen commented 9 years ago

Although I'm fine with you closing this issue, it is not a simple CORS issue. The jQuery AJAX method is right above the upnpSearch method and is working correctly. I have no idea what's causing it but for now I'll simply use that AJAX call via jQuery to get the details and I'll probably switch to a different npm module in the near future.

Thanks for the help though.

peter-murray commented 9 years ago

The error message you have provided is a CORS error. I have done a very simple conversion of the node-hue-api into a standalone self contained js file using browserify (which I assume you are still using).

I get a complete different result from you, in that request is screwing up the URL, into http://www.meethue.com:443/api/nupnp which is not valid, as it should be https, and if I fix the browserify generated code, then the CORS request executes correctly as restify sets the necessary cors related headers.

If you want me to look further into this, then you will have to provide me with the browserify command that you are running to generate the wrapper js file.

peter-murray commented 9 years ago

I got the other bottom of the changing of the https to http, and it is related to how request and resultant browserify code works. It switches the request from https to http as my express server that I had running was running over http.

When I switched the express server over to run under https, the code works as expected and the call to meet hue.com/api/nupnp returns the value of the bridges on my network.

This library is not really written to support its use in the browser, but if you do run your express server under https, then it the search/discovery should function as you desire.

cascornelissen commented 9 years ago

First of all, thanks for the further investigations and detailed information on your discoveries.

I'm running a simple BrowserSync server to develop the application but it will later on be packaged using nw.js, so no express there as far as I know.

I did some quick debugging and the hue.nuphpSearch() function results in a request header Request URL:https://www.meethue.com/api/nupnp so I don't think that the protocol is what is going wrong, unfortunately.

For your first question, I'm using the gulp-browserify module in combination with gulp-watchify based on this snippet.

If you want, I can send you the entire project so you can debug a little yourself.

I'll try and see if I can debug some more later today or tomorrow regarding the protocol issues.

peter-murray commented 9 years ago

I am happy to take a look at your project, if you can make the source available to me.

Sent from my iPad

On 26 Jul 2015, at 12:30, Cas Cornelissen notifications@github.com<mailto:notifications@github.com> wrote:

First of all, thanks for the further investigations and detailed information on your discoveries.

I'm running a simple BrowserSync server to develop the application but it will later on be packaged using nw.js, so no express there as far as I know.

I did some quick debugging and the hue.nuphpSearch() function results in a request header Request URL:https://www.meethue.com/api/nupnp so I don't think that the protocol is what is going wrong, unfortunately.

For your first question, I'm using the gulp-browserify module in combination with gulp-watchify based on this snippethttps://github.com/gulpjs/gulp/blob/master/docs/recipes/fast-browserify-builds-with-watchify.md.

If you want, I can send you the entire project so you can debug a little yourself.

Reply to this email directly or view it on GitHubhttps://github.com/peter-murray/node-hue-api/issues/51#issuecomment-124974342.

cascornelissen commented 9 years ago

@peter-murray, is there any way to contact you privately as I would like to keep my project private for some time.

peter-murray commented 9 years ago

I have added you as a collaborator on a private repository under my account called "private-repo", we can utilize that.