mirror of
https://github.com/fankes/komari-agent.git
synced 2025-12-10 15:23:35 +08:00
fix: https://github.com/komari-monitor/komari/issues/248 使用中文域名进行自动发现无法链接面板
This commit is contained in:
@@ -12,6 +12,7 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/komari-monitor/komari-agent/cmd/flags"
|
"github.com/komari-monitor/komari-agent/cmd/flags"
|
||||||
|
"github.com/komari-monitor/komari-agent/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
// AutoDiscoveryConfig 自动发现配置结构体
|
// AutoDiscoveryConfig 自动发现配置结构体
|
||||||
@@ -109,6 +110,14 @@ func registerWithAutoDiscovery() error {
|
|||||||
if len(endpoint) > 0 && endpoint[len(endpoint)-1] == '/' {
|
if len(endpoint) > 0 && endpoint[len(endpoint)-1] == '/' {
|
||||||
endpoint = endpoint[:len(endpoint)-1]
|
endpoint = endpoint[:len(endpoint)-1]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 转换中文域名为 ASCII 兼容编码
|
||||||
|
endpoint, err = utils.ConvertIDNToASCII(endpoint)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Warning: Failed to convert IDN to ASCII: %v", err)
|
||||||
|
// 继续使用原始 endpoint,可能在某些情况下仍能工作
|
||||||
|
}
|
||||||
|
|
||||||
registerURL := fmt.Sprintf("%s/api/clients/register?name=%s", endpoint, url.QueryEscape(hostname))
|
registerURL := fmt.Sprintf("%s/api/clients/register?name=%s", endpoint, url.QueryEscape(hostname))
|
||||||
|
|
||||||
// 创建HTTP请求
|
// 创建HTTP请求
|
||||||
@@ -120,7 +129,7 @@ func registerWithAutoDiscovery() error {
|
|||||||
// 设置请求头
|
// 设置请求头
|
||||||
req.Header.Set("Content-Type", "application/json")
|
req.Header.Set("Content-Type", "application/json")
|
||||||
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", flags.AutoDiscoveryKey))
|
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", flags.AutoDiscoveryKey))
|
||||||
|
|
||||||
// 添加Cloudflare Access头部
|
// 添加Cloudflare Access头部
|
||||||
if flags.CFAccessClientID != "" && flags.CFAccessClientSecret != "" {
|
if flags.CFAccessClientID != "" && flags.CFAccessClientSecret != "" {
|
||||||
req.Header.Set("CF-Access-Client-Id", flags.CFAccessClientID)
|
req.Header.Set("CF-Access-Client-Id", flags.CFAccessClientID)
|
||||||
|
|||||||
5
go.mod
5
go.mod
@@ -13,6 +13,7 @@ require (
|
|||||||
github.com/rhysd/go-github-selfupdate v1.2.3
|
github.com/rhysd/go-github-selfupdate v1.2.3
|
||||||
github.com/shirou/gopsutil/v4 v4.25.6
|
github.com/shirou/gopsutil/v4 v4.25.6
|
||||||
github.com/spf13/cobra v1.9.1
|
github.com/spf13/cobra v1.9.1
|
||||||
|
golang.org/x/net v0.38.0
|
||||||
golang.org/x/sys v0.33.0
|
golang.org/x/sys v0.33.0
|
||||||
gopkg.in/toast.v1 v1.0.0-20180812000517-0a84660828b2
|
gopkg.in/toast.v1 v1.0.0-20180812000517-0a84660828b2
|
||||||
)
|
)
|
||||||
@@ -34,7 +35,7 @@ require (
|
|||||||
github.com/ulikunitz/xz v0.5.9 // indirect
|
github.com/ulikunitz/xz v0.5.9 // indirect
|
||||||
github.com/yusufpapurcu/wmi v1.2.4 // indirect
|
github.com/yusufpapurcu/wmi v1.2.4 // indirect
|
||||||
golang.org/x/crypto v0.39.0 // indirect
|
golang.org/x/crypto v0.39.0 // indirect
|
||||||
golang.org/x/net v0.38.0 // indirect
|
|
||||||
golang.org/x/oauth2 v0.30.0 // indirect
|
golang.org/x/oauth2 v0.30.0 // indirect
|
||||||
golang.org/x/sync v0.13.0 // indirect
|
golang.org/x/sync v0.15.0 // indirect
|
||||||
|
golang.org/x/text v0.26.0 // indirect
|
||||||
)
|
)
|
||||||
|
|||||||
4
go.sum
4
go.sum
@@ -84,8 +84,8 @@ golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAG
|
|||||||
golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI=
|
golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI=
|
||||||
golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU=
|
golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU=
|
||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610=
|
golang.org/x/sync v0.15.0 h1:KWH3jNZsfyT6xfAfKiz6MRNmd46ByHDYaZ7KSkCtdW8=
|
||||||
golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
golang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import (
|
|||||||
"github.com/komari-monitor/komari-agent/dnsresolver"
|
"github.com/komari-monitor/komari-agent/dnsresolver"
|
||||||
"github.com/komari-monitor/komari-agent/monitoring"
|
"github.com/komari-monitor/komari-agent/monitoring"
|
||||||
"github.com/komari-monitor/komari-agent/terminal"
|
"github.com/komari-monitor/komari-agent/terminal"
|
||||||
|
"github.com/komari-monitor/komari-agent/utils"
|
||||||
"github.com/komari-monitor/komari-agent/ws"
|
"github.com/komari-monitor/komari-agent/ws"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -22,6 +23,13 @@ func EstablishWebSocketConnection() {
|
|||||||
websocketEndpoint := strings.TrimSuffix(flags.Endpoint, "/") + "/api/clients/report?token=" + flags.Token
|
websocketEndpoint := strings.TrimSuffix(flags.Endpoint, "/") + "/api/clients/report?token=" + flags.Token
|
||||||
websocketEndpoint = "ws" + strings.TrimPrefix(websocketEndpoint, "http")
|
websocketEndpoint = "ws" + strings.TrimPrefix(websocketEndpoint, "http")
|
||||||
|
|
||||||
|
// 转换中文域名为 ASCII 兼容编码
|
||||||
|
if convertedEndpoint, err := utils.ConvertIDNToASCII(websocketEndpoint); err == nil {
|
||||||
|
websocketEndpoint = convertedEndpoint
|
||||||
|
} else {
|
||||||
|
log.Printf("Warning: Failed to convert WebSocket IDN to ASCII: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
var conn *ws.SafeConn
|
var conn *ws.SafeConn
|
||||||
defer func() {
|
defer func() {
|
||||||
if conn != nil {
|
if conn != nil {
|
||||||
@@ -155,6 +163,13 @@ func establishTerminalConnection(token, id, endpoint string) {
|
|||||||
endpoint = strings.TrimSuffix(endpoint, "/") + "/api/clients/terminal?token=" + token + "&id=" + id
|
endpoint = strings.TrimSuffix(endpoint, "/") + "/api/clients/terminal?token=" + token + "&id=" + id
|
||||||
endpoint = "ws" + strings.TrimPrefix(endpoint, "http")
|
endpoint = "ws" + strings.TrimPrefix(endpoint, "http")
|
||||||
|
|
||||||
|
// 转换中文域名为 ASCII 兼容编码
|
||||||
|
if convertedEndpoint, err := utils.ConvertIDNToASCII(endpoint); err == nil {
|
||||||
|
endpoint = convertedEndpoint
|
||||||
|
} else {
|
||||||
|
log.Printf("Warning: Failed to convert Terminal WebSocket IDN to ASCII: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
// 使用与主 WS 相同的拨号策略
|
// 使用与主 WS 相同的拨号策略
|
||||||
dialer := newWSDialer()
|
dialer := newWSDialer()
|
||||||
|
|
||||||
|
|||||||
54
utils/idna.go
Normal file
54
utils/idna.go
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/url"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"golang.org/x/net/idna"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ConvertIDNToASCII 将包含国际化域名(IDN)的 URL 转换为 ASCII 兼容编码(ACE)格式
|
||||||
|
// 例如: "https://中文域名.com" -> "https://xn--fiq228c.com"
|
||||||
|
func ConvertIDNToASCII(urlStr string) (string, error) {
|
||||||
|
// 解析 URL
|
||||||
|
parsedURL, err := url.Parse(urlStr)
|
||||||
|
if err != nil {
|
||||||
|
return urlStr, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 转换主机名为 Punycode
|
||||||
|
asciiHost, err := idna.ToASCII(parsedURL.Hostname())
|
||||||
|
if err != nil {
|
||||||
|
return urlStr, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果有端口,需要保留
|
||||||
|
if parsedURL.Port() != "" {
|
||||||
|
parsedURL.Host = asciiHost + ":" + parsedURL.Port()
|
||||||
|
} else {
|
||||||
|
parsedURL.Host = asciiHost
|
||||||
|
}
|
||||||
|
|
||||||
|
return parsedURL.String(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ConvertHostToASCII 将主机名(可能包含端口)转换为 ASCII 兼容编码格式
|
||||||
|
// 例如: "中文域名.com:8080" -> "xn--fiq228c.com:8080"
|
||||||
|
func ConvertHostToASCII(host string) (string, error) {
|
||||||
|
// 分离主机名和端口
|
||||||
|
var hostname, port string
|
||||||
|
if idx := strings.LastIndex(host, ":"); idx != -1 {
|
||||||
|
hostname = host[:idx]
|
||||||
|
port = host[idx:]
|
||||||
|
} else {
|
||||||
|
hostname = host
|
||||||
|
}
|
||||||
|
|
||||||
|
// 转换为 ASCII
|
||||||
|
asciiHost, err := idna.ToASCII(hostname)
|
||||||
|
if err != nil {
|
||||||
|
return host, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return asciiHost + port, nil
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user