photoprism/pkg/http/header/ip.go
Michael Mayer 149f5e5731 CI: Apply Go linter recommendations to remaining "pkg/..." code #5330
Signed-off-by: Michael Mayer <michael@photoprism.app>
2025-11-22 16:14:43 +01:00

64 lines
1.5 KiB
Go

package header
import (
"net"
"regexp"
)
// IpRegExp matches characters allowed in IPv4 or IPv6 network addresses.
// Kept for backwards compatibility (other packages reference it), but IP() no longer uses it.
var IpRegExp = regexp.MustCompile(`[^a-zA-Z0-9:.]`)
const (
// IPv6Length represents the maximum length of an IPv6 address string.
IPv6Length = 39
)
// IsIP returns true if the string matches a valid IP address.
func IsIP(s string) bool {
return IP(s, "") != ""
}
// IP returns the sanitized and normalized network address if it is valid, or the default otherwise.
func IP(s, defaultIp string) string {
// Return default if invalid.
if s == "" || len(s) > 64 || s == defaultIp {
return defaultIp
}
// Filter invalid characters: allow only [A-Za-z0-9:.]
fastOK := true
for i := 0; i < len(s); i++ {
b := s[i]
isAlphaNum := (b >= '0' && b <= '9') || (b >= 'a' && b <= 'z') || (b >= 'A' && b <= 'Z')
if !isAlphaNum && b != ':' && b != '.' {
fastOK = false
break
}
}
if !fastOK {
dst := make([]byte, 0, len(s))
for i := 0; i < len(s); i++ {
c := s[i]
if (c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == ':' || c == '.' {
dst = append(dst, c)
}
}
s = string(dst)
if s == "" {
return defaultIp
}
}
// Limit string length to 39 characters.
if len(s) > IPv6Length {
s = s[:IPv6Length]
}
// Parse IP address and return it as string.
if ip := net.ParseIP(s); ip == nil {
return defaultIp
} else {
return ip.String()
}
}