-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
fix(#124): resolve all *.localhost to localhost, and fix ipv6 issue #1114
Conversation
After some more thinking, I should probably do a dns lookup first and use the returned ip for localhost, and fallback to the ipv6 and ipv4 check if we can't connect to it, what do you think? @helloanoop |
Thanks for this fix @BrandonGillis ! |
@BrandonGillis Based on the research you have done, you clearly are more knowledgable on this issue than me :). Based on my reading I would also recommend caching the check in a variable const connectionCache = new Map(); // Cache to store checkConnection() results
const checkConnection = (host, port) =>
new Promise((resolve) => {
const key = `${host}:${port}`;
const cachedResult = connectionCache.get(key);
if (cachedResult !== undefined) {
resolve(cachedResult);
} else {
const socket = new Socket();
socket.once('connect', () => {
socket.end();
connectionCache.set(key, true); // Cache successful connection
resolve(true);
});
socket.once('error', () => {
connectionCache.set(key, false); // Cache failed connection
resolve(false);
});
// Try to connect to the host and port
socket.connect(port, host);
}
}); |
@BrandonGillis I had to temporarily disable this fix as it is breaking "localhost" resolution that used to work in my system. I am getting this error
DNS resolution logs on my systemResolving const dns = require('dns');
dns.lookup('localhost', (err, address, family) => {
console.log('address: %j family: IPv%s', address, family);
});
// console: address: "::1" family: IPv6 Resolving dns.lookup('[::1]', (err, address, family) => {
if (err) {
console.log(err);
return;
}
console.log('address: %j family: IPv%s', address, family);
});
// console
// Error: getaddrinfo ENOTFOUND [::1]
// at GetAddrInfoReqWrap.onlookup [as oncomplete] (node:dns:107:26) {
// errno: -3008,
// code: 'ENOTFOUND',
// syscall: 'getaddrinfo',
// hostname: '[::1]'
// } Axios debuggingconst axios = require('axios');
axios.get('http://[::1]:6000/ping')
.then(function (response) {
console.log(response.data);
})
.catch(function (error) {
console.log(error);
}); Above axios code when I run it independently fails on my system with the same |
@BrandonGillis I'd be willing to get on a call and fix this together. Let me know if this is possible, else no worries - we can continue to share findings here and get to a fix. |
Hello @helloanoop, I could be available at around 12h00 UTC+1 on the discord if you're available at that time, so we can take a look at the issue together. But I agree with you, I think we should first use a dns lookup, check the tcp connection and fallback to the fix I did if we can't reach it. Regarding your issue I had it too on Linux with [::1], can't remember how as it disappeared after, I'll have to dig it out |
Regarding your test with dns lookup dns.lookup('[::1]', (err, address, family) => {
if (err) {
console.log(err);
return;
}
console.log('address: %j family: IPv%s', address, family);
});
// console
// Error: getaddrinfo ENOTFOUND [::1]
// at GetAddrInfoReqWrap.onlookup [as oncomplete] (node:dns:107:26) {
// errno: -3008,
// code: 'ENOTFOUND',
// syscall: 'getaddrinfo',
// hostname: '[::1]'
// } this is normal, as it should be a hostname that's why it fail on [::1] |
After a quick search the issue your encountering on your machine is probably related to axios/axios#5333 |
After some digging, it looks like there's a different behaviour from dns resolution / axios / nodejs on windows & linux : Without my fix, here's the result on windows when using [::1] : And now, without my fix on Linux with [::1] : @helloanoop can you confirm that using |
@BrandonGillis Yes, I confirm So it looks like below code would work in windows, but will error on Mac and Linux const axios = require('axios');
const dns = require('dns');
axios.get('http://[::1]:6000/ping')
.then(function (response) {
console.log(response.data);
})
.catch(function (error) {
console.log(error);
});
dns.lookup('[::1]', (err, address, family) => {
if (err) {
console.log(err);
return;
}
console.log('address: %j family: IPv%s', address, family);
}); Below are the console logs for above code on Mac
|
I did test the code you provided on windows, and it works as expected :
EDIT: I opened a new PR that should handle all cases correctly, and work as expected on windows & linux |
Description
This PR fix #124, by correctly handling :
(see RFC: 6761 section 6.3 https://tools.ietf.org/html/rfc6761#section-6.3).
This fix is heavily inspired by how PostmanRuntime is handling it (https://github.com/postmanlabs/postman-runtime/blob/develop/lib/requester/core.js#L433), their handling is even more complex by overriding DNS lookup of node (https://github.com/postmanlabs/postman-runtime/blob/develop/lib/requester/core.js#L285).
I did some tests on windows & linux, and this PR correctly fix subdomains, or ipv6 issues.
If you have any comments on this PR let me know !
Contribution Checklist: