From 1bd693a21825e17a5268960219c69dd370366019 Mon Sep 17 00:00:00 2001 From: xxf098 Date: Mon, 9 Jan 2023 20:51:31 -0500 Subject: [PATCH 01/43] set default remarks --- config/trojan.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/config/trojan.go b/config/trojan.go index ca77fa9..0f623a7 100644 --- a/config/trojan.go +++ b/config/trojan.go @@ -71,6 +71,9 @@ func TrojanLinkToTrojanOption(link string) (*outbound.TrojanOption, error) { } } + if len(trojanOption.Remarks) < 1 { + trojanOption.Remarks = trojanOption.Server + } return &trojanOption, nil } From 89aec788f9e48bb9e9750de9b1ba22e7140f4913 Mon Sep 17 00:00:00 2001 From: xxf098 Date: Mon, 9 Jan 2023 21:23:35 -0500 Subject: [PATCH 02/43] refactor --- web/profile.go | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/web/profile.go b/web/profile.go index 88607b4..3c42407 100644 --- a/web/profile.go +++ b/web/profile.go @@ -192,19 +192,17 @@ func scanClashProxies(scanner *bufio.Scanner, greedy bool) ([]string, error) { for scanner.Scan() { b := scanner.Bytes() trimLine := strings.TrimSpace(string(b)) - if trimLine == "proxy-groups:" || trimLine == "rules:" || trimLine == "Proxy Group:" { - break - } - if proxiesStart { - if _, err := config.ParseBaseProxy(trimLine); err != nil { - continue - } - } if !proxiesStart && (trimLine == "proxies:" || trimLine == "Proxy:") { proxiesStart = true b = []byte("proxies:") } if proxiesStart { + if trimLine == "proxy-groups:" || trimLine == "rules:" || trimLine == "Proxy Group:" { + break + } + if _, err := config.ParseBaseProxy(trimLine); err != nil { + continue + } data = append(data, b...) data = append(data, byte('\n')) } From 6e241d2c0e00698124dca652074d0c4ad1549988 Mon Sep 17 00:00:00 2001 From: xxf098 Date: Mon, 9 Jan 2023 22:00:13 -0500 Subject: [PATCH 03/43] ignore proxiesStart --- web/profile.go | 51 +++----------------------------------------------- 1 file changed, 3 insertions(+), 48 deletions(-) diff --git a/web/profile.go b/web/profile.go index 3c42407..5294a9f 100644 --- a/web/profile.go +++ b/web/profile.go @@ -92,51 +92,6 @@ func ParseLinks(message string) ([]string, error) { return links, err } -// FIXME: return the top n links -func PeekClash(input string, n int) ([]string, error) { - scanner := bufio.NewScanner(strings.NewReader(input)) - proxiesStart := false - data := []byte{} - linkCount := 0 - for scanner.Scan() { - b := scanner.Bytes() - trimLine := strings.TrimSpace(string(b)) - if trimLine == "proxy-groups:" || trimLine == "rules:" || trimLine == "Proxy Group:" { - break - } - if proxiesStart { - if _, err := config.ParseBaseProxy(trimLine); err != nil { - continue - } - if strings.HasPrefix(trimLine, "-") { - if linkCount >= n { - break - } - linkCount += 1 - } - data = append(data, b...) - data = append(data, byte('\n')) - continue - } - if !proxiesStart && (trimLine == "proxies:" || trimLine == "Proxy:") { - proxiesStart = true - b = []byte("proxies:") - } - data = append(data, b...) - data = append(data, byte('\n')) - } - // fmt.Println(string(data)) - links, err := parseClashByte(data) - if err != nil || len(links) < 1 { - return []string{}, err - } - endIndex := n - if endIndex > len(links) { - endIndex = len(links) - } - return links[:endIndex], nil -} - func parseProfiles(data string) ([]string, error) { // encodeed url links := strings.Split(data, "\n") @@ -192,14 +147,14 @@ func scanClashProxies(scanner *bufio.Scanner, greedy bool) ([]string, error) { for scanner.Scan() { b := scanner.Bytes() trimLine := strings.TrimSpace(string(b)) + if trimLine == "proxy-groups:" || trimLine == "rules:" || trimLine == "Proxy Group:" { + break + } if !proxiesStart && (trimLine == "proxies:" || trimLine == "Proxy:") { proxiesStart = true b = []byte("proxies:") } if proxiesStart { - if trimLine == "proxy-groups:" || trimLine == "rules:" || trimLine == "Proxy Group:" { - break - } if _, err := config.ParseBaseProxy(trimLine); err != nil { continue } From 7c039ead3c63bc08c55a01dc4c138ef6954d1283 Mon Sep 17 00:00:00 2001 From: xxf098 Date: Mon, 9 Jan 2023 22:04:38 -0500 Subject: [PATCH 04/43] scan yaml file --- web/profile.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/web/profile.go b/web/profile.go index 5294a9f..4be3213 100644 --- a/web/profile.go +++ b/web/profile.go @@ -49,14 +49,15 @@ func getSubscriptionLinks(link string) ([]string, error) { return nil, err } defer resp.Body.Close() + if isYamlFile(link) { + scanner := bufio.NewScanner(resp.Body) + return scanClashProxies(scanner, true) + } data, err := io.ReadAll(resp.Body) if err != nil { return nil, err } dataStr := string(data) - if isYamlFile(link) { - return parseClash(dataStr) - } msg, err := utils.DecodeB64(dataStr) if err != nil { if strings.Contains(dataStr, "proxies:") { From 7ba608acebdd1db8ea040bce4a0af6f10e8b8636 Mon Sep 17 00:00:00 2001 From: xxf098 Date: Mon, 9 Jan 2023 22:38:36 -0500 Subject: [PATCH 05/43] rename --- web/profile.go | 6 +++--- web/server.go | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/web/profile.go b/web/profile.go index 4be3213..478826c 100644 --- a/web/profile.go +++ b/web/profile.go @@ -167,7 +167,7 @@ func scanClashProxies(scanner *bufio.Scanner, greedy bool) ([]string, error) { return parseClashByte(data) } -func parseClashByLine(filepath string) ([]string, error) { +func parseClashFileByLine(filepath string) ([]string, error) { file, err := os.Open(filepath) if err != nil { return nil, err @@ -192,7 +192,7 @@ func parseFile(filepath string) ([]string, error) { } // clash if isYamlFile(filepath) { - return parseClashByLine(filepath) + return parseClashFileByLine(filepath) } data, err := ioutil.ReadFile(filepath) if err != nil { @@ -203,7 +203,7 @@ func parseFile(filepath string) ([]string, error) { if err != nil && len(data) > 2048 { preview := string(data[:2048]) if strings.Contains(preview, "proxies:") { - return parseClashByLine(filepath) + return parseClashFileByLine(filepath) } if strings.Contains(preview, "vmess://") || strings.Contains(preview, "trojan://") || diff --git a/web/server.go b/web/server.go index 3a2ab2d..d60d5b4 100644 --- a/web/server.go +++ b/web/server.go @@ -396,7 +396,7 @@ func getSubscription(w http.ResponseWriter, r *http.Request) { } func writeClash(filePath string) ([]byte, error) { - links, err := parseClashByLine(filePath) + links, err := parseClashFileByLine(filePath) if err != nil { // return nil, err From 5f9ab1245b4ff89680ace546f44375f9940fff52 Mon Sep 17 00:00:00 2001 From: xxf098 Date: Tue, 10 Jan 2023 01:20:00 -0500 Subject: [PATCH 06/43] check is file --- utils/utils.go | 13 +++++++++++++ web/profile.go | 4 ++++ 2 files changed, 17 insertions(+) diff --git a/utils/utils.go b/utils/utils.go index 978fca0..63f70d2 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -8,6 +8,7 @@ import ( "regexp" "runtime" "strconv" + "strings" "unsafe" "github.com/xxf098/lite-proxy/common" @@ -65,6 +66,18 @@ func IsUrl(message string) bool { return matched && err == nil } +func IsFilePath(message string) bool { + if len(message) < 1024 && + !strings.HasPrefix(message, "vmess://") && + !strings.HasPrefix(message, "trojan://") && + !strings.HasPrefix(message, "ssr://") && + !strings.HasPrefix(message, "ss://") { + _, err := os.Stat(message) + return err == nil + } + return false +} + func UnsafeGetBytes(s string) []byte { return unsafe.Slice((*byte)(unsafe.Pointer((*reflect.StringHeader)(unsafe.Pointer(&s)).Data)), len(s)) } diff --git a/web/profile.go b/web/profile.go index 478826c..2b624d3 100644 --- a/web/profile.go +++ b/web/profile.go @@ -82,6 +82,10 @@ func ParseLinks(message string) ([]string, error) { if utils.IsUrl(message) { return getSubscriptionLinks(message) } + // check is file path + if utils.IsFilePath(message) { + return parseFile(message) + } var links []string var err error for _, fn := range []parseFunc{parseProfiles, parseBase64, parseClash, parseFile} { From 97449df160a58757ff1f50827d12b6746eda4df1 Mon Sep 17 00:00:00 2001 From: xxf098 Date: Tue, 10 Jan 2023 01:40:21 -0500 Subject: [PATCH 07/43] scan from reader --- web/profile.go | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/web/profile.go b/web/profile.go index 2b624d3..60c72f2 100644 --- a/web/profile.go +++ b/web/profile.go @@ -50,8 +50,7 @@ func getSubscriptionLinks(link string) ([]string, error) { } defer resp.Body.Close() if isYamlFile(link) { - scanner := bufio.NewScanner(resp.Body) - return scanClashProxies(scanner, true) + return scanClashProxies(resp.Body, true) } data, err := io.ReadAll(resp.Body) if err != nil { @@ -141,14 +140,13 @@ func parseClashProxies(input string) ([]string, error) { if !strings.Contains(input, "{") { return []string{}, nil } - scanner := bufio.NewScanner(strings.NewReader(input)) - return scanClashProxies(scanner, true) + return scanClashProxies(strings.NewReader(input), true) } -// -func scanClashProxies(scanner *bufio.Scanner, greedy bool) ([]string, error) { +func scanClashProxies(r io.Reader, greedy bool) ([]string, error) { proxiesStart := false data := []byte{} + scanner := bufio.NewScanner(r) for scanner.Scan() { b := scanner.Bytes() trimLine := strings.TrimSpace(string(b)) @@ -177,8 +175,7 @@ func parseClashFileByLine(filepath string) ([]string, error) { return nil, err } defer file.Close() - scanner := bufio.NewScanner(file) - return scanClashProxies(scanner, false) + return scanClashProxies(file, false) } func parseClashByte(data []byte) ([]string, error) { From c46de1fe66dfff52c366b395e3852a551430b841 Mon Sep 17 00:00:00 2001 From: xxf098 Date: Tue, 10 Jan 2023 20:32:11 -0500 Subject: [PATCH 08/43] check } --- config/clash.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/config/clash.go b/config/clash.go index d59bf62..20b9adb 100644 --- a/config/clash.go +++ b/config/clash.go @@ -105,7 +105,8 @@ type BaseProxy struct { func ParseBaseProxy(profile string) (*BaseProxy, error) { idx := strings.IndexByte(profile, byte('{')) - if idx < 0 { + idxLast := strings.LastIndexByte(profile, byte('}')) + if idx < 0 || idxLast <= idx { // multiple lines form return nil, nil } From 01d651bc84349e9a85b237f70b97d154c27f2b88 Mon Sep 17 00:00:00 2001 From: xxf098 Date: Tue, 10 Jan 2023 20:49:52 -0500 Subject: [PATCH 09/43] parse with option --- web/profile.go | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/web/profile.go b/web/profile.go index 60c72f2..190dc91 100644 --- a/web/profile.go +++ b/web/profile.go @@ -35,6 +35,17 @@ const ( JSON_OUTPUT ) +type PAESE_TYPE int + +const ( + PARSE_ANY PAESE_TYPE = iota + PARSE_URL + PARSE_FILE + PARSE_BASE64 + PARSE_CLASH + PARSE_PROFILE +) + // support proxy // concurrency setting // as subscription server @@ -75,16 +86,35 @@ func getSubscriptionLinks(link string) ([]string, error) { type parseFunc func(string) ([]string, error) +type ParseOption struct { + Type PAESE_TYPE +} + // api func ParseLinks(message string) ([]string, error) { + opt := ParseOption{Type: PARSE_ANY} + return ParseLinksWithOption(message, opt) +} + +// api +func ParseLinksWithOption(message string, opt ParseOption) ([]string, error) { // matched, err := regexp.MatchString(`^(?:https?:\/\/)(?:[^@\/\n]+@)?(?:www\.)?([^:\/\n]+)`, message) - if utils.IsUrl(message) { + if opt.Type == PARSE_URL || utils.IsUrl(message) { return getSubscriptionLinks(message) } // check is file path - if utils.IsFilePath(message) { + if opt.Type == PARSE_FILE || utils.IsFilePath(message) { return parseFile(message) } + if opt.Type == PARSE_BASE64 { + return parseBase64(message) + } + if opt.Type == PARSE_CLASH { + return parseClash(message) + } + if opt.Type == PARSE_PROFILE { + return parseProfiles(message) + } var links []string var err error for _, fn := range []parseFunc{parseProfiles, parseBase64, parseClash, parseFile} { From 6008d85856b7ba2b34ab7990c8890afba7593506 Mon Sep 17 00:00:00 2001 From: xxf098 Date: Tue, 10 Jan 2023 21:33:29 -0500 Subject: [PATCH 10/43] scanClashProxies --- web/profile.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/web/profile.go b/web/profile.go index 190dc91..7ab2082 100644 --- a/web/profile.go +++ b/web/profile.go @@ -2,6 +2,7 @@ package web import ( "bufio" + "bytes" "context" "encoding/base64" "encoding/json" @@ -234,7 +235,7 @@ func parseFile(filepath string) ([]string, error) { if err != nil && len(data) > 2048 { preview := string(data[:2048]) if strings.Contains(preview, "proxies:") { - return parseClashFileByLine(filepath) + return scanClashProxies(bytes.NewReader(data), true) } if strings.Contains(preview, "vmess://") || strings.Contains(preview, "trojan://") || From e5f5bc63fdf421d3ae0f40cc5ac8031577e2bee4 Mon Sep 17 00:00:00 2001 From: xxf098 Date: Tue, 10 Jan 2023 22:07:21 -0500 Subject: [PATCH 11/43] set links --- web/profile.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/web/profile.go b/web/profile.go index 7ab2082..eba7bf3 100644 --- a/web/profile.go +++ b/web/profile.go @@ -142,7 +142,12 @@ func parseProfiles(data string) ([]string, error) { } reg := regexp.MustCompile(`((?i)vmess://[a-zA-Z0-9+_/=-]+([?#][^\s]+)?)|((?i)ssr://[a-zA-Z0-9+_/=-]+)|((?i)(vless|ss|trojan)://(\S+?)@(\S+?):([0-9]{2,5})([?#][^\s]+))|((?i)(ss)://[a-zA-Z0-9+_/=-]+([?#][^\s]+))`) matches := reg.FindAllStringSubmatch(data, -1) - links = make([]string, len(matches)) + linksLen, matchesLen := len(links), len(matches) + if linksLen < matchesLen { + links = make([]string, matchesLen) + } else if linksLen > matchesLen { + links = links[:len(matches)] + } for index, match := range matches { links[index] = match[0] } From ab3e625ce9b2537d9a91be75ba088ff6dd5ce0fd Mon Sep 17 00:00:00 2001 From: xxf098 Date: Sat, 14 Jan 2023 21:27:52 -0500 Subject: [PATCH 12/43] fix JoinHostPort --- config/parser.go | 10 ++++++---- config/shadowsocksr.go | 4 ++-- core/core.go | 4 +++- proxy/proxy.go | 3 ++- web/msg.go | 6 ++++-- web/server.go | 3 ++- 6 files changed, 19 insertions(+), 11 deletions(-) diff --git a/config/parser.go b/config/parser.go index e592ae1..2bb9c1d 100644 --- a/config/parser.go +++ b/config/parser.go @@ -4,7 +4,9 @@ import ( "encoding/base64" "encoding/json" "fmt" + "net" "net/url" + "strconv" "strings" "github.com/xxf098/lite-proxy/common/structure" @@ -31,7 +33,7 @@ func ParseProxy(mapping map[string]interface{}, namePrefix string) (string, erro break } auth := fmt.Sprintf("%s:%s", ssOption.Cipher, ssOption.Password) - link = fmt.Sprintf("ss://%s@%s:%d", base64.StdEncoding.EncodeToString([]byte(auth)), ssOption.Server, ssOption.Port) + link = fmt.Sprintf("ss://%s@%s", base64.StdEncoding.EncodeToString([]byte(auth)), net.JoinHostPort(ssOption.Server, strconv.Itoa(ssOption.Port))) if len(ssOption.Name) > 0 { link = fmt.Sprintf("%s#%s", link, url.QueryEscape(ssOption.Name)) } @@ -42,7 +44,7 @@ func ParseProxy(mapping map[string]interface{}, namePrefix string) (string, erro break } password := base64.StdEncoding.EncodeToString([]byte(ssrOption.Password)) - link = fmt.Sprintf("%s:%d:%s:%s:%s:%s", ssrOption.Server, ssrOption.Port, ssrOption.Protocol, ssrOption.Cipher, ssrOption.Obfs, password) + link = fmt.Sprintf("%s:%s:%s:%s:%s", net.JoinHostPort(ssrOption.Server, strconv.Itoa(ssrOption.Port)), ssrOption.Protocol, ssrOption.Cipher, ssrOption.Obfs, password) remarks := base64.StdEncoding.EncodeToString([]byte(ssrOption.Name)) obfsParam := base64.StdEncoding.EncodeToString([]byte(ssrOption.ObfsParam)) @@ -118,7 +120,7 @@ func ParseProxy(mapping map[string]interface{}, namePrefix string) (string, erro break } - link = fmt.Sprintf("trojan://%s@%s:%d", trojanOption.Password, trojanOption.Server, trojanOption.Port) + link = fmt.Sprintf("trojan://%s@%s", trojanOption.Password, net.JoinHostPort(trojanOption.Server, strconv.Itoa(trojanOption.Port))) query := []string{} // allowInsecure if trojanOption.SkipCertVerify { @@ -162,7 +164,7 @@ func ParseProxy(mapping map[string]interface{}, namePrefix string) (string, erro if err != nil { break } - link = fmt.Sprintf("http://%s@%s:%d", httpOption.Password, httpOption.Server, httpOption.Port) + link = fmt.Sprintf("http://%s@%s", httpOption.Password, net.JoinHostPort(httpOption.Server, strconv.Itoa(httpOption.Port))) query := []string{} query = append(query, fmt.Sprintf("tls=%t", httpOption.TLS)) if len(httpOption.UserName) > 0 { diff --git a/config/shadowsocksr.go b/config/shadowsocksr.go index 3e39cc2..8a655d6 100644 --- a/config/shadowsocksr.go +++ b/config/shadowsocksr.go @@ -2,7 +2,7 @@ package config import ( "errors" - "fmt" + "net" "net/url" "regexp" "strconv" @@ -77,7 +77,7 @@ func SSRLinkToSSROption(link string) (*outbound.ShadowSocksROption, error) { remarks, err := utils.DecodeB64(rawQuery.Get("remarks")) if err == nil { if remarks == "" { - remarks = fmt.Sprintf("%s:%d", ssrOption.Server, ssrOption.Port) + remarks = net.JoinHostPort(ssrOption.Server, strconv.Itoa(ssrOption.Port)) } ssrOption.Remarks = remarks ssrOption.Name = remarks diff --git a/core/core.go b/core/core.go index 39d8bb9..02162d4 100644 --- a/core/core.go +++ b/core/core.go @@ -5,6 +5,8 @@ import ( "errors" "fmt" "log" + "net" + "strconv" "time" "github.com/xxf098/lite-proxy/config" @@ -52,7 +54,7 @@ func StartInstance(c Config) (*proxy.Proxy, error) { Attempts: c.Ping, TimeOut: 1200 * time.Millisecond, } - info := fmt.Sprintf("%s %s:%d", cfg.Remarks, cfg.Server, cfg.Port) + info := fmt.Sprintf("%s %s", cfg.Remarks, net.JoinHostPort(cfg.Server, strconv.Itoa(cfg.Port))) if elapse, err := request.PingLinkInternal(link, opt); err == nil { info = fmt.Sprintf("%s \033[32m%dms\033[0m", info, elapse) } else { diff --git a/proxy/proxy.go b/proxy/proxy.go index 3854af8..76768f3 100644 --- a/proxy/proxy.go +++ b/proxy/proxy.go @@ -5,6 +5,7 @@ import ( "fmt" "io" "net" + "strconv" "time" "github.com/xxf098/lite-proxy/common" @@ -60,7 +61,7 @@ func (p *Proxy) relayConnLoop() { if networkType == "" { networkType = "tcp" } - add := fmt.Sprintf("%s:%d", addr.IP.String(), addr.Port) + add := net.JoinHostPort(addr.IP.String(), strconv.Itoa(addr.Port)) outbound, err = net.Dial(networkType, add) } else { outbound, err = p.sink.DialConn(addr, nil) diff --git a/web/msg.go b/web/msg.go index c511daa..c1ca81b 100644 --- a/web/msg.go +++ b/web/msg.go @@ -3,6 +3,8 @@ package web import ( "encoding/json" "fmt" + "net" + "strconv" "strings" "github.com/xxf098/lite-proxy/config" @@ -48,7 +50,7 @@ func gotserverMsg(id int, link string, groupName string) []byte { if err == nil { msg.Group = groupName msg.Remarks = cfg.Remarks - msg.Server = fmt.Sprintf("%s:%d", cfg.Server, cfg.Port) + msg.Server = net.JoinHostPort(cfg.Server, strconv.Itoa(cfg.Port)) msg.Protocol = cfg.Protocol if cfg.Protocol == "vmess" && cfg.Net != "" { msg.Protocol = fmt.Sprintf("%s/%s", cfg.Protocol, cfg.Net) @@ -68,7 +70,7 @@ func gotserversMsg(startID int, links []string, groupName string) []byte { if err == nil { msg.Group = groupName msg.Remarks = cfg.Remarks - msg.Server = fmt.Sprintf("%s:%d", cfg.Server, cfg.Port) + msg.Server = net.JoinHostPort(cfg.Server, strconv.Itoa(cfg.Port)) msg.Protocol = cfg.Protocol if (cfg.Protocol == "vmess" || cfg.Protocol == "trojan") && cfg.Net != "" { msg.Protocol = fmt.Sprintf("%s/%s", cfg.Protocol, cfg.Net) diff --git a/web/server.go b/web/server.go index d60d5b4..ad7a9f2 100644 --- a/web/server.go +++ b/web/server.go @@ -13,6 +13,7 @@ import ( "net/http" "net/url" "os" + "strconv" "strings" "time" @@ -33,7 +34,7 @@ func ServeFile(port int) error { http.HandleFunc("/generateResult", generateResult) log.Printf("Start server at http://127.0.0.1:%d\n", port) if ipAddr, err := localIP(); err == nil { - log.Printf("Start server at http://%s:%d", ipAddr.String(), port) + log.Printf("Start server at http://%s", net.JoinHostPort(ipAddr.String(), strconv.Itoa(port))) } err := http.ListenAndServe(fmt.Sprintf(":%d", port), nil) return err From 042aba67925a7a278fc09c4b0d71692d06ee6db0 Mon Sep 17 00:00:00 2001 From: xxf098 Date: Mon, 23 Jan 2023 21:39:54 -0500 Subject: [PATCH 13/43] print url --- web/profile.go | 1 + 1 file changed, 1 insertion(+) diff --git a/web/profile.go b/web/profile.go index eba7bf3..0f3cac3 100644 --- a/web/profile.go +++ b/web/profile.go @@ -101,6 +101,7 @@ func ParseLinks(message string) ([]string, error) { func ParseLinksWithOption(message string, opt ParseOption) ([]string, error) { // matched, err := regexp.MatchString(`^(?:https?:\/\/)(?:[^@\/\n]+@)?(?:www\.)?([^:\/\n]+)`, message) if opt.Type == PARSE_URL || utils.IsUrl(message) { + log.Println(message) return getSubscriptionLinks(message) } // check is file path From 4501df0f29e1f1bd8496badf03ed31387ca14745 Mon Sep 17 00:00:00 2001 From: xxf098 Date: Fri, 27 Jan 2023 21:36:24 -0500 Subject: [PATCH 14/43] update hint --- web/gui/src/App.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/gui/src/App.vue b/web/gui/src/App.vue index b2efbb4..8261855 100644 --- a/web/gui/src/App.vue +++ b/web/gui/src/App.vue @@ -18,7 +18,7 @@ From fcd447ede63830765b8e90a65acee9387b31e3ca Mon Sep 17 00:00:00 2001 From: xxf098 Date: Mon, 30 Jan 2023 20:14:48 -0500 Subject: [PATCH 15/43] check nil --- transport/vmess/http.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/transport/vmess/http.go b/transport/vmess/http.go index 1c09e21..92ee06a 100644 --- a/transport/vmess/http.go +++ b/transport/vmess/http.go @@ -60,6 +60,9 @@ func (hc *httpConn) Write(b []byte) (int, error) { u := fmt.Sprintf("http://%s%s", host, path) req, _ := http.NewRequest("GET", u, bytes.NewBuffer(b)) for key, list := range hc.cfg.Headers { + if list == nil { + continue + } req.Header.Set(key, list[rand.Intn(len(list))]) } req.ContentLength = int64(len(b)) From f88df96e4849dcc1dcffc13f18dc9aa6b08f6cb2 Mon Sep 17 00:00:00 2001 From: xxf098 Date: Tue, 31 Jan 2023 07:58:50 -0500 Subject: [PATCH 16/43] check error --- transport/vmess/http.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/transport/vmess/http.go b/transport/vmess/http.go index 92ee06a..07e1552 100644 --- a/transport/vmess/http.go +++ b/transport/vmess/http.go @@ -58,11 +58,11 @@ func (hc *httpConn) Write(b []byte) (int, error) { } u := fmt.Sprintf("http://%s%s", host, path) - req, _ := http.NewRequest("GET", u, bytes.NewBuffer(b)) + req, err := http.NewRequest("GET", u, bytes.NewBuffer(b)) + if err != nil { + return 0, err + } for key, list := range hc.cfg.Headers { - if list == nil { - continue - } req.Header.Set(key, list[rand.Intn(len(list))]) } req.ContentLength = int64(len(b)) From 29f5b188f22f0c724d792a7e2bdfd28e67842258 Mon Sep 17 00:00:00 2001 From: xxf098 Date: Fri, 3 Feb 2023 18:36:02 -0500 Subject: [PATCH 17/43] udpate readme --- README.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 81b3aa1..67dd07d 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,14 @@ # LiteSpeedTest LiteSpeedTest is a simple tool for batch test ss/ssr/v2ray/trojan/clash servers. -Support tested by single link, multiple links, subscription link and file path. +Feature +- 支持ss/ssr/v2ray/trojan/clash订阅链接 +- 支持ss/ssr/v2ray/trojan/clash节点链接 +- 支持ss/ssr/v2ray/trojan/clash订阅或节点文件 +- support ss/ssr/v2ray/trojan/clash subscription url, +- support ss/ssr/v2ray/trojan/clash profile links +- support ss/ssr/v2ray/trojan/clash subscription or profile file, + ![build](https://github.com/xxf098/LiteSpeedTest/actions/workflows/test.yaml/badge.svg?branch=master&event=push) From 73556414b5e48d0509dc0a9297b155abd3f0783d Mon Sep 17 00:00:00 2001 From: xxf098 Date: Sat, 4 Feb 2023 03:22:25 -0500 Subject: [PATCH 18/43] fix typo --- config/vmess.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/vmess.go b/config/vmess.go index 212484d..360bcc1 100644 --- a/config/vmess.go +++ b/config/vmess.go @@ -333,14 +333,14 @@ func ShadowrocketVmessLinkToVmessConfig(link string, resolveip bool) (*VmessConf mhp := strings.SplitN(string(b), ":", 3) if len(mhp) != 3 { - return nil, fmt.Errorf("vmess unreconized: method:host:port -- %v", mhp) + return nil, fmt.Errorf("vmess unrecognized: method:host:port -- %v", mhp) } config.Security = mhp[0] // mhp[0] is the encryption method config.Port = []byte(mhp[2]) idadd := strings.SplitN(mhp[1], "@", 2) if len(idadd) != 2 { - return nil, fmt.Errorf("vmess unreconized: id@addr -- %v", idadd) + return nil, fmt.Errorf("vmess unrecognized: id@addr -- %v", idadd) } config.ID = idadd[0] config.Add = idadd[1] From b688101ad4511a7fdb00b0ef77f081b195f6c105 Mon Sep 17 00:00:00 2001 From: xxf098 Date: Mon, 6 Feb 2023 09:08:28 -0500 Subject: [PATCH 19/43] log more details --- config/clash.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/config/clash.go b/config/clash.go index 20b9adb..524fa33 100644 --- a/config/clash.go +++ b/config/clash.go @@ -1,6 +1,7 @@ package config import ( + "encoding/json" "fmt" "log" "net" @@ -203,7 +204,11 @@ func parseProxies(cfg *ClashRawConfig) ([]string, error) { for idx, mapping := range cfg.Proxy { link, err := ParseProxy(mapping, cfg.NamePrefix) if err != nil { - log.Printf("parseProxies %d: %s", idx, err.Error()) + if b, err := json.Marshal(mapping); err == nil { + log.Printf("parseProxies %d: %s | %s", idx, err.Error(), string(b)) + } else { + log.Printf("parseProxies %d: %s", idx, err.Error()) + } continue } proxyList = append(proxyList, link) From 0575a996350c5b80d598a116c09cdcac3d84862f Mon Sep 17 00:00:00 2001 From: xxf098 Date: Mon, 6 Feb 2023 20:10:41 -0500 Subject: [PATCH 20/43] fix error --- config/clash.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/clash.go b/config/clash.go index 524fa33..6a801d2 100644 --- a/config/clash.go +++ b/config/clash.go @@ -204,7 +204,7 @@ func parseProxies(cfg *ClashRawConfig) ([]string, error) { for idx, mapping := range cfg.Proxy { link, err := ParseProxy(mapping, cfg.NamePrefix) if err != nil { - if b, err := json.Marshal(mapping); err == nil { + if b, err1 := json.Marshal(mapping); err1 == nil { log.Printf("parseProxies %d: %s | %s", idx, err.Error(), string(b)) } else { log.Printf("parseProxies %d: %s", idx, err.Error()) From 71487fb92dc030db97d44bbecef862412eb61793 Mon Sep 17 00:00:00 2001 From: xxf098 Date: Sat, 11 Feb 2023 07:19:28 -0500 Subject: [PATCH 21/43] parse Shadowrocket Vmess link --- config/clash.go | 7 +--- config/vmess.go | 90 ++++++++++++++++++++++++++++++++++++++++++++----- web/profile.go | 17 +++++++--- 3 files changed, 96 insertions(+), 18 deletions(-) diff --git a/config/clash.go b/config/clash.go index 6a801d2..20b9adb 100644 --- a/config/clash.go +++ b/config/clash.go @@ -1,7 +1,6 @@ package config import ( - "encoding/json" "fmt" "log" "net" @@ -204,11 +203,7 @@ func parseProxies(cfg *ClashRawConfig) ([]string, error) { for idx, mapping := range cfg.Proxy { link, err := ParseProxy(mapping, cfg.NamePrefix) if err != nil { - if b, err1 := json.Marshal(mapping); err1 == nil { - log.Printf("parseProxies %d: %s | %s", idx, err.Error(), string(b)) - } else { - log.Printf("parseProxies %d: %s", idx, err.Error()) - } + log.Printf("parseProxies %d: %s", idx, err.Error()) continue } proxyList = append(proxyList, link) diff --git a/config/vmess.go b/config/vmess.go index 360bcc1..393c03d 100644 --- a/config/vmess.go +++ b/config/vmess.go @@ -5,6 +5,7 @@ import ( "encoding/json" "fmt" "io/ioutil" + "net" "net/url" "regexp" "strconv" @@ -14,6 +15,8 @@ import ( "github.com/xxf098/lite-proxy/utils" ) +var RegShadowrocketVmess = regexp.MustCompile(`(?i)vmess://(\S+?)@(\S+?):([0-9]{2,5})/?([?#][^\s]+)`) + type User struct { Email string `json:"Email"` ID string `json:"ID"` @@ -315,8 +318,8 @@ func ShadowrocketLinkToVmessLink(link string) (string, error) { } func ShadowrocketVmessLinkToVmessConfig(link string, resolveip bool) (*VmessConfig, error) { - if !strings.HasPrefix(link, "vmess://") { - return nil, fmt.Errorf("vmess unreconized: %s", link) + if !RegShadowrocketVmess.MatchString(link) { + return nil, fmt.Errorf("not a vmess link: %s", link) } url, err := url.Parse(link) if err != nil { @@ -328,7 +331,7 @@ func ShadowrocketVmessLinkToVmessConfig(link string, resolveip bool) (*VmessConf b64 := url.Host b, err := utils.DecodeB64Bytes(b64) if err != nil { - return nil, err + return shadowrocketVmessURLToVmessConfig(link, resolveip) } mhp := strings.SplitN(string(b), ":", 3) @@ -376,13 +379,84 @@ func ShadowrocketVmessLinkToVmessConfig(link string, resolveip bool) (*VmessConf return &config, nil } -func VmessLinkToVmessConfigIP(link string, resolveip bool) (*VmessConfig, error) { - config, err := VmessLinkToVmessConfig(link, resolveip) +func shadowrocketVmessURLToVmessConfig(link string, resolveip bool) (*VmessConfig, error) { + u, err := url.Parse(link) + if err != nil { + return nil, err + } + if u.Scheme != "vmess" { + return nil, fmt.Errorf("not a vmess link: %s", link) + } + pass := u.User.Username() + hostport := u.Host + host, _, err := net.SplitHostPort(hostport) + if err != nil { + return nil, err + } + _, err = strconv.Atoi(u.Port()) + if err != nil { + return nil, err + } + + config := VmessConfig{ + V: []byte("2"), + ID: pass, + Add: host, + Port: []byte(u.Port()), + Ps: u.Fragment, + Net: "tcp", + Aid: []byte("0"), + Type: "auto", + TLSRaw: []byte("false"), + } + + vals, err := url.ParseQuery(u.RawQuery) if err != nil { + return nil, err + } + if v := vals.Get("type"); v != "" { + config.Net = v + } + + if v := vals.Get("encryption"); v != "" { + config.Encryption = v + } + + if v := vals.Get("host"); v != "" { + config.Host = v + } + + if v := vals.Get("path"); v != "" { + config.Path = v + } + + if v := vals.Get("security"); v != "" { + config.TLS = v + config.TLSRaw = json.RawMessage("true") + } + + if v := vals.Get("sni"); v != "" { + config.ServerName = v + } + + if v := vals.Get("aid"); v != "" { + config.Aid = []byte(v) + } + + config.ResolveIP = resolveip + return &config, nil +} + +func VmessLinkToVmessConfigIP(link string, resolveip bool) (*VmessConfig, error) { + var config *VmessConfig + var err error + if strings.Contains(link, "&") { config, err = ShadowrocketVmessLinkToVmessConfig(link, resolveip) - if err != nil { - return nil, err - } + } else { + config, err = VmessLinkToVmessConfig(link, resolveip) + } + if err != nil { + return nil, err } port, err := rawMessageToInt(config.Port) if err != nil { diff --git a/web/profile.go b/web/profile.go index 0f3cac3..196e5ad 100644 --- a/web/profile.go +++ b/web/profile.go @@ -27,7 +27,10 @@ import ( "github.com/xxf098/lite-proxy/web/render" ) -var ErrInvalidData = errors.New("invalid data") +var ( + ErrInvalidData = errors.New("invalid data") + regProfile = regexp.MustCompile(`((?i)vmess://(\S+?)@(\S+?):([0-9]{2,5})/([?#][^\s]+))|((?i)vmess://[a-zA-Z0-9+_/=-]+([?#][^\s]+)?)|((?i)ssr://[a-zA-Z0-9+_/=-]+)|((?i)(vless|ss|trojan)://(\S+?)@(\S+?):([0-9]{2,5})([?#][^\s]+))|((?i)(ss)://[a-zA-Z0-9+_/=-]+([?#][^\s]+))`) +) const ( PIC_BASE64 = iota @@ -141,8 +144,8 @@ func parseProfiles(data string) ([]string, error) { } data = strings.Join(links, "\n") } - reg := regexp.MustCompile(`((?i)vmess://[a-zA-Z0-9+_/=-]+([?#][^\s]+)?)|((?i)ssr://[a-zA-Z0-9+_/=-]+)|((?i)(vless|ss|trojan)://(\S+?)@(\S+?):([0-9]{2,5})([?#][^\s]+))|((?i)(ss)://[a-zA-Z0-9+_/=-]+([?#][^\s]+))`) - matches := reg.FindAllStringSubmatch(data, -1) + // reg := regexp.MustCompile(`((?i)vmess://(\S+?)@(\S+?):([0-9]{2,5})/([?#][^\s]+))|((?i)vmess://[a-zA-Z0-9+_/=-]+([?#][^\s]+)?)|((?i)ssr://[a-zA-Z0-9+_/=-]+)|((?i)(vless|ss|trojan)://(\S+?)@(\S+?):([0-9]{2,5})([?#][^\s]+))|((?i)(ss)://[a-zA-Z0-9+_/=-]+([?#][^\s]+))`) + matches := regProfile.FindAllStringSubmatch(data, -1) linksLen, matchesLen := len(links), len(matches) if linksLen < matchesLen { links = make([]string, matchesLen) @@ -150,7 +153,13 @@ func parseProfiles(data string) ([]string, error) { links = links[:len(matches)] } for index, match := range matches { - links[index] = match[0] + link := match[0] + if config.RegShadowrocketVmess.MatchString(link) { + if l, err := config.ShadowrocketLinkToVmessLink(link); err == nil { + link = l + } + } + links[index] = link } return links, nil } From c1cd8a72deac167c6d20999010acbc786ecdb962 Mon Sep 17 00:00:00 2001 From: xxf098 Date: Sat, 18 Feb 2023 02:24:12 -0500 Subject: [PATCH 22/43] update go v1.20 --- .github/workflows/cron.yaml | 2 +- .github/workflows/release.yaml | 2 +- .github/workflows/test.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/cron.yaml b/.github/workflows/cron.yaml index 8b868f0..0b13e24 100644 --- a/.github/workflows/cron.yaml +++ b/.github/workflows/cron.yaml @@ -29,7 +29,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v3 with: - go-version: 1.18 # The Go version to download (if necessary) and use. + go-version: 1.20 # The Go version to download (if necessary) and use. cache: true - uses: actions/setup-node@v3 diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 9f50ed2..20c08a2 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -11,7 +11,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v3 with: - go-version: 1.19 + go-version: 1.20 cache: true - uses: actions/setup-node@v3 with: diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 4ce4dc0..8a9c5a6 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -45,7 +45,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v3 with: - go-version: 1.19 + go-version: 1.20 cache: true - uses: actions/setup-node@v3 From ea6ce54b9a57591de7b8583d3c85be82a2b20987 Mon Sep 17 00:00:00 2001 From: xxf098 Date: Sat, 18 Feb 2023 02:26:54 -0500 Subject: [PATCH 23/43] update go v1.20.1 --- .github/workflows/cron.yaml | 2 +- .github/workflows/release.yaml | 2 +- .github/workflows/test.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/cron.yaml b/.github/workflows/cron.yaml index 0b13e24..ccf03ce 100644 --- a/.github/workflows/cron.yaml +++ b/.github/workflows/cron.yaml @@ -29,7 +29,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v3 with: - go-version: 1.20 # The Go version to download (if necessary) and use. + go-version: 1.20.1 # The Go version to download (if necessary) and use. cache: true - uses: actions/setup-node@v3 diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 20c08a2..09ec797 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -11,7 +11,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v3 with: - go-version: 1.20 + go-version: 1.20.1 cache: true - uses: actions/setup-node@v3 with: diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 8a9c5a6..4b75c48 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -45,7 +45,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v3 with: - go-version: 1.20 + go-version: 1.20.1 cache: true - uses: actions/setup-node@v3 From e6902dbbc5f92342879ef52f80452ef365ec5a0e Mon Sep 17 00:00:00 2001 From: xxf098 Date: Sat, 18 Feb 2023 03:20:25 -0500 Subject: [PATCH 24/43] remove AddrType on Metadata --- constant/metadata.go | 35 ++++++++++++-------- outbound/util.go | 5 +-- outbound/vmess.go | 9 ++--- proxy/client.go | 9 +++-- proxy/shadowsocks/shadowsocks.go | 9 +++-- proxy/trojan/trojan.go | 9 +++-- proxy/vmess/client.go | 9 +++-- request/request.go | 57 +++++++++++++++----------------- 8 files changed, 72 insertions(+), 70 deletions(-) diff --git a/constant/metadata.go b/constant/metadata.go index 855f0ec..021943a 100644 --- a/constant/metadata.go +++ b/constant/metadata.go @@ -5,14 +5,12 @@ import ( "net" "strconv" "time" + + "github.com/xxf098/lite-proxy/transport/socks5" ) // Socks addr type const ( - AtypIPv4 = 1 - AtypDomainName = 3 - AtypIPv6 = 4 - TCP NetWork = iota UDP @@ -64,15 +62,14 @@ func (t Type) MarshalJSON() ([]byte, error) { // Metadata is used to store connection address type Metadata struct { - NetWork NetWork `json:"network"` // tcp =3 udp = 4 - Type Type `json:"type"` - SrcIP net.IP `json:"sourceIP"` - DstIP net.IP `json:"destinationIP"` - SrcPort string `json:"sourcePort"` - DstPort string `json:"destinationPort"` - AddrType int `json:"-"` // IPv4=1 DomainName=3 IPv6=4 - Host string `json:"host"` - Timeout time.Duration + NetWork NetWork `json:"network"` // tcp =3 udp = 4 + Type Type `json:"type"` + SrcIP net.IP `json:"sourceIP"` + DstIP net.IP `json:"destinationIP"` + SrcPort string `json:"sourcePort"` + DstPort string `json:"destinationPort"` + Host string `json:"host"` + Timeout time.Duration } func (m *Metadata) RemoteAddress() string { @@ -83,6 +80,18 @@ func (m *Metadata) SourceAddress() string { return net.JoinHostPort(m.SrcIP.String(), m.SrcPort) } +// IPv4=1 DomainName=3 IPv6=4 +func (m *Metadata) AddrType() int { + switch true { + case m.Host != "" || m.DstIP == nil: + return socks5.AtypDomainName + case m.DstIP.To4() != nil: + return socks5.AtypIPv4 + default: + return socks5.AtypIPv6 + } +} + func (m *Metadata) Resolved() bool { return m.DstIP != nil } diff --git a/outbound/util.go b/outbound/util.go index 20e8173..a1576c9 100644 --- a/outbound/util.go +++ b/outbound/util.go @@ -38,10 +38,11 @@ func tcpKeepAlive(c net.Conn) { func serializesSocksAddr(metadata *C.Metadata) []byte { var buf [][]byte - aType := uint8(metadata.AddrType) + addrType := metadata.AddrType() + aType := uint8(addrType) p, _ := strconv.ParseUint(metadata.DstPort, 10, 16) port := []byte{uint8(p >> 8), uint8(p & 0xff)} - switch metadata.AddrType { + switch addrType { case socks5.AtypDomainName: len := uint8(len(metadata.Host)) host := []byte(metadata.Host) diff --git a/outbound/vmess.go b/outbound/vmess.go index 3e4b6c1..aaeb41b 100644 --- a/outbound/vmess.go +++ b/outbound/vmess.go @@ -15,6 +15,7 @@ import ( "github.com/xxf098/lite-proxy/stats" "github.com/xxf098/lite-proxy/transport/dialer" "github.com/xxf098/lite-proxy/transport/resolver" + "github.com/xxf098/lite-proxy/transport/socks5" "github.com/xxf098/lite-proxy/transport/vmess" "github.com/xxf098/lite-proxy/utils" ) @@ -253,16 +254,16 @@ func NewVmess(option *VmessOption) (*Vmess, error) { func parseVmessAddr(metadata *C.Metadata) *vmess.DstAddr { var addrType byte var addr []byte - switch metadata.AddrType { - case C.AtypIPv4: + switch metadata.AddrType() { + case socks5.AtypIPv4: addrType = byte(vmess.AtypIPv4) addr = make([]byte, net.IPv4len) copy(addr[:], metadata.DstIP.To4()) - case C.AtypIPv6: + case socks5.AtypIPv6: addrType = byte(vmess.AtypIPv6) addr = make([]byte, net.IPv6len) copy(addr[:], metadata.DstIP.To16()) - case C.AtypDomainName: + case socks5.AtypDomainName: addrType = byte(vmess.AtypDomainName) addr = make([]byte, len(metadata.Host)+1) addr[0] = byte(len(metadata.Host)) diff --git a/proxy/client.go b/proxy/client.go index c600f92..d7f8774 100644 --- a/proxy/client.go +++ b/proxy/client.go @@ -21,11 +21,10 @@ func (c Client) DialConn(addr *tunnel.Address, _ tunnel.Tunnel) (net.Conn, error networkType = C.UDP } meta := &C.Metadata{ - NetWork: networkType, - Type: 0, - SrcPort: "", - AddrType: int(addr.AddressType), - DstPort: fmt.Sprintf("%d", addr.Port), + NetWork: networkType, + Type: 0, + SrcPort: "", + DstPort: fmt.Sprintf("%d", addr.Port), } switch addr.AddressType { case tunnel.IPv4: diff --git a/proxy/shadowsocks/shadowsocks.go b/proxy/shadowsocks/shadowsocks.go index 6ac027c..e9befe7 100644 --- a/proxy/shadowsocks/shadowsocks.go +++ b/proxy/shadowsocks/shadowsocks.go @@ -17,11 +17,10 @@ type Client struct { func (c Client) DialConn(addr *tunnel.Address, _ tunnel.Tunnel) (net.Conn, error) { meta := &C.Metadata{ - NetWork: 0, - Type: 0, - SrcPort: "", - AddrType: int(addr.AddressType), - DstPort: fmt.Sprintf("%d", addr.Port), + NetWork: 0, + Type: 0, + SrcPort: "", + DstPort: fmt.Sprintf("%d", addr.Port), } switch addr.AddressType { case tunnel.IPv4: diff --git a/proxy/trojan/trojan.go b/proxy/trojan/trojan.go index ccd5315..091307b 100644 --- a/proxy/trojan/trojan.go +++ b/proxy/trojan/trojan.go @@ -17,11 +17,10 @@ type Client struct { func (c Client) DialConn(addr *tunnel.Address, _ tunnel.Tunnel) (net.Conn, error) { meta := &C.Metadata{ - NetWork: 0, - Type: 0, - SrcPort: "", - AddrType: int(addr.AddressType), - DstPort: fmt.Sprintf("%d", addr.Port), + NetWork: 0, + Type: 0, + SrcPort: "", + DstPort: fmt.Sprintf("%d", addr.Port), } switch addr.AddressType { case tunnel.IPv4: diff --git a/proxy/vmess/client.go b/proxy/vmess/client.go index 5af6ad8..654f338 100644 --- a/proxy/vmess/client.go +++ b/proxy/vmess/client.go @@ -21,11 +21,10 @@ func (c Client) DialConn(addr *tunnel.Address, _ tunnel.Tunnel) (net.Conn, error networkType = C.UDP } meta := &C.Metadata{ - NetWork: networkType, - Type: 0, - SrcPort: "", - AddrType: int(addr.AddressType), - DstPort: fmt.Sprintf("%d", addr.Port), + NetWork: networkType, + Type: 0, + SrcPort: "", + DstPort: fmt.Sprintf("%d", addr.Port), } switch addr.AddressType { case tunnel.IPv4: diff --git a/request/request.go b/request/request.go index a291fa8..0a126d6 100644 --- a/request/request.go +++ b/request/request.go @@ -43,12 +43,11 @@ func PingVmess(vmessOption *outbound.VmessOption) (int64, error) { return 0, err } meta := &C.Metadata{ - NetWork: 0, - Type: 0, - SrcPort: "", - DstPort: "80", - AddrType: 3, - Host: remoteHost, + NetWork: 0, + Type: 0, + SrcPort: "", + DstPort: "80", + Host: remoteHost, } remoteConn, err := vmess.DialContext(ctx, meta) if err != nil { @@ -134,12 +133,11 @@ func PingTrojan(trojanOption *outbound.TrojanOption) (int64, error) { return 0, err } meta := &C.Metadata{ - NetWork: 0, - Type: 0, - SrcPort: "", - DstPort: "80", - AddrType: 3, - Host: remoteHost, + NetWork: 0, + Type: 0, + SrcPort: "", + DstPort: "80", + Host: remoteHost, } remoteConn, err := trojan.DialContext(ctx, meta) if err != nil { @@ -156,12 +154,11 @@ func PingSS(ssOption *outbound.ShadowSocksOption) (int64, error) { return 0, err } meta := &C.Metadata{ - NetWork: 0, - Type: 0, - SrcPort: "", - DstPort: "80", - AddrType: 3, - Host: remoteHost, + NetWork: 0, + Type: 0, + SrcPort: "", + DstPort: "80", + Host: remoteHost, } remoteConn, err := ss.DialContext(ctx, meta) if err != nil { @@ -178,12 +175,11 @@ func PingSSR(ssrOption *outbound.ShadowSocksROption) (int64, error) { return 0, err } meta := &C.Metadata{ - NetWork: 0, - Type: 0, - SrcPort: "", - DstPort: "80", - AddrType: 3, - Host: remoteHost, + NetWork: 0, + Type: 0, + SrcPort: "", + DstPort: "80", + Host: remoteHost, } remoteConn, err := ssr.DialContext(ctx, meta) if err != nil { @@ -266,13 +262,12 @@ func PingContext(ctx context.Context, option interface{}) (int64, error) { var d outbound.ContextDialer var err error meta := &C.Metadata{ - NetWork: 0, - Type: C.TEST, - SrcPort: "", - DstPort: "80", - AddrType: 3, - Host: remoteHost, - Timeout: tcpTimeout, + NetWork: 0, + Type: C.TEST, + SrcPort: "", + DstPort: "80", + Host: remoteHost, + Timeout: tcpTimeout, } if ssOption, ok := option.(*outbound.ShadowSocksOption); ok { d, err = outbound.NewShadowSocks(ssOption) From af84fd07ab84c08cc3288521a8fc4b0f11168ff8 Mon Sep 17 00:00:00 2001 From: xxf098 Date: Sat, 18 Feb 2023 22:54:30 -0500 Subject: [PATCH 25/43] restore PeekClash --- web/profile.go | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/web/profile.go b/web/profile.go index 196e5ad..a00bd28 100644 --- a/web/profile.go +++ b/web/profile.go @@ -703,3 +703,48 @@ func png2base64(path string) (string, error) { func isYamlFile(filePath string) bool { return strings.HasSuffix(filePath, ".yaml") || strings.HasSuffix(filePath, ".yml") } + +// api +func PeekClash(input string, n int) ([]string, error) { + scanner := bufio.NewScanner(strings.NewReader(input)) + proxiesStart := false + data := []byte{} + linkCount := 0 + for scanner.Scan() { + b := scanner.Bytes() + trimLine := strings.TrimSpace(string(b)) + if trimLine == "proxy-groups:" || trimLine == "rules:" || trimLine == "Proxy Group:" { + break + } + if proxiesStart { + if _, err := config.ParseBaseProxy(trimLine); err != nil { + continue + } + if strings.HasPrefix(trimLine, "-") { + if linkCount >= n { + break + } + linkCount += 1 + } + data = append(data, b...) + data = append(data, byte('\n')) + continue + } + if !proxiesStart && (trimLine == "proxies:" || trimLine == "Proxy:") { + proxiesStart = true + b = []byte("proxies:") + } + data = append(data, b...) + data = append(data, byte('\n')) + } + // fmt.Println(string(data)) + links, err := parseClashByte(data) + if err != nil || len(links) < 1 { + return []string{}, err + } + endIndex := n + if endIndex > len(links) { + endIndex = len(links) + } + return links[:endIndex], nil +} From ef556007ed012bbed3385d08bad4fb32656d07e9 Mon Sep 17 00:00:00 2001 From: xxf098 Date: Sun, 19 Feb 2023 01:39:23 -0500 Subject: [PATCH 26/43] update go v1.20 --- go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 2f90f3a..ce54c0e 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/xxf098/lite-proxy -go 1.18 +go 1.20 require ( github.com/Dreamacro/go-shadowsocks2 v0.1.8 From 37a714f3e30f84826433a15d4d5fff583973c609 Mon Sep 17 00:00:00 2001 From: xxf098 Date: Sun, 19 Feb 2023 02:13:48 -0500 Subject: [PATCH 27/43] go v1.19 --- go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go.mod b/go.mod index ce54c0e..bb316ea 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/xxf098/lite-proxy -go 1.20 +go 1.19 require ( github.com/Dreamacro/go-shadowsocks2 v0.1.8 From 7e11417837064632796f8472576751a5971dce8d Mon Sep 17 00:00:00 2001 From: xxf098 Date: Fri, 17 Mar 2023 23:35:23 -0400 Subject: [PATCH 28/43] remove ioutil --- config/vmess.go | 4 ++-- web/render/util.go | 5 ++--- web/server.go | 10 +++++----- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/config/vmess.go b/config/vmess.go index 393c03d..7d53a63 100644 --- a/config/vmess.go +++ b/config/vmess.go @@ -4,9 +4,9 @@ import ( "encoding/base64" "encoding/json" "fmt" - "io/ioutil" "net" "net/url" + "os" "regexp" "strconv" "strings" @@ -485,7 +485,7 @@ func VmessLinkToVmessConfigIP(link string, resolveip bool) (*VmessConfig, error) } func ToVmessOption(path string) (*outbound.VmessOption, error) { - data, err := ioutil.ReadFile(path) + data, err := os.ReadFile(path) if err != nil { return nil, err } diff --git a/web/render/util.go b/web/render/util.go index 3155d29..875a8f3 100644 --- a/web/render/util.go +++ b/web/render/util.go @@ -7,7 +7,6 @@ import ( "image/jpeg" _ "image/jpeg" "image/png" - "io/ioutil" "math" "os" "strings" @@ -131,7 +130,7 @@ func unfix(x fixed.Int26_6) float64 { // You can usually just use the Context.LoadFontFace function instead of // this package-level function. func LoadFontFace(path string, points float64) (font.Face, error) { - fontBytes, err := ioutil.ReadFile(path) + fontBytes, err := os.ReadFile(path) if err != nil { return nil, err } @@ -162,7 +161,7 @@ func LoadFontFaceByBytes(fontBytes []byte, fontPath string, points float64) (fon } func LoadFontFace1(path string, points float64) (font.Face, error) { - fontBytes, err := ioutil.ReadFile(path) + fontBytes, err := os.ReadFile(path) if err != nil { return nil, err } diff --git a/web/server.go b/web/server.go index ad7a9f2..63efa5e 100644 --- a/web/server.go +++ b/web/server.go @@ -7,7 +7,7 @@ import ( "encoding/json" "errors" "fmt" - "io/ioutil" + "io" "log" "net" "net/http" @@ -107,7 +107,7 @@ func updateTest(w http.ResponseWriter, r *http.Request) { } func readConfig(configPath string) (*ProfileTestOptions, error) { - data, err := ioutil.ReadFile(configPath) + data, err := os.ReadFile(configPath) if err != nil { return nil, err } @@ -218,7 +218,7 @@ func generateResult(w http.ResponseWriter, r *http.Request) { http.Error(w, "Please send a request body", 400) return } - data, err := ioutil.ReadAll(r.Body) + data, err := io.ReadAll(r.Body) if err != nil { http.Error(w, "Please send a request body", 400) return @@ -315,7 +315,7 @@ func getSubscriptionLink(w http.ResponseWriter, r *http.Request) { http.Error(w, "Invalid Parameter", 400) return } - data, err := ioutil.ReadAll(r.Body) + data, err := io.ReadAll(r.Body) if err != nil { http.Error(w, "Invalid Parameter", 400) return @@ -375,7 +375,7 @@ func getSubscription(w http.ResponseWriter, r *http.Request) { w.Write(data) return } - data, err := ioutil.ReadFile(filePath) + data, err := os.ReadFile(filePath) if err != nil { http.Error(w, err.Error(), 400) return From 25cfd6f2e34000225ac2649c42455752e245fcc8 Mon Sep 17 00:00:00 2001 From: xxf098 Date: Sun, 26 Mar 2023 02:35:23 -0400 Subject: [PATCH 29/43] update regex --- web/profile.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/profile.go b/web/profile.go index a00bd28..689887d 100644 --- a/web/profile.go +++ b/web/profile.go @@ -29,7 +29,7 @@ import ( var ( ErrInvalidData = errors.New("invalid data") - regProfile = regexp.MustCompile(`((?i)vmess://(\S+?)@(\S+?):([0-9]{2,5})/([?#][^\s]+))|((?i)vmess://[a-zA-Z0-9+_/=-]+([?#][^\s]+)?)|((?i)ssr://[a-zA-Z0-9+_/=-]+)|((?i)(vless|ss|trojan)://(\S+?)@(\S+?):([0-9]{2,5})([?#][^\s]+))|((?i)(ss)://[a-zA-Z0-9+_/=-]+([?#][^\s]+))`) + regProfile = regexp.MustCompile(`((?i)vmess://(\S+?)@(\S+?):([0-9]{2,5})/([?#][^\s]+))|((?i)vmess://[a-zA-Z0-9+_/=-]+([?#][^\s]+)?)|((?i)ssr://[a-zA-Z0-9+_/=-]+)|((?i)(vless|ss|trojan)://(\S+?)@(\S+?):([0-9]{2,5})/?([?#][^\s]+))|((?i)(ss)://[a-zA-Z0-9+_/=-]+([?#][^\s]+))`) ) const ( From 9d2aa82da61ffc17eaf95edd63b0083a74bd239d Mon Sep 17 00:00:00 2001 From: xxf098 Date: Fri, 31 Mar 2023 20:27:18 -0400 Subject: [PATCH 30/43] show net type --- web/profile.go | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/web/profile.go b/web/profile.go index 689887d..5738929 100644 --- a/web/profile.go +++ b/web/profile.go @@ -584,10 +584,18 @@ func (p *ProfileTest) testOne(ctx context.Context, index int, link string, nodeC link = p.Links[index] link = strings.SplitN(link, "^", 2)[0] } - protocol, remarks, err := GetRemarks(link) + cfg, err := config.Link2Config(link) + if err != nil { + return err + } + remarks := cfg.Remarks if err != nil || remarks == "" { remarks = fmt.Sprintf("Profile %d", index) } + protocol := cfg.Protocol + if (cfg.Protocol == "vmess" || cfg.Protocol == "trojan") && cfg.Net != "" { + protocol = fmt.Sprintf("%s/%s", cfg.Protocol, cfg.Net) + } elapse, err := p.pingLink(index, link) log.Printf("%d %s elapse: %dms", index, remarks, elapse) if err != nil { From 91e066c51c336662d82235c53b7b1acaef7145b4 Mon Sep 17 00:00:00 2001 From: xxf098 Date: Fri, 31 Mar 2023 21:07:49 -0400 Subject: [PATCH 31/43] =?UTF-8?q?=E6=B5=8B=E8=AF=95=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web/gui/src/App.vue | 1 + 1 file changed, 1 insertion(+) diff --git a/web/gui/src/App.vue b/web/gui/src/App.vue index 8261855..977d67e 100644 --- a/web/gui/src/App.vue +++ b/web/gui/src/App.vue @@ -1054,6 +1054,7 @@ export default { break; case "eof": this.loading = false; + this.$notify.success("测试完成"); console.log(this.result) break; case "retest": From 7cd38366eb32650f6249ac474f02e36fa9cbf7a7 Mon Sep 17 00:00:00 2001 From: xxf098 Date: Wed, 5 Apr 2023 04:48:31 -0400 Subject: [PATCH 32/43] add OutputMode --- web/profile.go | 23 ++++++++++++++++++----- web/server.go | 4 ++++ 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/web/profile.go b/web/profile.go index 5738929..5cae990 100644 --- a/web/profile.go +++ b/web/profile.go @@ -37,6 +37,7 @@ const ( PIC_PATH PIC_NONE JSON_OUTPUT + TEXT_OUTPUT ) type PAESE_TYPE int @@ -319,7 +320,8 @@ type ProfileTestOptions struct { FontSize int `json:"fontSize"` Theme string `json:"theme"` Unique bool `json:"unique"` - GeneratePicMode int `json:"generatePicMode"` // 0: base64 1:pic path 2: no pic 3: json + GeneratePicMode int `json:"generatePicMode"` // 0: base64 1:pic path 2: no pic 3: json @deprecated use outputMode + OutputMode int `json:"outputMode"` } type JSONOutput struct { @@ -525,15 +527,17 @@ func (p *ProfileTest) testAll(ctx context.Context) (render.Nodes, error) { } close(nodeChan) - if p.Options.GeneratePicMode == PIC_NONE { + if p.Options.OutputMode == PIC_NONE { return nodes, nil } // sort nodes nodes.Sort(p.Options.SortMethod) // save json - if p.Options.GeneratePicMode == JSON_OUTPUT { + if p.Options.OutputMode == JSON_OUTPUT { p.saveJSON(nodes, traffic, duration, successCount, linksCount) + } else if p.Options.OutputMode == TEXT_OUTPUT { + p.saveText(nodes) } else { // render the result to pic p.renderPic(nodes, traffic, duration, successCount, linksCount) @@ -550,7 +554,7 @@ func (p *ProfileTest) renderPic(nodes render.Nodes, traffic int64, duration stri } // msg := fmt.Sprintf("Total Traffic : %s. Total Time : %s. Working Nodes: [%d/%d]", download.ByteCountIECTrim(traffic), duration, successCount, linksCount) msg := table.FormatTraffic(download.ByteCountIECTrim(traffic), duration, fmt.Sprintf("%d/%d", successCount, linksCount)) - if p.Options.GeneratePicMode == PIC_PATH { + if p.Options.OutputMode == PIC_PATH { table.Draw("out.png", msg) p.WriteMessage(getMsgByte(-1, "picdata", "out.png")) return nil @@ -574,7 +578,16 @@ func (p *ProfileTest) saveJSON(nodes render.Nodes, traffic int64, duration strin if err != nil { return err } - return ioutil.WriteFile("out.json", data, 0644) + return ioutil.WriteFile("output.json", data, 0644) +} + +func (p *ProfileTest) saveText(nodes render.Nodes) error { + links := []string{} + for _, node := range nodes { + links = append(links, node.Link) + } + data := []byte(strings.Join(links, "\n")) + return ioutil.WriteFile("output.txt", data, 0644) } func (p *ProfileTest) testOne(ctx context.Context, index int, link string, nodeChan chan<- render.Node, trafficChan chan<- int64) error { diff --git a/web/server.go b/web/server.go index 63efa5e..ed815ad 100644 --- a/web/server.go +++ b/web/server.go @@ -147,10 +147,14 @@ func TestFromCMD(subscription string, configPath *string) error { Theme: "rainbow", Timeout: 15 * time.Second, GeneratePicMode: PIC_PATH, + OutputMode: PIC_PATH, } if configPath != nil { if opt, err := readConfig(*configPath); err == nil { options = *opt + if options.GeneratePicMode != 0 { + options.OutputMode = options.GeneratePicMode + } // options.GeneratePic = true } } From 58218e0908d9617cef4af036cfe1a29eb0455a47 Mon Sep 17 00:00:00 2001 From: xxf098 Date: Wed, 5 Apr 2023 21:17:20 -0400 Subject: [PATCH 33/43] set OutputMode for rpc --- api/rpc/lite/lite.pb.go | 111 +++++++++++++++--------------- api/rpc/lite/lite.proto | 2 +- api/rpc/liteclient/client_test.go | 24 +++---- api/rpc/liteclientpy/README.md | 2 +- api/rpc/liteclientpy/lite_pb2.py | 24 +++---- 5 files changed, 81 insertions(+), 82 deletions(-) diff --git a/api/rpc/lite/lite.pb.go b/api/rpc/lite/lite.pb.go index 579ac47..0c51cc3 100644 --- a/api/rpc/lite/lite.pb.go +++ b/api/rpc/lite/lite.pb.go @@ -173,18 +173,18 @@ type TestRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - GroupName string `protobuf:"bytes,1,opt,name=GroupName,proto3" json:"GroupName,omitempty"` - SpeedTestMode SpeedTestMode `protobuf:"varint,2,opt,name=SpeedTestMode,proto3,enum=liteproxy.SpeedTestMode" json:"SpeedTestMode,omitempty"` - PingMethod PingMethod `protobuf:"varint,3,opt,name=PingMethod,proto3,enum=liteproxy.PingMethod" json:"PingMethod,omitempty"` - SortMethod SortMethod `protobuf:"varint,4,opt,name=SortMethod,proto3,enum=liteproxy.SortMethod" json:"SortMethod,omitempty"` - Concurrency int32 `protobuf:"varint,5,opt,name=Concurrency,proto3" json:"Concurrency,omitempty"` - TestMode uint32 `protobuf:"varint,6,opt,name=TestMode,proto3" json:"TestMode,omitempty"` // 0: all 1: speed only 2: ping only - Subscription string `protobuf:"bytes,7,opt,name=Subscription,proto3" json:"Subscription,omitempty"` // subscription link, clash link, profile links - Language string `protobuf:"bytes,8,opt,name=Language,proto3" json:"Language,omitempty"` - FontSize uint32 `protobuf:"varint,9,opt,name=FontSize,proto3" json:"FontSize,omitempty"` - Theme string `protobuf:"bytes,10,opt,name=Theme,proto3" json:"Theme,omitempty"` - Timeout int64 `protobuf:"varint,11,opt,name=Timeout,proto3" json:"Timeout,omitempty"` - GeneratePicMode uint32 `protobuf:"varint,12,opt,name=GeneratePicMode,proto3" json:"GeneratePicMode,omitempty"` // 0: base64 1:file path 2: no pic + GroupName string `protobuf:"bytes,1,opt,name=GroupName,proto3" json:"GroupName,omitempty"` + SpeedTestMode SpeedTestMode `protobuf:"varint,2,opt,name=SpeedTestMode,proto3,enum=liteproxy.SpeedTestMode" json:"SpeedTestMode,omitempty"` + PingMethod PingMethod `protobuf:"varint,3,opt,name=PingMethod,proto3,enum=liteproxy.PingMethod" json:"PingMethod,omitempty"` + SortMethod SortMethod `protobuf:"varint,4,opt,name=SortMethod,proto3,enum=liteproxy.SortMethod" json:"SortMethod,omitempty"` + Concurrency int32 `protobuf:"varint,5,opt,name=Concurrency,proto3" json:"Concurrency,omitempty"` + TestMode uint32 `protobuf:"varint,6,opt,name=TestMode,proto3" json:"TestMode,omitempty"` // 0: all 1: speed only 2: ping only + Subscription string `protobuf:"bytes,7,opt,name=Subscription,proto3" json:"Subscription,omitempty"` // subscription link, clash link, profile links + Language string `protobuf:"bytes,8,opt,name=Language,proto3" json:"Language,omitempty"` + FontSize uint32 `protobuf:"varint,9,opt,name=FontSize,proto3" json:"FontSize,omitempty"` + Theme string `protobuf:"bytes,10,opt,name=Theme,proto3" json:"Theme,omitempty"` + Timeout int64 `protobuf:"varint,11,opt,name=Timeout,proto3" json:"Timeout,omitempty"` + OutputMode uint32 `protobuf:"varint,12,opt,name=OutputMode,proto3" json:"OutputMode,omitempty"` // 0: base64 1:file path 2: no pic 3: json 4: txt } func (x *TestRequest) Reset() { @@ -296,9 +296,9 @@ func (x *TestRequest) GetTimeout() int64 { return 0 } -func (x *TestRequest) GetGeneratePicMode() uint32 { +func (x *TestRequest) GetOutputMode() uint32 { if x != nil { - return x.GeneratePicMode + return x.OutputMode } return 0 } @@ -427,7 +427,7 @@ var File_lite_proto protoreflect.FileDescriptor var file_lite_proto_rawDesc = []byte{ 0x0a, 0x0a, 0x6c, 0x69, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x09, 0x6c, 0x69, - 0x74, 0x65, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x22, 0xcd, 0x03, 0x0a, 0x0b, 0x54, 0x65, 0x73, 0x74, + 0x74, 0x65, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x22, 0xc3, 0x03, 0x0a, 0x0b, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x3e, 0x0a, 0x0d, 0x53, 0x70, 0x65, 0x65, 0x64, 0x54, 0x65, @@ -453,47 +453,46 @@ var file_lite_proto_rawDesc = []byte{ 0x01, 0x28, 0x0d, 0x52, 0x08, 0x46, 0x6f, 0x6e, 0x74, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x54, 0x68, 0x65, 0x6d, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x54, 0x68, 0x65, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x0b, - 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x28, 0x0a, - 0x0f, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x50, 0x69, 0x63, 0x4d, 0x6f, 0x64, 0x65, - 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0f, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, - 0x50, 0x69, 0x63, 0x4d, 0x6f, 0x64, 0x65, 0x22, 0xfd, 0x01, 0x0a, 0x09, 0x54, 0x65, 0x73, 0x74, - 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x05, 0x52, 0x02, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x4e, 0x61, - 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x4e, - 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x52, 0x65, 0x6d, 0x61, 0x72, 0x6b, 0x73, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x52, 0x65, 0x6d, 0x61, 0x72, 0x6b, 0x73, 0x12, 0x1a, 0x0a, - 0x08, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x08, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x50, 0x69, 0x6e, - 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x50, 0x69, 0x6e, 0x67, 0x12, 0x1a, 0x0a, - 0x08, 0x41, 0x76, 0x67, 0x53, 0x70, 0x65, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, - 0x08, 0x41, 0x76, 0x67, 0x53, 0x70, 0x65, 0x65, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x4d, 0x61, 0x78, - 0x53, 0x70, 0x65, 0x65, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x4d, 0x61, 0x78, - 0x53, 0x70, 0x65, 0x65, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x49, 0x73, 0x4f, 0x6b, 0x18, 0x08, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x04, 0x49, 0x73, 0x4f, 0x6b, 0x12, 0x18, 0x0a, 0x07, 0x54, 0x72, 0x61, - 0x66, 0x66, 0x69, 0x63, 0x18, 0x09, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x54, 0x72, 0x61, 0x66, - 0x66, 0x69, 0x63, 0x12, 0x12, 0x0a, 0x04, 0x4c, 0x69, 0x6e, 0x6b, 0x18, 0x0a, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x4c, 0x69, 0x6e, 0x6b, 0x2a, 0x35, 0x0a, 0x0d, 0x53, 0x70, 0x65, 0x65, 0x64, - 0x54, 0x65, 0x73, 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x0c, 0x0a, 0x08, 0x70, 0x69, 0x6e, 0x67, - 0x6f, 0x6e, 0x6c, 0x79, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x73, 0x70, 0x65, 0x65, 0x64, 0x6f, - 0x6e, 0x6c, 0x79, 0x10, 0x01, 0x12, 0x07, 0x0a, 0x03, 0x61, 0x6c, 0x6c, 0x10, 0x02, 0x2a, 0x29, - 0x0a, 0x0a, 0x50, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x0e, 0x0a, 0x0a, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x70, 0x69, 0x6e, 0x67, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, - 0x74, 0x63, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x10, 0x01, 0x2a, 0x38, 0x0a, 0x0a, 0x53, 0x6f, 0x72, - 0x74, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x09, 0x0a, 0x05, 0x73, 0x70, 0x65, 0x65, 0x64, - 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x72, 0x73, 0x70, 0x65, 0x65, 0x64, 0x10, 0x01, 0x12, 0x08, - 0x0a, 0x04, 0x70, 0x69, 0x6e, 0x67, 0x10, 0x02, 0x12, 0x09, 0x0a, 0x05, 0x72, 0x70, 0x69, 0x6e, - 0x67, 0x10, 0x03, 0x32, 0x4a, 0x0a, 0x09, 0x54, 0x65, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x78, 0x79, - 0x12, 0x3d, 0x0a, 0x09, 0x53, 0x74, 0x61, 0x72, 0x74, 0x54, 0x65, 0x73, 0x74, 0x12, 0x16, 0x2e, - 0x6c, 0x69, 0x74, 0x65, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x6c, 0x69, 0x74, 0x65, 0x70, 0x72, 0x6f, 0x78, - 0x79, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x30, 0x01, 0x42, - 0x58, 0x0a, 0x1e, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x78, 0x78, - 0x66, 0x30, 0x39, 0x38, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x6c, 0x69, 0x74, - 0x65, 0x42, 0x09, 0x4c, 0x69, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x50, 0x01, 0x5a, 0x29, - 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x78, 0x66, 0x30, 0x39, - 0x38, 0x2f, 0x6c, 0x69, 0x74, 0x65, 0x2d, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2f, 0x61, 0x70, 0x69, - 0x2f, 0x72, 0x70, 0x63, 0x2f, 0x6c, 0x69, 0x74, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x1e, 0x0a, + 0x0a, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, + 0x0d, 0x52, 0x0a, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x22, 0xfd, 0x01, + 0x0a, 0x09, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x49, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x47, + 0x72, 0x6f, 0x75, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, + 0x47, 0x72, 0x6f, 0x75, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x52, 0x65, 0x6d, + 0x61, 0x72, 0x6b, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x52, 0x65, 0x6d, 0x61, + 0x72, 0x6b, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, + 0x12, 0x0a, 0x04, 0x50, 0x69, 0x6e, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x50, + 0x69, 0x6e, 0x67, 0x12, 0x1a, 0x0a, 0x08, 0x41, 0x76, 0x67, 0x53, 0x70, 0x65, 0x65, 0x64, 0x18, + 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x41, 0x76, 0x67, 0x53, 0x70, 0x65, 0x65, 0x64, 0x12, + 0x1a, 0x0a, 0x08, 0x4d, 0x61, 0x78, 0x53, 0x70, 0x65, 0x65, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x08, 0x4d, 0x61, 0x78, 0x53, 0x70, 0x65, 0x65, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x49, + 0x73, 0x4f, 0x6b, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x49, 0x73, 0x4f, 0x6b, 0x12, + 0x18, 0x0a, 0x07, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x18, 0x09, 0x20, 0x01, 0x28, 0x03, + 0x52, 0x07, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x12, 0x12, 0x0a, 0x04, 0x4c, 0x69, 0x6e, + 0x6b, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4c, 0x69, 0x6e, 0x6b, 0x2a, 0x35, 0x0a, + 0x0d, 0x53, 0x70, 0x65, 0x65, 0x64, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x0c, + 0x0a, 0x08, 0x70, 0x69, 0x6e, 0x67, 0x6f, 0x6e, 0x6c, 0x79, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, + 0x73, 0x70, 0x65, 0x65, 0x64, 0x6f, 0x6e, 0x6c, 0x79, 0x10, 0x01, 0x12, 0x07, 0x0a, 0x03, 0x61, + 0x6c, 0x6c, 0x10, 0x02, 0x2a, 0x29, 0x0a, 0x0a, 0x50, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x74, 0x68, + 0x6f, 0x64, 0x12, 0x0e, 0x0a, 0x0a, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x70, 0x69, 0x6e, 0x67, + 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x74, 0x63, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x10, 0x01, 0x2a, + 0x38, 0x0a, 0x0a, 0x53, 0x6f, 0x72, 0x74, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x09, 0x0a, + 0x05, 0x73, 0x70, 0x65, 0x65, 0x64, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x72, 0x73, 0x70, 0x65, + 0x65, 0x64, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x70, 0x69, 0x6e, 0x67, 0x10, 0x02, 0x12, 0x09, + 0x0a, 0x05, 0x72, 0x70, 0x69, 0x6e, 0x67, 0x10, 0x03, 0x32, 0x4a, 0x0a, 0x09, 0x54, 0x65, 0x73, + 0x74, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x12, 0x3d, 0x0a, 0x09, 0x53, 0x74, 0x61, 0x72, 0x74, 0x54, + 0x65, 0x73, 0x74, 0x12, 0x16, 0x2e, 0x6c, 0x69, 0x74, 0x65, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2e, + 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x6c, 0x69, + 0x74, 0x65, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6c, + 0x79, 0x22, 0x00, 0x30, 0x01, 0x42, 0x58, 0x0a, 0x1e, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x69, 0x74, + 0x68, 0x75, 0x62, 0x2e, 0x78, 0x78, 0x66, 0x30, 0x39, 0x38, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, + 0x70, 0x63, 0x2e, 0x6c, 0x69, 0x74, 0x65, 0x42, 0x09, 0x4c, 0x69, 0x74, 0x65, 0x50, 0x72, 0x6f, + 0x78, 0x79, 0x50, 0x01, 0x5a, 0x29, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, + 0x2f, 0x78, 0x78, 0x66, 0x30, 0x39, 0x38, 0x2f, 0x6c, 0x69, 0x74, 0x65, 0x2d, 0x70, 0x72, 0x6f, + 0x78, 0x79, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x72, 0x70, 0x63, 0x2f, 0x6c, 0x69, 0x74, 0x65, 0x62, + 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/api/rpc/lite/lite.proto b/api/rpc/lite/lite.proto index c83bdfd..33048c4 100644 --- a/api/rpc/lite/lite.proto +++ b/api/rpc/lite/lite.proto @@ -43,7 +43,7 @@ message TestRequest { uint32 FontSize = 9; string Theme = 10; int64 Timeout = 11; - uint32 GeneratePicMode = 12; // 0: base64 1:file path 2: no pic + uint32 OutputMode = 12; // 0: base64 1:file path 2: no pic 3: json 4: txt } // reply message diff --git a/api/rpc/liteclient/client_test.go b/api/rpc/liteclient/client_test.go index 22230e9..cafbb40 100644 --- a/api/rpc/liteclient/client_test.go +++ b/api/rpc/liteclient/client_test.go @@ -10,18 +10,18 @@ import ( func TestStartClient(t *testing.T) { go s.StartServer(10999) req := pb.TestRequest{ - GroupName: "Default", - SpeedTestMode: pb.SpeedTestMode_all, - PingMethod: pb.PingMethod_googleping, - SortMethod: pb.SortMethod_rspeed, - Concurrency: 2, - TestMode: 2, - Subscription: "https://raw.githubusercontent.com/freefq/free/master/v2", - Language: "en", - FontSize: 24, - Theme: "rainbow", - Timeout: 10, - GeneratePicMode: 0, + GroupName: "Default", + SpeedTestMode: pb.SpeedTestMode_all, + PingMethod: pb.PingMethod_googleping, + SortMethod: pb.SortMethod_rspeed, + Concurrency: 2, + TestMode: 2, + Subscription: "https://raw.githubusercontent.com/freefq/free/master/v2", + Language: "en", + FontSize: 24, + Theme: "rainbow", + Timeout: 10, + OutputMode: 0, } reply, err := StartClient("127.0.0.1:10999", &req) if err != nil { diff --git a/api/rpc/liteclientpy/README.md b/api/rpc/liteclientpy/README.md index e10f2c5..5690ed3 100644 --- a/api/rpc/liteclientpy/README.md +++ b/api/rpc/liteclientpy/README.md @@ -4,7 +4,7 @@ virtualenv -p python3 env source env/bin/activate pip install grpcio grpcio-tools -cp ../lite/lite.proto +cp ../lite/lite.proto ./ # generate lite_pb2.py lite_pb2_grpc.py python3 -m grpc_tools.protoc --proto_path=. ./lite.proto --python_out=. --grpc_python_out=. ``` diff --git a/api/rpc/liteclientpy/lite_pb2.py b/api/rpc/liteclientpy/lite_pb2.py index 67fec59..87a9bef 100644 --- a/api/rpc/liteclientpy/lite_pb2.py +++ b/api/rpc/liteclientpy/lite_pb2.py @@ -13,7 +13,7 @@ -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\nlite.proto\x12\tliteproxy\"\xc1\x02\n\x0bTestRequest\x12\x11\n\tGroupName\x18\x01 \x01(\t\x12/\n\rSpeedTestMode\x18\x02 \x01(\x0e\x32\x18.liteproxy.SpeedTestMode\x12)\n\nPingMethod\x18\x03 \x01(\x0e\x32\x15.liteproxy.PingMethod\x12)\n\nSortMethod\x18\x04 \x01(\x0e\x32\x15.liteproxy.SortMethod\x12\x13\n\x0b\x43oncurrency\x18\x05 \x01(\x05\x12\x10\n\x08TestMode\x18\x06 \x01(\r\x12\x14\n\x0cSubscription\x18\x07 \x01(\t\x12\x10\n\x08Language\x18\x08 \x01(\t\x12\x10\n\x08\x46ontSize\x18\t \x01(\r\x12\r\n\x05Theme\x18\n \x01(\t\x12\x0f\n\x07Timeout\x18\x0b \x01(\x03\x12\x17\n\x0fGeneratePicMode\x18\x0c \x01(\r\"\xac\x01\n\tTestReply\x12\n\n\x02Id\x18\x01 \x01(\x05\x12\x11\n\tGroupName\x18\x02 \x01(\t\x12\x0f\n\x07Remarks\x18\x03 \x01(\t\x12\x10\n\x08Protocol\x18\x04 \x01(\t\x12\x0c\n\x04Ping\x18\x05 \x01(\t\x12\x10\n\x08\x41vgSpeed\x18\x06 \x01(\x03\x12\x10\n\x08MaxSpeed\x18\x07 \x01(\x03\x12\x0c\n\x04IsOk\x18\x08 \x01(\x08\x12\x0f\n\x07Traffic\x18\t \x01(\x03\x12\x0c\n\x04Link\x18\n \x01(\t*5\n\rSpeedTestMode\x12\x0c\n\x08pingonly\x10\x00\x12\r\n\tspeedonly\x10\x01\x12\x07\n\x03\x61ll\x10\x02*)\n\nPingMethod\x12\x0e\n\ngoogleping\x10\x00\x12\x0b\n\x07tcpping\x10\x01*8\n\nSortMethod\x12\t\n\x05speed\x10\x00\x12\n\n\x06rspeed\x10\x01\x12\x08\n\x04ping\x10\x02\x12\t\n\x05rping\x10\x03\x32J\n\tTestProxy\x12=\n\tStartTest\x12\x16.liteproxy.TestRequest\x1a\x14.liteproxy.TestReply\"\x00\x30\x01\x42X\n\x1e\x63om.github.xxf098.api.rpc.liteB\tLiteProxyP\x01Z)github.com/xxf098/lite-proxy/api/rpc/liteb\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\nlite.proto\x12\tliteproxy\"\xbc\x02\n\x0bTestRequest\x12\x11\n\tGroupName\x18\x01 \x01(\t\x12/\n\rSpeedTestMode\x18\x02 \x01(\x0e\x32\x18.liteproxy.SpeedTestMode\x12)\n\nPingMethod\x18\x03 \x01(\x0e\x32\x15.liteproxy.PingMethod\x12)\n\nSortMethod\x18\x04 \x01(\x0e\x32\x15.liteproxy.SortMethod\x12\x13\n\x0b\x43oncurrency\x18\x05 \x01(\x05\x12\x10\n\x08TestMode\x18\x06 \x01(\r\x12\x14\n\x0cSubscription\x18\x07 \x01(\t\x12\x10\n\x08Language\x18\x08 \x01(\t\x12\x10\n\x08\x46ontSize\x18\t \x01(\r\x12\r\n\x05Theme\x18\n \x01(\t\x12\x0f\n\x07Timeout\x18\x0b \x01(\x03\x12\x12\n\nOutputMode\x18\x0c \x01(\r\"\xac\x01\n\tTestReply\x12\n\n\x02Id\x18\x01 \x01(\x05\x12\x11\n\tGroupName\x18\x02 \x01(\t\x12\x0f\n\x07Remarks\x18\x03 \x01(\t\x12\x10\n\x08Protocol\x18\x04 \x01(\t\x12\x0c\n\x04Ping\x18\x05 \x01(\t\x12\x10\n\x08\x41vgSpeed\x18\x06 \x01(\x03\x12\x10\n\x08MaxSpeed\x18\x07 \x01(\x03\x12\x0c\n\x04IsOk\x18\x08 \x01(\x08\x12\x0f\n\x07Traffic\x18\t \x01(\x03\x12\x0c\n\x04Link\x18\n \x01(\t*5\n\rSpeedTestMode\x12\x0c\n\x08pingonly\x10\x00\x12\r\n\tspeedonly\x10\x01\x12\x07\n\x03\x61ll\x10\x02*)\n\nPingMethod\x12\x0e\n\ngoogleping\x10\x00\x12\x0b\n\x07tcpping\x10\x01*8\n\nSortMethod\x12\t\n\x05speed\x10\x00\x12\n\n\x06rspeed\x10\x01\x12\x08\n\x04ping\x10\x02\x12\t\n\x05rping\x10\x03\x32J\n\tTestProxy\x12=\n\tStartTest\x12\x16.liteproxy.TestRequest\x1a\x14.liteproxy.TestReply\"\x00\x30\x01\x42X\n\x1e\x63om.github.xxf098.api.rpc.liteB\tLiteProxyP\x01Z)github.com/xxf098/lite-proxy/api/rpc/liteb\x06proto3') _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'lite_pb2', globals()) @@ -21,16 +21,16 @@ DESCRIPTOR._options = None DESCRIPTOR._serialized_options = b'\n\036com.github.xxf098.api.rpc.liteB\tLiteProxyP\001Z)github.com/xxf098/lite-proxy/api/rpc/lite' - _SPEEDTESTMODE._serialized_start=524 - _SPEEDTESTMODE._serialized_end=577 - _PINGMETHOD._serialized_start=579 - _PINGMETHOD._serialized_end=620 - _SORTMETHOD._serialized_start=622 - _SORTMETHOD._serialized_end=678 + _SPEEDTESTMODE._serialized_start=519 + _SPEEDTESTMODE._serialized_end=572 + _PINGMETHOD._serialized_start=574 + _PINGMETHOD._serialized_end=615 + _SORTMETHOD._serialized_start=617 + _SORTMETHOD._serialized_end=673 _TESTREQUEST._serialized_start=26 - _TESTREQUEST._serialized_end=347 - _TESTREPLY._serialized_start=350 - _TESTREPLY._serialized_end=522 - _TESTPROXY._serialized_start=680 - _TESTPROXY._serialized_end=754 + _TESTREQUEST._serialized_end=342 + _TESTREPLY._serialized_start=345 + _TESTREPLY._serialized_end=517 + _TESTPROXY._serialized_start=675 + _TESTPROXY._serialized_end=749 # @@protoc_insertion_point(module_scope) From 8f58d806f601b2cb6b935dacd7d64fb242efeffe Mon Sep 17 00:00:00 2001 From: xxf098 Date: Fri, 7 Apr 2023 20:37:35 -0400 Subject: [PATCH 34/43] change to OutputMode --- api/rpc/liteclientpy/client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/rpc/liteclientpy/client.py b/api/rpc/liteclientpy/client.py index c847c57..4033047 100644 --- a/api/rpc/liteclientpy/client.py +++ b/api/rpc/liteclientpy/client.py @@ -35,7 +35,7 @@ def start_test(self): FontSize=24, Theme="rainbow", Timeout=10, - GeneratePicMode=0 + OutputMode=0 ) print(f'{message}') for response in self.stub.StartTest(message): From c40a633ff909ea7c7f6218c2f8755c81fc41a603 Mon Sep 17 00:00:00 2001 From: xxf098 Date: Sat, 8 Apr 2023 04:45:22 -0400 Subject: [PATCH 35/43] change to OutputMode --- README.md | 4 ++-- examples/ping.go | 24 ++++++++++++------------ 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 67dd07d..1bf964b 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ Run as a speed test tool: # "fontSize":24, # "unique": true, // remove duplicated value # "theme":"rainbow", - # "generatePicMode": 1 // 0: base64 1: pic path 2: no pic 3: json + # "outputMode": 1 // 0: base64 1: pic path 2: no pic 3: json 4: txt ./lite --config config.json --test https://raw.githubusercontent.com/freefq/free/master/v2 @@ -104,7 +104,7 @@ func testPing() error { Theme: "rainbow", Unique: true, Timeout: 10 * time.Second, - GeneratePicMode: 0, + OutputMode: 0, } nodes, err := web.TestContext(ctx, opts, &web.EmptyMessageWriter{}) if err != nil { diff --git a/examples/ping.go b/examples/ping.go index dd8c1c4..902b7f8 100644 --- a/examples/ping.go +++ b/examples/ping.go @@ -21,18 +21,18 @@ func main() { log.Fatal("link required") } opts := web.ProfileTestOptions{ - GroupName: "Default", - SpeedTestMode: *mode, // pingonly speedonly all - PingMethod: "googleping", // googleping - SortMethod: "rspeed", // speed rspeed ping rping - Concurrency: 2, - TestMode: 2, // 2: ALLTEST 3: RETEST - Subscription: *link, - Language: "en", // en cn - FontSize: 24, - Theme: "rainbow", - Timeout: 10 * time.Second, - GeneratePicMode: 0, // 0: base64 1:file path 2: no pic + GroupName: "Default", + SpeedTestMode: *mode, // pingonly speedonly all + PingMethod: "googleping", // googleping + SortMethod: "rspeed", // speed rspeed ping rping + Concurrency: 2, + TestMode: 2, // 2: ALLTEST 3: RETEST + Subscription: *link, + Language: "en", // en cn + FontSize: 24, + Theme: "rainbow", + Timeout: 10 * time.Second, + OutputMode: 0, // 0: base64 1:file path 2: no pic 3: json 4: txt } ctx := context.Background() var err error From a87cb925ce6e866f73af8073f89a9641043d75f6 Mon Sep 17 00:00:00 2001 From: xxf098 Date: Sat, 8 Apr 2023 04:52:33 -0400 Subject: [PATCH 36/43] OutputMode --- .github/workflows/cron.yaml | 2 +- config.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/cron.yaml b/.github/workflows/cron.yaml index ccf03ce..ecbaca1 100644 --- a/.github/workflows/cron.yaml +++ b/.github/workflows/cron.yaml @@ -51,7 +51,7 @@ jobs: - name: test link run: | - echo '{"group": "cronjob", "speedtestMode": "all", "pingMethod": "googleping", "sortMethod": "rspeed", "concurrency": 2, "testMode": 2, "subscription": "https://raw.githubusercontent.com/freefq/free/master/v2", "timeout": 16, "language": "en", "fontSize": 24, "theme": "rainbow", "generatePicMode": 3}' > config.json + echo '{"group": "cronjob", "speedtestMode": "all", "pingMethod": "googleping", "sortMethod": "rspeed", "concurrency": 2, "testMode": 2, "subscription": "https://raw.githubusercontent.com/freefq/free/master/v2", "timeout": 16, "language": "en", "fontSize": 24, "theme": "rainbow", "outputMode": 3}' > config.json ./lite --config config.json --test https://raw.githubusercontent.com/freefq/free/master/v2 ls diff --git a/config.json b/config.json index bebfabf..79e2e7f 100644 --- a/config.json +++ b/config.json @@ -10,5 +10,5 @@ "language":"en", "fontSize":24, "theme":"rainbow", - "generatePicMode": 1 + "outputMode": 1 } \ No newline at end of file From e5cc6b9f4b552b0955329b04560fe303a794b765 Mon Sep 17 00:00:00 2001 From: xxf098 Date: Sat, 8 Apr 2023 05:32:16 -0400 Subject: [PATCH 37/43] update go version --- docker/Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docker/Dockerfile b/docker/Dockerfile index c4e4636..e5225d0 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,5 +1,5 @@ # sudo docker build --network=host -t lite:0.1 -f ./docker/Dockerfile ./ -FROM golang:1.18 as wasm +FROM golang:1.19 as wasm ADD / /wasm/lite WORKDIR /wasm/lite RUN cp $(go env GOROOT)/misc/wasm/wasm_exec.js ./web/gui/wasm_exec.js @@ -11,7 +11,7 @@ COPY --from=wasm /wasm/lite/web/gui/wasm_exec.js /gui/lite/web/gui/wasm_exec.js RUN npm install --prefix web/gui build RUN npm run --prefix web/gui build -FROM golang:1.18 as build +FROM golang:1.19 as build ADD / /go/lite WORKDIR /go/lite COPY --from=gui /gui/lite/web/gui/dist/ /go/lite/web/gui/dist From b45f502c70f8d9c32845487e30fc6d6b2eb479cc Mon Sep 17 00:00:00 2001 From: xxf098 Date: Sat, 8 Apr 2023 08:39:24 -0400 Subject: [PATCH 38/43] only save working node --- web/profile.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/web/profile.go b/web/profile.go index 5cae990..59574c8 100644 --- a/web/profile.go +++ b/web/profile.go @@ -584,7 +584,9 @@ func (p *ProfileTest) saveJSON(nodes render.Nodes, traffic int64, duration strin func (p *ProfileTest) saveText(nodes render.Nodes) error { links := []string{} for _, node := range nodes { - links = append(links, node.Link) + if node.Ping != "0" || node.AvgSpeed > 0 || node.MaxSpeed > 0 { + links = append(links, node.Link) + } } data := []byte(strings.Join(links, "\n")) return ioutil.WriteFile("output.txt", data, 0644) From db120b5031629f28294fdf5861dd9961c7617f90 Mon Sep 17 00:00:00 2001 From: xxf098 Date: Sat, 15 Apr 2023 22:51:30 -0400 Subject: [PATCH 39/43] init slice --- web/profile.go | 4 ++-- web/render/table.go | 2 +- web/server.go | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/web/profile.go b/web/profile.go index 59574c8..dd3bbec 100644 --- a/web/profile.go +++ b/web/profile.go @@ -192,7 +192,7 @@ func parseClashProxies(input string) ([]string, error) { func scanClashProxies(r io.Reader, greedy bool) ([]string, error) { proxiesStart := false - data := []byte{} + var data []byte scanner := bufio.NewScanner(r) for scanner.Scan() { b := scanner.Bytes() @@ -582,7 +582,7 @@ func (p *ProfileTest) saveJSON(nodes render.Nodes, traffic int64, duration strin } func (p *ProfileTest) saveText(nodes render.Nodes) error { - links := []string{} + var links []string for _, node := range nodes { if node.Ping != "0" || node.AvgSpeed > 0 || node.MaxSpeed > 0 { links = append(links, node.Link) diff --git a/web/render/table.go b/web/render/table.go index 1ff787d..0a78373 100644 --- a/web/render/table.go +++ b/web/render/table.go @@ -79,7 +79,7 @@ type Node struct { func getNodeHeaders(language string) ([]string, map[string]string) { kvs := map[string]string{} - keys := []string{} + var keys []string t := reflect.TypeOf(Node{}) for i := 0; i < t.NumField(); i++ { f := t.Field(i) diff --git a/web/server.go b/web/server.go index ed815ad..3b78348 100644 --- a/web/server.go +++ b/web/server.go @@ -417,7 +417,7 @@ func writeShadowrocket(data []byte) ([]byte, error) { if err != nil { return nil, err } - newLinks := []string{} + var newLinks []string for _, link := range links { if strings.HasPrefix(link, "vmess://") && strings.Contains(link, "&") { if newLink, err := config.ShadowrocketLinkToVmessLink(link); err == nil { From cec67c5646deef50b690c3432db18cea0c766b7a Mon Sep 17 00:00:00 2001 From: xxf098 Date: Sat, 15 Apr 2023 22:55:08 -0400 Subject: [PATCH 40/43] make new slice --- web/server.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/server.go b/web/server.go index 3b78348..1a167b6 100644 --- a/web/server.go +++ b/web/server.go @@ -417,7 +417,7 @@ func writeShadowrocket(data []byte) ([]byte, error) { if err != nil { return nil, err } - var newLinks []string + newLinks := make([]string, 0, len(links)) for _, link := range links { if strings.HasPrefix(link, "vmess://") && strings.Contains(link, "&") { if newLink, err := config.ShadowrocketLinkToVmessLink(link); err == nil { From 2efe376c38dd432896a4e830d490c32dc0918a16 Mon Sep 17 00:00:00 2001 From: xxf098 Date: Tue, 18 Apr 2023 10:28:26 -0400 Subject: [PATCH 41/43] =?UTF-8?q?=E8=8A=82=E7=82=B9=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web/gui/src/App.vue | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/web/gui/src/App.vue b/web/gui/src/App.vue index 977d67e..c496a22 100644 --- a/web/gui/src/App.vue +++ b/web/gui/src/App.vue @@ -1054,8 +1054,7 @@ export default { break; case "eof": this.loading = false; - this.$notify.success("测试完成"); - console.log(this.result) + this.$notify.success(`${this.result.length}个节点测试完成`); break; case "retest": item = this.result[id]; From fc02e14752f38c6884b4765c3a939b5f79145ab4 Mon Sep 17 00:00:00 2001 From: xxf098 Date: Sat, 22 Apr 2023 00:08:49 -0400 Subject: [PATCH 42/43] update readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1bf964b..fcfaaff 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ Run as a speed test tool: ./lite -p 10889 # test in command line only mode - ./lite --test https://raw.githubusercontent.com/freefq/free/master/v2 + ./lite --config ./config.json --test https://raw.githubusercontent.com/freefq/free/master/v2 # test in command line only mode with custom config. # details can find here https://github.com/xxf098/LiteSpeedTest/blob/master/config.json # all config options: From 6669d9364fe33eb31267d86b5cd38e67c4c32ae5 Mon Sep 17 00:00:00 2001 From: xxf098 Date: Sat, 22 Apr 2023 03:46:05 -0400 Subject: [PATCH 43/43] update v0.15.0 --- README.md | 4 ++-- constant/version.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index fcfaaff..e16be50 100644 --- a/README.md +++ b/README.md @@ -21,8 +21,9 @@ Run as a speed test tool: ./lite -p 10889 # test in command line only mode - ./lite --config ./config.json --test https://raw.githubusercontent.com/freefq/free/master/v2 + ./lite --test https://raw.githubusercontent.com/freefq/free/master/v2 # test in command line only mode with custom config. + ./lite --config config.json --test https://raw.githubusercontent.com/freefq/free/master/v2 # details can find here https://github.com/xxf098/LiteSpeedTest/blob/master/config.json # all config options: # "group":"job", // group name @@ -38,7 +39,6 @@ Run as a speed test tool: # "unique": true, // remove duplicated value # "theme":"rainbow", # "outputMode": 1 // 0: base64 1: pic path 2: no pic 3: json 4: txt - ./lite --config config.json --test https://raw.githubusercontent.com/freefq/free/master/v2 Run as a grpc server: diff --git a/constant/version.go b/constant/version.go index 45c4505..6c5a45e 100644 --- a/constant/version.go +++ b/constant/version.go @@ -1,6 +1,6 @@ package constant var ( - Version = "v0.14.0" + Version = "v0.15.0" BuildTime = "unknown time" )