3 Commits

5 changed files with 76 additions and 38 deletions

View File

@ -5,6 +5,7 @@ import (
"errors" "errors"
"strconv" "strconv"
"strings" "strings"
"unicode/utf8"
P "github.com/bestnite/sub2clash/model/proxy" P "github.com/bestnite/sub2clash/model/proxy"
) )
@ -32,8 +33,13 @@ func ParsePort(portStr string) (int, error) {
return port, nil return port, nil
} }
// isLikelyBase64 不严格判断是否是合法的 Base64, 很多分享链接不符合 Base64 规范
func isLikelyBase64(s string) bool { func isLikelyBase64(s string) bool {
if len(s)%4 == 0 && !strings.Contains(strings.TrimSuffix(s, "="), "=") { if strings.TrimSpace(s) == "" {
return false
}
if !strings.Contains(strings.TrimSuffix(s, "="), "=") {
s = strings.TrimSuffix(s, "=") s = strings.TrimSuffix(s, "=")
chars := "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" chars := "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
for _, c := range s { for _, c := range s {
@ -41,17 +47,25 @@ func isLikelyBase64(s string) bool {
return false return false
} }
} }
return true
} }
decoded, err := DecodeBase64(s)
if err != nil {
return false return false
}
if !utf8.ValidString(decoded) {
return false
}
return true
} }
func DecodeBase64(s string) (string, error) { func DecodeBase64(s string) (string, error) {
s = strings.TrimSpace(s) s = strings.TrimSpace(s)
if strings.Contains(s, "-") || strings.Contains(s, "_") { if strings.Contains(s, "-") || strings.Contains(s, "_") {
s = strings.Replace(s, "-", "+", -1) s = strings.ReplaceAll(s, "-", "+")
s = strings.Replace(s, "_", "/", -1) s = strings.ReplaceAll(s, "_", "/")
} }
if len(s)%4 != 0 { if len(s)%4 != 0 {
s += strings.Repeat("=", 4-len(s)%4) s += strings.Repeat("=", 4-len(s)%4)

View File

@ -58,7 +58,17 @@ func (p *TrojanParser) Parse(proxy string) (P.Proxy, error) {
remarks = strings.TrimSpace(remarks) remarks = strings.TrimSpace(remarks)
query := link.Query() query := link.Query()
network, security, alpnStr, sni, pbk, sid, fp, path, host, serviceName, udp := query.Get("type"), query.Get("security"), query.Get("alpn"), query.Get("sni"), query.Get("pbk"), query.Get("sid"), query.Get("fp"), query.Get("path"), query.Get("host"), query.Get("serviceName"), query.Get("udp") network, security, alpnStr, sni, pbk, sid, fp, path, host, serviceName, udp, insecure := query.Get("type"), query.Get("security"), query.Get("alpn"), query.Get("sni"), query.Get("pbk"), query.Get("sid"), query.Get("fp"), query.Get("path"), query.Get("host"), query.Get("serviceName"), query.Get("udp"), query.Get("allowInsecure")
insecureBool := insecure == "1"
result := P.Trojan{
Server: server,
Port: port,
Password: password,
Network: network,
UDP: udp == "true",
SkipCertVerify: insecureBool,
}
var alpn []string var alpn []string
if strings.Contains(alpnStr, ",") { if strings.Contains(alpnStr, ",") {
@ -66,27 +76,23 @@ func (p *TrojanParser) Parse(proxy string) (P.Proxy, error) {
} else { } else {
alpn = nil alpn = nil
} }
if len(alpn) > 0 {
result := P.Trojan{ result.ALPN = alpn
Server: server,
Port: port,
Password: password,
Network: network,
UDP: udp == "true",
} }
if security == "xtls" || security == "tls" { if fp != "" {
result.ALPN = alpn result.ClientFingerprint = fp
}
if sni != "" {
result.SNI = sni result.SNI = sni
} }
if security == "reality" { if security == "reality" {
result.SNI = sni
result.RealityOpts = P.RealityOptions{ result.RealityOpts = P.RealityOptions{
PublicKey: pbk, PublicKey: pbk,
ShortID: sid, ShortID: sid,
} }
result.Fingerprint = fp
} }
if network == "ws" { if network == "ws" {

View File

@ -57,6 +57,7 @@ func (p *VlessParser) Parse(proxy string) (P.Proxy, error) {
} else { } else {
alpn = nil alpn = nil
} }
remarks := link.Fragment remarks := link.Fragment
if remarks == "" { if remarks == "" {
remarks = fmt.Sprintf("%s:%s", server, portStr) remarks = fmt.Sprintf("%s:%s", server, portStr)
@ -69,24 +70,31 @@ func (p *VlessParser) Parse(proxy string) (P.Proxy, error) {
UUID: uuid, UUID: uuid,
Flow: flow, Flow: flow,
UDP: udp == "true", UDP: udp == "true",
SkipCertVerify: insecureBool,
}
if len(alpn) > 0 {
result.ALPN = alpn
}
if fp != "" {
result.ClientFingerprint = fp
}
if sni != "" {
result.ServerName = sni
} }
if security == "tls" { if security == "tls" {
result.TLS = true result.TLS = true
result.ALPN = alpn
result.SkipCertVerify = insecureBool
result.Fingerprint = fp
result.ServerName = sni
} }
if security == "reality" { if security == "reality" {
result.TLS = true result.TLS = true
result.ServerName = sni
result.RealityOpts = P.RealityOptions{ result.RealityOpts = P.RealityOptions{
PublicKey: pbk, PublicKey: pbk,
ShortID: sid, ShortID: sid,
} }
result.Fingerprint = fp
} }
if _type == "ws" { if _type == "ws" {

View File

@ -99,6 +99,13 @@ func (p *VmessParser) Parse(proxy string) (P.Proxy, error) {
name = vmess.Ps name = vmess.Ps
} }
var alpn []string
if strings.Contains(vmess.Alpn, ",") {
alpn = strings.Split(vmess.Alpn, ",")
} else {
alpn = nil
}
result := P.Vmess{ result := P.Vmess{
Server: vmess.Add, Server: vmess.Add,
Port: port, Port: port,
@ -107,19 +114,22 @@ func (p *VmessParser) Parse(proxy string) (P.Proxy, error) {
Cipher: vmess.Scy, Cipher: vmess.Scy,
} }
if vmess.Tls == "tls" { if len(alpn) > 0 {
var alpn []string
if strings.Contains(vmess.Alpn, ",") {
alpn = strings.Split(vmess.Alpn, ",")
} else {
alpn = nil
}
result.TLS = true
result.Fingerprint = vmess.Fp
result.ALPN = alpn result.ALPN = alpn
}
if vmess.Fp != "" {
result.ClientFingerprint = vmess.Fp
}
if vmess.Sni != "" {
result.ServerName = vmess.Sni result.ServerName = vmess.Sni
} }
if vmess.Tls == "tls" {
result.TLS = true
}
if vmess.Net == "ws" { if vmess.Net == "ws" {
if vmess.Path == "" { if vmess.Path == "" {
vmess.Path = "/" vmess.Path = "/"

View File

@ -168,7 +168,7 @@ func GetRawConfHandler(c *gin.Context) {
return return
} }
response, err := http.Get(strings.TrimSuffix(config.GlobalConfig.Address, "/") + "/" + shortLink.Url) response, err := http.Get("http://" + strings.TrimSuffix(config.GlobalConfig.Address, "/") + "/" + shortLink.Url)
if err != nil { if err != nil {
respondWithError(c, http.StatusInternalServerError, "请求错误: "+err.Error()) respondWithError(c, http.StatusInternalServerError, "请求错误: "+err.Error())
return return