watcher/pkg/utils/proxy.go

58 lines
1.3 KiB
Go
Raw Normal View History

2024-04-10 17:36:56 +08:00
package utils
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
}