Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v5.0.0-beta.6 breaks IPv6 connectivity #206

Closed
jeffreykog opened this issue Nov 8, 2021 · 4 comments
Closed

v5.0.0-beta.6 breaks IPv6 connectivity #206

jeffreykog opened this issue Nov 8, 2021 · 4 comments

Comments

@jeffreykog
Copy link

jeffreykog commented Nov 8, 2021

I just upgraded from 5.0.0-beta4 to 5.0.0-beta8 and noticed that configuring the LocalBootstrap with an IPv6 literal address throws an error. I was able to trace it back to the following line: 7eb54d9#diff-c4a87cd5eb211b3a0ed9b3d49084ba200c40ef268f5117d0f4d48d1546d821b3R34

The issue can be reproduced with the following simple code:

const v3 = require('node-hue-api').v3;
v3.api.createLocal('fe80::1').connect('test');

It doesn't matter that the IPv6 address is not reachable when testing, as it is the validation that breaks here. The linked line of code puts :443 behind the IPv6 address, adding it as an additional octet which is invalid. url.format does handle this properly, by adding square brackets around the address (like this: [fe80::1]:443 instead of fe80::1:443).

This causes the following error to be thrown:

TypeError [ERR_INVALID_URL]: Invalid URL: https://fe80::1:443
    at onParseError (internal/url.js:259:9)
    at new URL (internal/url.js:335:5)
    at new LocalBootstrap (/data/jk-5/development/artnet-hue-entertainment/node_modules/node-hue-api/dist/cjs/api/http/LocalBootstrap.js:41:24)
    at Object.createLocal (/data/jk-5/development/artnet-hue-entertainment/node_modules/node-hue-api/dist/cjs/api/index.js:24:12)
    at Object.<anonymous> (/data/jk-5/development/artnet-hue-entertainment/reproduce.js:3:8)
    at Module._compile (internal/modules/cjs/loader.js:1068:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1097:10)
    at Module.load (internal/modules/cjs/loader.js:933:32)
    at Function.Module._load (internal/modules/cjs/loader.js:774:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:72:12) {
  input: 'https://fe80::1:443',
  code: 'ERR_INVALID_URL'
}

I can see why the url.format() call has been removed, as it was deprecated. But it seems that the deprecation has been revoked as the newer URL utility provides no good alternative for url.format. See nodejs/node#25099 and nodejs/node@c8383dd.

That would mean it's probably safe to restore to the old url.format approach, fixing IPv6 support in the process as it adds square brackets when needed.

Just posting this here to document the issue and start a discussion. If the maintainers agree to restore to url.format i'd be happy to contribute that.

@peter-murray
Copy link
Owner

Thank you for the detailed issue 🙇

I am somewhat cautious to add back in a Node.js specific library here, as this library is used in the browser as well as on Node.js code bases.

To satisfy the needs IPv6 support do you have knowledge in advance that you have an IPv6 address, or is this more open and you are providing a hostname, IPv4 or IPv6 address to the library in your use case?

@jeffreykog
Copy link
Author

I did not realise this was also used in the browser, so then i can understand the choice to remove it. Specifying the address family could be an option, but that presents a breaking API change (but that might be fine because this is 5.0.0). That will move the address family detection into my responsibility. But that still requires a change in node-hue-api, as baseUrl will need to be constructed with square brackets, and hostname without.

We have 3 possible inputs. An IPv4 address, an IPv6 address and a DNS hostname. We need to add brackets for the IPv6 address. Detecting these would not be to complicated, as a colon is only valid for an IPv6 address (and not for v4 or DNS). So we could simply check if an IPv6 address is given by checking .indexOf(':') !== -1, and adding square brackets if that's the case.

An other alternative would be to add a minor dependency on https://github.com/sindresorhus/ip-regex. But i do realise node-hue-api has very little dependencies currently, and keeping it that way is nice. But an ipv6 regex could be borrowed from that repository, as their license allows it.

My personal preference would go against specifying the address family, and in favor of the other two options.

peter-murray added a commit that referenced this issue Dec 17, 2021
@peter-murray
Copy link
Owner

I have just made the changes to v5.0.0-beta.9 which is published to the npm registry to be picked up.

I have added handling for the hostname to support all forms of IPv6 including if you happened to wrap it in []s. Can you try this out @jeffreykog and report back if it is working for you 🙇 ?

@jeffreykog
Copy link
Author

@peter-murray Awesome! I have tested it with an ipv4 literal address, ipv6 literal address and a hostname, and it all seems to work. Closing this 🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants