```
feat(service): 优化地址解析逻辑以支持端口号直接解析 重构 parseTraditionalStyle 函数,简化 NetworkAddress 构造方式, 并引入 utils.IsNumber 判断纯端口号情况,提升地址解析的准确性与兼容性。 ```
This commit is contained in:
parent
75aa6ae647
commit
139983134b
|
@ -5,6 +5,8 @@ import (
|
||||||
"net"
|
"net"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"git.apinb.com/bsm-sdk/core/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
type NetworkAddress struct {
|
type NetworkAddress struct {
|
||||||
|
@ -126,28 +128,24 @@ func determineTCPProtocol(host string) string {
|
||||||
|
|
||||||
// 解析传统格式如 ":8080", "127.0.0.1:8080", "/tmp/socket"
|
// 解析传统格式如 ":8080", "127.0.0.1:8080", "/tmp/socket"
|
||||||
func parseTraditionalStyle(addr string) (*NetworkAddress, error) {
|
func parseTraditionalStyle(addr string) (*NetworkAddress, error) {
|
||||||
result := &NetworkAddress{Raw: addr}
|
|
||||||
|
|
||||||
// 检查是否是 Unix socket(包含路径分隔符)
|
// 检查是否是 Unix socket(包含路径分隔符)
|
||||||
if strings.Contains(addr, "/") || strings.HasPrefix(addr, "@/") {
|
if strings.Contains(addr, "/") || strings.HasPrefix(addr, "@/") {
|
||||||
result.Protocol = "unix"
|
return &NetworkAddress{Protocol: "unix", Path: addr}, nil
|
||||||
result.Path = addr
|
|
||||||
return result, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 否则按 TCP 地址解析
|
// 否则按 TCP 地址解析
|
||||||
result.Protocol = "tcp"
|
|
||||||
|
|
||||||
host, port, err := net.SplitHostPort(addr)
|
host, port, err := net.SplitHostPort(addr)
|
||||||
if err != nil {
|
if err == nil {
|
||||||
return nil, fmt.Errorf("解析地址失败: %w", err)
|
return &NetworkAddress{Protocol: "tcp", Host: host, Port: port}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
result.Host = host
|
// 检查是否是端口号
|
||||||
result.Port = port
|
if ok := utils.IsNumber(addr); ok {
|
||||||
result.Protocol = determineTCPProtocol(host)
|
return &NetworkAddress{Protocol: "tcp", Host: "0.0.0.0", Port: addr}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, fmt.Errorf("解析地址失败: %w", err)
|
||||||
|
|
||||||
return result, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取网络类型用于 net.Dial 或 net.Listen
|
// 获取网络类型用于 net.Dial 或 net.Listen
|
||||||
|
|
|
@ -0,0 +1,129 @@
|
||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
"unicode"
|
||||||
|
)
|
||||||
|
|
||||||
|
// IsEmail 验证是否是邮箱格式
|
||||||
|
func IsEmail(email string) bool {
|
||||||
|
if strings.TrimSpace(email) == "" {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// 邮箱正则表达式
|
||||||
|
pattern := `^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$`
|
||||||
|
matched, err := regexp.MatchString(pattern, email)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return matched
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsMobile 验证是否是手机号(中国手机号格式)
|
||||||
|
func IsMobile(mobile string) bool {
|
||||||
|
if strings.TrimSpace(mobile) == "" {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// 中国手机号正则表达式:1开头,第二位3-9,后面9位数字
|
||||||
|
pattern := `^1[3-9]\d{9}$`
|
||||||
|
matched, err := regexp.MatchString(pattern, mobile)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return matched
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsNumber 验证是否是纯数字
|
||||||
|
func IsNumber(str string) bool {
|
||||||
|
if strings.TrimSpace(str) == "" {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, char := range str {
|
||||||
|
if !unicode.IsDigit(char) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsEnglish 验证是否是英文字符(不限大小写)
|
||||||
|
func IsEnglish(str string) bool {
|
||||||
|
if strings.TrimSpace(str) == "" {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, char := range str {
|
||||||
|
if !unicode.IsLetter(char) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if !isEnglishLetter(char) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsEnglishWithSpace 验证是否是英文字符(允许空格)
|
||||||
|
func IsEnglishWithSpace(str string) bool {
|
||||||
|
if strings.TrimSpace(str) == "" {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, char := range str {
|
||||||
|
if unicode.IsSpace(char) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if !unicode.IsLetter(char) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if !isEnglishLetter(char) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsAlphanumeric 验证是否是字母和数字组合
|
||||||
|
func IsAlphanumeric(str string) bool {
|
||||||
|
if strings.TrimSpace(str) == "" {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, char := range str {
|
||||||
|
if !unicode.IsLetter(char) && !unicode.IsDigit(char) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsStrongPassword 验证强密码(至少8位,包含大小写字母和数字)
|
||||||
|
func IsStrongPassword(password string) bool {
|
||||||
|
if len(password) < 8 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
var hasUpper, hasLower, hasDigit bool
|
||||||
|
|
||||||
|
for _, char := range password {
|
||||||
|
switch {
|
||||||
|
case unicode.IsUpper(char):
|
||||||
|
hasUpper = true
|
||||||
|
case unicode.IsLower(char):
|
||||||
|
hasLower = true
|
||||||
|
case unicode.IsDigit(char):
|
||||||
|
hasDigit = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return hasUpper && hasLower && hasDigit
|
||||||
|
}
|
||||||
|
|
||||||
|
// 辅助函数:判断是否是英文字母
|
||||||
|
func isEnglishLetter(char rune) bool {
|
||||||
|
return (char >= 'a' && char <= 'z') || (char >= 'A' && char <= 'Z')
|
||||||
|
}
|
Loading…
Reference in New Issue