Reputation: 40335
Express provides the request IP address via req.ip
(where req
is the request), but for IPv4 addresses it uses IPv6 notation, e.g.:
::ffff:1.2.3.4
I'm happy that it supports IPv6 with no fuss, but for UI purposes I'd like to display IPv4 addresses in IPv4 notation ("1.2.3.4") while, of course, still maintaining support for IPv6 addresses.
Can I get Express to use pure IPv4 notation for IPv4 request addresses?
Upvotes: 1
Views: 1788
Reputation: 40335
Well, I found one way to do it using the ipaddr.js module, which I found via this answer. That module can be used to check if the IPv6 address is an IPv4 address, and then convert if so. For example:
var ip = require('ipaddr.js')
function cleanupAddress (str) {
// if it's a valid ipv6 address, and if its a mapped ipv4 address,
// then clean it up. otherwise return the original string.
if (ip.IPv6.isValid(str)) {
var addr = ip.IPv6.parse(str);
if (addr.isIPv4MappedAddress())
return addr.toIPv4Address().toString();
}
return str
}
console.log(cleanupAddress('1.2.3.4'));
console.log(cleanupAddress('::ffff:1.2.3.4'));
console.log(cleanupAddress('::ffff:102:304'));
console.log(cleanupAddress('0:0:0:0:0:ffff:1.2.3.4'));
console.log(cleanupAddress('::1'));
console.log(cleanupAddress('2001:0db8:85a3:0000:0000:8a2e:0370:7334'));
Outputs:
1.2.3.4
1.2.3.4
1.2.3.4
1.2.3.4
::1
2001:0db8:85a3:0000:0000:8a2e:0370:7334
Which is what I am going for. I don't particularly mind adding another dependency so this seems OK.
Assuming that module is implemented correctly, this should provide full support for IPv4- and IPv6-compliant addresses of any form.
Here's a more complete test for the curious:
var ip = require('ipaddr.js')
function test (str) {
console.log(str);
console.log(' IPv4.isValid:', ip.IPv4.isValid(str));
console.log(' IPv6.isValid:', ip.IPv6.isValid(str));
if (ip.IPv6.isValid(str)) {
var addr = ip.IPv6.parse(str);
console.log(' IPv6.parse.toString:', addr.toString());
console.log(' IPv6.isIPv4MappedAddress:', addr.isIPv4MappedAddress());
if (addr.isIPv4MappedAddress()) {
console.log(' IPv6.toIPv4Address.toString:', addr.toIPv4Address().toString());
}
}
}
test('1.2.3.4')
test('::ffff:1.2.3.4')
test('0:0:0:0:0:ffff:1.2.3.4')
test('::1')
test('2001:0db8:85a3:0000:0000:8a2e:0370:7334')
Which outputs:
1.2.3.4
IPv4.isValid: true
IPv6.isValid: false
::ffff:1.2.3.4
IPv4.isValid: false
IPv6.isValid: true
IPv6.parse.toString: ::ffff:102:304
IPv6.isIPv4MappedAddress: true
IPv6.toIPv4Address.toString: 1.2.3.4
0:0:0:0:0:ffff:1.2.3.4
IPv4.isValid: false
IPv6.isValid: true
IPv6.parse.toString: ::ffff:102:304
IPv6.isIPv4MappedAddress: true
IPv6.toIPv4Address.toString: 1.2.3.4
::1
IPv4.isValid: false
IPv6.isValid: true
IPv6.parse.toString: ::1
IPv6.isIPv4MappedAddress: false
2001:0db8:85a3:0000:0000:8a2e:0370:7334
IPv4.isValid: false
IPv6.isValid: true
IPv6.parse.toString: 2001:db8:85a3::8a2e:370:7334
IPv6.isIPv4MappedAddress: false
Upvotes: 2