Batch 1 重构: - 新增 utils.ParseIPAllowList 统一 IP/CIDR 解析(含 localhost 特殊处理) - pprof.go/status.go/purge.go 改用统一函数,减少 ~66 行重复代码 - 新增 loadbalance.buildExcludeSet 统一排除集合构建 - 更新 pprof_test.go 适配统一字段 allowed []net.IPNet Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
93 lines
2.1 KiB
Go
93 lines
2.1 KiB
Go
// Package utils 提供通用工具函数
|
||
package utils
|
||
|
||
import (
|
||
"net"
|
||
)
|
||
|
||
// ParseIPAllowList 解析 IP/CIDR 白名单列表。
|
||
//
|
||
// 支持格式:
|
||
// - CIDR 格式:192.168.1.0/24、::1/128
|
||
// - 单个 IP:192.168.1.1(自动转换为 /32 或 /128)
|
||
// - 特殊值 "localhost":映射为 127.0.0.1/32 和 ::1/128
|
||
//
|
||
// 参数:
|
||
// - allow: IP/CIDR 字符串列表
|
||
//
|
||
// 返回值:
|
||
// - []net.IPNet: 解析后的网络列表
|
||
// - error: 解析失败时返回错误
|
||
func ParseIPAllowList(allow []string) ([]net.IPNet, error) {
|
||
if len(allow) == 0 {
|
||
return nil, nil
|
||
}
|
||
|
||
result := make([]net.IPNet, 0, len(allow)+2) // +2 for localhost expansion
|
||
|
||
for _, cidr := range allow {
|
||
// 处理 localhost 特殊情况
|
||
if cidr == "localhost" {
|
||
// localhost 解析为 127.0.0.1 和 ::1
|
||
if v4Net, err := parseCIDR("127.0.0.1/32"); err == nil {
|
||
result = append(result, *v4Net)
|
||
}
|
||
if v6Net, err := parseCIDR("::1/128"); err == nil {
|
||
result = append(result, *v6Net)
|
||
}
|
||
continue
|
||
}
|
||
|
||
// 尝试 CIDR 解析
|
||
_, network, err := net.ParseCIDR(cidr)
|
||
if err == nil && network != nil {
|
||
result = append(result, *network)
|
||
continue
|
||
}
|
||
|
||
// fallback: 尝试作为单个 IP 解析
|
||
ip := net.ParseIP(cidr)
|
||
if ip == nil {
|
||
return nil, err // 返回原始 CIDR 解析错误
|
||
}
|
||
|
||
// 转换为 CIDR 格式
|
||
var ipNet *net.IPNet
|
||
if ip.To4() != nil {
|
||
ipNet, _ = parseCIDR(cidr + "/32")
|
||
} else {
|
||
ipNet, _ = parseCIDR(cidr + "/128")
|
||
}
|
||
if ipNet != nil {
|
||
result = append(result, *ipNet)
|
||
}
|
||
}
|
||
|
||
return result, nil
|
||
}
|
||
|
||
// parseCIDR 是 net.ParseCIDR 的包装,返回 *net.IPNet 而不返回 net.IP
|
||
func parseCIDR(cidr string) (*net.IPNet, error) {
|
||
_, network, err := net.ParseCIDR(cidr)
|
||
return network, err
|
||
}
|
||
|
||
// IPInAllowList 检查 IP 是否在白名单中。
|
||
//
|
||
// 参数:
|
||
// - ip: 要检查的 IP 地址
|
||
// - allowList: 白名单网络列表
|
||
//
|
||
// 返回值:
|
||
// - bool: IP 在白名单中返回 true
|
||
func IPInAllowList(ip net.IP, allowList []net.IPNet) bool {
|
||
if len(allowList) == 0 {
|
||
return false
|
||
}
|
||
for _, network := range allowList {
|
||
if network.Contains(ip) {
|
||
return true
|
||
}
|
||
}
|
||
return false
|
||
} |