mirror of https://github.com/allinssl/allinssl
feat(siteMonitor): add support for custom ports
parent
29a7579743
commit
497b45de83
|
@ -8,6 +8,7 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
// SSLInfo 定义结果结构体
|
// SSLInfo 定义结果结构体
|
||||||
|
@ -188,18 +189,48 @@ func UpdInfo(id, domain string, s *public.Sqlite, reportType string) error {
|
||||||
return errCheck
|
return errCheck
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ExtractHostPort 从 target 中提取 host 和 port 并校验,若无 port 则使用默认值
|
||||||
|
func ExtractAndValidateHostPort(target, defaultPort string) (host string, port string, err error) {
|
||||||
|
host = target
|
||||||
|
port = defaultPort
|
||||||
|
|
||||||
|
// 处理带端口情况
|
||||||
|
if strings.Contains(target, ":") {
|
||||||
|
h, p, splitErr := net.SplitHostPort(target)
|
||||||
|
if splitErr == nil {
|
||||||
|
host, port = h, p
|
||||||
|
} else if !(strings.Count(target, ":") >= 2) || strings.Contains(target, "]") {
|
||||||
|
return "", "", fmt.Errorf("地址格式错误:%v", splitErr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证端口是数字且在有效范围内
|
||||||
|
portNum, convErr := strconv.Atoi(port)
|
||||||
|
if convErr != nil || portNum < 1 || portNum > 65535 {
|
||||||
|
return "", "", fmt.Errorf("端口号非法:%s", port)
|
||||||
|
}
|
||||||
|
|
||||||
|
return host, port, nil
|
||||||
|
}
|
||||||
|
|
||||||
// CheckWebsite 实际检测函数
|
// CheckWebsite 实际检测函数
|
||||||
func CheckWebsite(target string) (*SSLInfo, error) {
|
func CheckWebsite(target string) (*SSLInfo, error) {
|
||||||
result := &SSLInfo{Target: target}
|
result := &SSLInfo{Target: target}
|
||||||
|
|
||||||
|
host, port, err := ExtractAndValidateHostPort(target, "443")
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
// 验证格式是否是 IP 或域名
|
// 验证格式是否是 IP 或域名
|
||||||
if net.ParseIP(target) == nil {
|
if net.ParseIP(host) == nil {
|
||||||
if _, err := net.LookupHost(target); err != nil {
|
if _, err := net.LookupHost(host); err != nil {
|
||||||
return result, fmt.Errorf("无效域名或 IP:%v", err)
|
return result, fmt.Errorf("无效域名或 IP:%v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hostPort := net.JoinHostPort(target, "443")
|
hostPort := net.JoinHostPort(host, port)
|
||||||
|
|
||||||
// result := &SSLInfo{Target: target}
|
// result := &SSLInfo{Target: target}
|
||||||
|
|
||||||
|
@ -213,7 +244,7 @@ func CheckWebsite(target string) (*SSLInfo, error) {
|
||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
|
|
||||||
// 发送 HTTPS 请求检测状态
|
// 发送 HTTPS 请求检测状态
|
||||||
resp, err := http.Get("https://" + target)
|
resp, err := http.Get("https://" + hostPort)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.HTTPStatus = 0
|
result.HTTPStatus = 0
|
||||||
result.HTTPStatusText = "异常"
|
result.HTTPStatusText = "异常"
|
||||||
|
|
|
@ -6,7 +6,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func Test(t *testing.T) {
|
func Test(t *testing.T) {
|
||||||
site := "bt.cn" // 只传域名或 IP,不要 http://
|
site := "bt.cn:443" // 只传域名或 IP,不要 http://
|
||||||
result, err := CheckWebsite(site)
|
result, err := CheckWebsite(site)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("❌ 检测失败: %v\n", err)
|
fmt.Printf("❌ 检测失败: %v\n", err)
|
||||||
|
|
|
@ -14,7 +14,7 @@ import {
|
||||||
useLoadingMask,
|
useLoadingMask,
|
||||||
} from '@baota/naive-ui/hooks'
|
} from '@baota/naive-ui/hooks'
|
||||||
import { useError } from '@baota/hooks/error'
|
import { useError } from '@baota/hooks/error'
|
||||||
import { isDomain } from '@baota/utils/business'
|
import { isDomain, isIp, isPort } from '@baota/utils/business'
|
||||||
import { $t } from '@locales/index'
|
import { $t } from '@locales/index'
|
||||||
|
|
||||||
// Store和组件
|
// Store和组件
|
||||||
|
@ -335,6 +335,61 @@ export const useMonitorFormController = (data: UpdateSiteMonitorParams | null =
|
||||||
}),
|
}),
|
||||||
])
|
])
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证输入是否合法域名或 IP 地址
|
||||||
|
*/
|
||||||
|
function isValidHost(host: string): boolean {
|
||||||
|
if (!host?.trim()) return false;
|
||||||
|
|
||||||
|
const trimmedHost = host.trim();
|
||||||
|
let hostPart: string;
|
||||||
|
let portPart: string | undefined;
|
||||||
|
|
||||||
|
// 分离主机和端口部分
|
||||||
|
if (trimmedHost.startsWith('[')) {
|
||||||
|
// IPv6 地址(可能带端口)
|
||||||
|
const closingBracketIndex = trimmedHost.indexOf(']');
|
||||||
|
// 缺少闭合括号
|
||||||
|
if (closingBracketIndex === -1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// 去掉 []
|
||||||
|
hostPart = trimmedHost.slice(1, closingBracketIndex);
|
||||||
|
const rest = trimmedHost.slice(closingBracketIndex + 1);
|
||||||
|
|
||||||
|
// 检查剩余部分(只能是 :端口 或空)
|
||||||
|
if (rest) {
|
||||||
|
// 非端口部分
|
||||||
|
if (!rest.startsWith(':')) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
portPart = rest.slice(1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// IPv4 或域名(可能带端口)
|
||||||
|
const lastColonIndex = trimmedHost.lastIndexOf(':');
|
||||||
|
if (lastColonIndex !== -1) {
|
||||||
|
hostPart = trimmedHost.slice(0, lastColonIndex);
|
||||||
|
portPart = trimmedHost.slice(lastColonIndex + 1);
|
||||||
|
} else {
|
||||||
|
hostPart = trimmedHost;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查主机部分(IPv4/IPv6/域名)
|
||||||
|
const isHostValid = isIp(hostPart) || isDomain(hostPart);
|
||||||
|
if (!isHostValid) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查端口部分
|
||||||
|
if (portPart !== undefined) {
|
||||||
|
return isPort(portPart);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 表单验证规则
|
* 表单验证规则
|
||||||
*/
|
*/
|
||||||
|
@ -345,7 +400,7 @@ export const useMonitorFormController = (data: UpdateSiteMonitorParams | null =
|
||||||
message: '请输入正确的域名',
|
message: '请输入正确的域名',
|
||||||
trigger: 'input',
|
trigger: 'input',
|
||||||
validator: (rule: any, value: any, callback: any) => {
|
validator: (rule: any, value: any, callback: any) => {
|
||||||
if (!isDomain(value)) {
|
if (!isValidHost(value)) {
|
||||||
callback(new Error('请输入正确的域名'))
|
callback(new Error('请输入正确的域名'))
|
||||||
} else {
|
} else {
|
||||||
callback()
|
callback()
|
||||||
|
|
Loading…
Reference in New Issue