Spaces:
Sleeping
Sleeping
| package node | |
| import ( | |
| "fmt" | |
| "net/url" | |
| "strconv" | |
| "strings" | |
| ) | |
| type Trojan struct { | |
| Password string `json:"password"` | |
| Hostname string `json:"hostname"` | |
| Port int `json:"port"` | |
| Query TrojanQuery `json:"query,omitempty"` | |
| Name string `json:"name"` | |
| Type string `json:"type"` | |
| } | |
| type TrojanQuery struct { | |
| Peer string `json:"peer,omitempty"` | |
| Type string `json:"type,omitempty"` | |
| Path string `json:"path,omitempty"` | |
| Security string `json:"security,omitempty"` | |
| Fp string `json:"fp,omitempty"` | |
| AllowInsecure int `json:"allowInsecure,omitempty"` | |
| Alpn []string `json:"alpn,omitempty"` | |
| Sni string `json:"sni,omitempty"` | |
| Host string `json:"host,omitempty"` | |
| Flow string `json:"flow,omitempty"` | |
| } | |
| // 开发者测试 | |
| func CallTrojan() { | |
| trojan := Trojan{ | |
| Password: "4cf3ca26cf114871b3d186a361a3de3", | |
| Hostname: "baidu.com", | |
| Port: 443, | |
| Query: TrojanQuery{ | |
| Peer: "", | |
| Type: "tcp", | |
| Path: "", | |
| Security: "tls", | |
| Fp: "", | |
| AllowInsecure: 0, | |
| Alpn: []string{"h2", "http/1.1"}, | |
| Sni: "baidu.com", | |
| Host: "", | |
| Flow: "", | |
| }, | |
| } | |
| fmt.Println(EncodeTrojanURL(trojan)) | |
| } | |
| // trojan 编码 | |
| func EncodeTrojanURL(t Trojan) string { | |
| /* | |
| trojan://password@hostname:port?peer=example.com&allowInsecure=0&sni=example.com | |
| */ | |
| u := url.URL{ | |
| Scheme: "trojan", | |
| User: url.User(t.Password), | |
| Host: fmt.Sprintf("%s:%d", t.Hostname, t.Port), | |
| } | |
| q := u.Query() | |
| q.Set("peer", t.Query.Peer) | |
| q.Set("allowInsecure", fmt.Sprintf("%d", t.Query.AllowInsecure)) | |
| q.Set("sni", t.Query.Sni) | |
| q.Set("type", t.Query.Type) | |
| q.Set("path", t.Query.Path) | |
| q.Set("security", t.Query.Security) | |
| q.Set("fp", t.Query.Fp) | |
| // q.Set("alpn", t.Query.Alpn) | |
| q.Set("host", t.Query.Host) | |
| q.Set("flow", t.Query.Flow) | |
| // 检查query是否有空值,有的话删除 | |
| for k, v := range q { | |
| if v[0] == "" { | |
| delete(q, k) | |
| // fmt.Printf("k: %v, v: %v\n", k, v) | |
| } | |
| } | |
| // 如果没有设置name,则使用hostname:port | |
| if t.Name == "" { | |
| t.Name = t.Hostname + ":" + strconv.Itoa(t.Port) | |
| } | |
| u.Fragment = t.Name | |
| u.RawQuery = q.Encode() | |
| return u.String() | |
| } | |
| // trojan 解码 | |
| func DecodeTrojanURL(s string) (Trojan, error) { | |
| /* | |
| trojan://password@hostname:port?peer=example.com&allowInsecure=0&sni=example.com | |
| */ | |
| u, err := url.Parse(s) | |
| if err != nil { | |
| return Trojan{}, fmt.Errorf("url格式化失败:%s", s) | |
| } | |
| if u.Scheme != "trojan" { | |
| return Trojan{}, fmt.Errorf("非trojan协议: %s", s) | |
| } | |
| password := u.User.Username() | |
| hostname := u.Hostname() | |
| port, _ := strconv.Atoi(u.Port()) | |
| peer := u.Query().Get("peer") | |
| allowInsecure := u.Query().Get("allowInsecure") | |
| sni := u.Query().Get("sni") | |
| types := u.Query().Get("type") | |
| path := u.Query().Get("path") | |
| security := u.Query().Get("security") | |
| fp := u.Query().Get("fp") | |
| alpns := u.Query().Get("alpn") | |
| alpn := strings.Split(alpns, ",") | |
| if alpns == "" { | |
| alpn = nil | |
| } | |
| host := u.Query().Get("host") | |
| flow := u.Query().Get("flow") | |
| name := u.Fragment | |
| // 如果没有设置name,则使用hostname:port | |
| if name == "" { | |
| name = hostname + ":" + u.Port() | |
| } | |
| if CheckEnvironment() { | |
| fmt.Println("password:", password) | |
| fmt.Println("password:", u.User.Username()) | |
| fmt.Println("hostname:", hostname) | |
| fmt.Println("port:", port) | |
| fmt.Println("peer:", peer) | |
| fmt.Println("allowInsecure:", allowInsecure) | |
| fmt.Println("sni:", sni) | |
| fmt.Println("type:", types) | |
| fmt.Println("path:", path) | |
| fmt.Println("security:", security) | |
| fmt.Println("fp:", fp) | |
| fmt.Println("alpn:", alpn) | |
| fmt.Println("host:", host) | |
| fmt.Println("flow:", flow) | |
| fmt.Println("name:", name) | |
| } | |
| return Trojan{ | |
| Password: password, | |
| Hostname: hostname, | |
| Port: port, | |
| Query: TrojanQuery{ | |
| Peer: peer, | |
| Type: types, | |
| Path: path, | |
| Security: security, | |
| Fp: fp, | |
| AllowInsecure: 0, | |
| Alpn: alpn, | |
| Sni: sni, | |
| Host: host, | |
| Flow: flow, | |
| }, | |
| Name: name, | |
| Type: "trojan", | |
| }, nil | |
| } | |