mirror of
https://github.com/grafana/grafana.git
synced 2024-11-29 20:24:18 -06:00
b858a5f496
* Bugfix: Fix parsing of IPv6 addresses Make sure that IPv6 addresses aren't truncated when parsing. Fixes #18924 * util: Change network address parsing funcs to return error * pkg/api: Return NetworkAddress instead of host/port
87 lines
2.0 KiB
Go
87 lines
2.0 KiB
Go
package util
|
|
|
|
import (
|
|
"fmt"
|
|
"net"
|
|
"strings"
|
|
|
|
"github.com/grafana/grafana/pkg/util/errutil"
|
|
)
|
|
|
|
// ParseIPAddress parses an IP address and removes port and/or IPV6 format
|
|
func ParseIPAddress(input string) (string, error) {
|
|
addr, err := SplitHostPort(input)
|
|
if err != nil {
|
|
return "", errutil.Wrapf(err, "Failed to split network address '%s' by host and port",
|
|
input)
|
|
}
|
|
|
|
ip := net.ParseIP(addr.Host)
|
|
if ip == nil {
|
|
return addr.Host, nil
|
|
}
|
|
|
|
if ip.IsLoopback() {
|
|
if strings.Contains(addr.Host, ":") {
|
|
// IPv6
|
|
return "::1", nil
|
|
}
|
|
return "127.0.0.1", nil
|
|
}
|
|
|
|
return ip.String(), nil
|
|
}
|
|
|
|
type NetworkAddress struct {
|
|
Host string
|
|
Port string
|
|
}
|
|
|
|
// SplitHostPortDefault splits ip address/hostname string by host and port. Defaults used if no match found
|
|
func SplitHostPortDefault(input, defaultHost, defaultPort string) (NetworkAddress, error) {
|
|
addr := NetworkAddress{
|
|
Host: defaultHost,
|
|
Port: defaultPort,
|
|
}
|
|
if len(input) == 0 {
|
|
return addr, fmt.Errorf("Input is empty")
|
|
}
|
|
|
|
start := 0
|
|
// Determine if IPv6 address, in which case IP address will be enclosed in square brackets
|
|
if strings.Index(input, "[") == 0 {
|
|
addrEnd := strings.LastIndex(input, "]")
|
|
if addrEnd < 0 {
|
|
// Malformed address
|
|
return addr, fmt.Errorf("Malformed IPv6 address: '%s'", input)
|
|
}
|
|
|
|
start = addrEnd
|
|
}
|
|
if strings.LastIndex(input[start:], ":") < 0 {
|
|
// There's no port section of the input
|
|
// It's still useful to call net.SplitHostPort though, since it removes IPv6
|
|
// square brackets from the address
|
|
input = fmt.Sprintf("%s:%s", input, defaultPort)
|
|
}
|
|
|
|
host, port, err := net.SplitHostPort(input)
|
|
if err != nil {
|
|
return addr, errutil.Wrapf(err, "net.SplitHostPort failed for '%s'", input)
|
|
}
|
|
|
|
if len(host) > 0 {
|
|
addr.Host = host
|
|
}
|
|
if len(port) > 0 {
|
|
addr.Port = port
|
|
}
|
|
|
|
return addr, nil
|
|
}
|
|
|
|
// SplitHostPort splits ip address/hostname string by host and port
|
|
func SplitHostPort(input string) (NetworkAddress, error) {
|
|
return SplitHostPortDefault(input, "", "")
|
|
}
|