UNPKG

3.4 kBJavaScriptView Raw
1// Licensed to the Software Freedom Conservancy (SFC) under one
2// or more contributor license agreements. See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership. The SFC licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License. You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied. See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18'use strict'
19
20const os = require('os')
21
22function getLoInterface() {
23 let name
24 if (process.platform === 'darwin') {
25 name = 'lo0'
26 } else if (process.platform === 'linux') {
27 name = 'lo'
28 }
29 return name ? os.networkInterfaces()[name] : null
30}
31
32/**
33 * Queries the system network interfaces for an IP address.
34 * @param {boolean} loopback Whether to find a loopback address.
35 * @param {string} family The IP family (IPv4 or IPv6). Defaults to IPv4.
36 * @return {(string|undefined)} The located IP address or undefined.
37 */
38function getAddress(loopback, family) {
39 let interfaces
40 if (loopback) {
41 let lo = getLoInterface()
42 interfaces = lo ? [lo] : null
43 }
44 interfaces = interfaces || os.networkInterfaces()
45 for (let key in interfaces) {
46 if (!Object.prototype.hasOwnProperty.call(interfaces, key)) {
47 continue
48 }
49
50 for (let ipAddress of interfaces[key]) {
51 if (ipAddress.family === family && ipAddress.internal === loopback) {
52 return ipAddress.address
53 }
54 }
55 }
56 return undefined
57}
58
59// PUBLIC API
60
61/**
62 * Retrieves the external IP address for this host.
63 * @param {string=} family The IP family to retrieve. Defaults to "IPv4".
64 * @return {(string|undefined)} The IP address or undefined if not available.
65 */
66exports.getAddress = function (family = 'IPv4') {
67 return getAddress(false, family)
68}
69
70/**
71 * Retrieves a loopback address for this machine.
72 * @param {string=} family The IP family to retrieve. Defaults to "IPv4".
73 * @return {(string|undefined)} The IP address or undefined if not available.
74 */
75exports.getLoopbackAddress = function (family = 'IPv4') {
76 return getAddress(true, family)
77}
78
79/**
80 * Splits a hostport string, e.g. "www.example.com:80", into its component
81 * parts.
82 *
83 * @param {string} hostport The string to split.
84 * @return {{host: string, port: ?number}} A host and port. If no port is
85 * present in the argument `hostport`, port is null.
86 */
87exports.splitHostAndPort = function (hostport) {
88 let lastIndex = hostport.lastIndexOf(':')
89 if (lastIndex < 0) {
90 return { host: hostport, port: null }
91 }
92
93 let firstIndex = hostport.indexOf(':')
94 if (firstIndex != lastIndex && !hostport.includes('[')) {
95 // Multiple colons but no brackets, so assume the string is an IPv6 address
96 // with no port (e.g. "1234:5678:9:0:1234:5678:9:0").
97 return { host: hostport, port: null }
98 }
99
100 let host = hostport.slice(0, lastIndex)
101 if (host.startsWith('[') && host.endsWith(']')) {
102 host = host.slice(1, -1)
103 }
104
105 let port = parseInt(hostport.slice(lastIndex + 1), 10)
106 return { host, port }
107}