Prechádzať zdrojové kódy

add parse url function

Joyit 1 mesiac pred
rodič
commit
4592673f15
2 zmenil súbory, kde vykonal 88 pridanie a 0 odobranie
  1. 72 0
      type.go
  2. 16 0
      type_test.go

+ 72 - 0
type.go

@@ -2,7 +2,11 @@ package tinymq
 
 import (
 	"bytes"
+	"errors"
 	"fmt"
+	"regexp"
+	"strconv"
+
 	// "regexp"
 	"strings"
 	"time"
@@ -126,6 +130,74 @@ type HostInfo struct {
 	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 {
 	var b bytes.Buffer

+ 16 - 0
type_test.go

@@ -0,0 +1,16 @@
+package tinymq
+
+import "testing"
+
+func TestParseUrl(t *testing.T) {
+	url := "ws2://xor:s^7mv7L!Mrn8Y!vn@127.0.0.1:141/wsv2?proxy=1"
+	hostInfo, err := ParseUrl(url)
+	if err != nil {
+		t.Error(err)
+		return
+	}
+	result := hostInfo.Url()
+	if result != url {
+		t.Errorf("want: %s, get: %s", url, result)
+	}
+}