package proxy import ( "context" "fmt" "github.com/bytedance/sonic" "github.com/metacubex/mihomo/adapter" "github.com/metacubex/mihomo/constant" "github.com/timerzz/proxypool/pkg/proxy" "net" "net/url" "strconv" ) func ConnFromProxy(ctx context.Context, p proxy.Proxy, addr constant.Metadata) (conn net.Conn, err error) { pmap := make(map[string]interface{}) err = sonic.UnmarshalString(p.String(), &pmap) if err != nil { return } pmap["port"] = int(pmap["port"].(float64)) if p.TypeName() == "vmess" { pmap["alterId"] = int(pmap["alterId"].(float64)) } clashProxy, err := adapter.ParseProxy(pmap) if err != nil { return nil, err } return clashProxy.DialContext(ctx, &addr) // 建立到proxy server的connection,对Proxy的类别做了自适应相当于泛型 } // UrlToMetadata DO NOT EDIT. Copied from clash because it's an unexported function func UrlToMetadata(rawURL string) (addr constant.Metadata, err error) { u, err := url.Parse(rawURL) if err != nil { return } port := u.Port() if port == "" { switch u.Scheme { case "https": port = "443" case "http": port = "80" default: err = fmt.Errorf("%s scheme not Support", rawURL) return } } pi, _ := strconv.Atoi(port) addr = constant.Metadata{ Host: u.Hostname(), DstPort: uint16(pi), } return }