|
@@ -2,7 +2,11 @@ package tinymq
|
|
|
|
|
|
|
|
import (
|
|
import (
|
|
|
"bytes"
|
|
"bytes"
|
|
|
|
|
+ "errors"
|
|
|
"fmt"
|
|
"fmt"
|
|
|
|
|
+ "regexp"
|
|
|
|
|
+ "strconv"
|
|
|
|
|
+
|
|
|
// "regexp"
|
|
// "regexp"
|
|
|
"strings"
|
|
"strings"
|
|
|
"time"
|
|
"time"
|
|
@@ -126,6 +130,74 @@ type HostInfo struct {
|
|
|
Updated time.Time `json:"updated" yaml:"updated"` // 节点信息刷新时间
|
|
Updated time.Time `json:"updated" yaml:"updated"` // 节点信息刷新时间
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+// 从 url 中解析信息
|
|
|
|
|
+// url 格式:ws2://xor:s^7mv7L!Mrn8Y!vn@127.0.0.1:14541/wsv2?proxy=1
|
|
|
|
|
+// 仅支持客户端连接使用
|
|
|
|
|
+func ParseUrl(url string) (hostInfo *HostInfo, err error) {
|
|
|
|
|
+ mx := regexp.MustCompile(`^([a-z]+)([0-9]+)://([^/#\?]+)(/[\w\-/]+)?`).FindStringSubmatch(url)
|
|
|
|
|
+ if mx == nil {
|
|
|
|
|
+ return nil, errors.New("invalid url")
|
|
|
|
|
+ }
|
|
|
|
|
+ protocol := mx[1]
|
|
|
|
|
+ version, err := strconv.Atoi(mx[2])
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return nil, err
|
|
|
|
|
+ }
|
|
|
|
|
+ host := mx[3]
|
|
|
|
|
+ index := strings.Index(host, "@")
|
|
|
|
|
+ hash := ""
|
|
|
|
|
+ if index >= 0 {
|
|
|
|
|
+ hash = host[0:index]
|
|
|
|
|
+ host = host[index+1:]
|
|
|
|
|
+ }
|
|
|
|
|
+ // 检查是否ipv6,解析出ip和端口
|
|
|
|
|
+ index = strings.Index(host, "]:")
|
|
|
|
|
+ port := 0
|
|
|
|
|
+ if index > 0 {
|
|
|
|
|
+ // ipv6 地址和端口
|
|
|
|
|
+ port, err = strconv.Atoi(host[index+2:])
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return nil, err
|
|
|
|
|
+ }
|
|
|
|
|
+ host = host[1:index]
|
|
|
|
|
+ } else {
|
|
|
|
|
+ hs := strings.Split(host, ":")
|
|
|
|
|
+ if len(hs) == 2 {
|
|
|
|
|
+ host = hs[0]
|
|
|
|
|
+ port, err = strconv.Atoi(hs[1])
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return nil, err
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ path := ""
|
|
|
|
|
+ if len(mx) > 4 {
|
|
|
|
|
+ path = mx[4]
|
|
|
|
|
+ }
|
|
|
|
|
+ hostInfo = &HostInfo{
|
|
|
|
|
+ Proto: protocol,
|
|
|
|
|
+ Version: uint8(version),
|
|
|
|
|
+ Host: host,
|
|
|
|
|
+ Port: uint16(port),
|
|
|
|
|
+ Hash: hash,
|
|
|
|
|
+ Path: path,
|
|
|
|
|
+ }
|
|
|
|
|
+ // 查找是否代理
|
|
|
|
|
+ url = url[len(mx[0]):]
|
|
|
|
|
+ if regexp.MustCompile(`[\?&]proxy=1`).MatchString(url) {
|
|
|
|
|
+ hostInfo.Proxy = true
|
|
|
|
|
+ }
|
|
|
|
|
+ priorityM := regexp.MustCompile(`[\?&]priority=(-?\d+)`).FindStringSubmatch(url)
|
|
|
|
|
+ if priorityM != nil {
|
|
|
|
|
+ priority, err := strconv.Atoi(priorityM[1])
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return nil, err
|
|
|
|
|
+ }
|
|
|
|
|
+ hostInfo.Priority = int16(priority)
|
|
|
|
|
+ }
|
|
|
|
|
+ return hostInfo, nil
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
// 只输出客户端要连接的信息
|
|
// 只输出客户端要连接的信息
|
|
|
func (h *HostInfo) Url() string {
|
|
func (h *HostInfo) Url() string {
|
|
|
var b bytes.Buffer
|
|
var b bytes.Buffer
|