mirror of
https://github.com/SagerNet/sing-box.git
synced 2025-06-13 13:44:14 +08:00
extract link.ParseCollection
This commit is contained in:
parent
de46340e83
commit
05280d01b9
@ -1,7 +1,9 @@
|
||||
package link
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"github.com/sagernet/sing-box/option"
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
@ -34,3 +36,49 @@ func Parse(u *url.URL) (Link, error) {
|
||||
}
|
||||
return nil, E.Errors(errs...)
|
||||
}
|
||||
|
||||
// ParseCollection parses a links collection string to []Link
|
||||
func ParseCollection(content string) ([]Link, error) {
|
||||
content = doBase64DecodeOrNothing(content)
|
||||
links := make([]Link, 0)
|
||||
errs := make([]error, 0)
|
||||
for _, line := range strings.Split(content, "\n") {
|
||||
line = strings.TrimSpace(line)
|
||||
if line == "" {
|
||||
continue
|
||||
}
|
||||
u, err := url.Parse(line)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
link, err := Parse(u)
|
||||
if err != nil {
|
||||
errs = append(errs, err)
|
||||
continue
|
||||
}
|
||||
links = append(links, link)
|
||||
}
|
||||
return links, E.Errors(errs...)
|
||||
}
|
||||
|
||||
func doBase64DecodeOrNothing(s string) string {
|
||||
b, err := base64Decode(s)
|
||||
if err != nil {
|
||||
return s
|
||||
}
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func base64Decode(b64 string) ([]byte, error) {
|
||||
b64 = strings.TrimSpace(b64)
|
||||
stdb64 := b64
|
||||
if pad := len(b64) % 4; pad != 0 {
|
||||
stdb64 += strings.Repeat("=", 4-pad)
|
||||
}
|
||||
|
||||
b, err := base64.StdEncoding.DecodeString(stdb64)
|
||||
if err != nil {
|
||||
return base64.URLEncoding.DecodeString(b64)
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
package link
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strconv"
|
||||
@ -87,17 +86,3 @@ func (l *SSLink) Options() *option.Outbound {
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func base64Decode(b64 string) ([]byte, error) {
|
||||
b64 = strings.TrimSpace(b64)
|
||||
stdb64 := b64
|
||||
if pad := len(b64) % 4; pad != 0 {
|
||||
stdb64 += strings.Repeat("=", 4-pad)
|
||||
}
|
||||
|
||||
b, err := base64.StdEncoding.DecodeString(stdb64)
|
||||
if err != nil {
|
||||
return base64.URLEncoding.DecodeString(b64)
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
|
@ -2,12 +2,9 @@ package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/sagernet/sing-box/adapter"
|
||||
@ -144,63 +141,19 @@ func (s *Subscription) fetchProvider(client *http.Client, provider option.Subscr
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// try undecoded
|
||||
content := string(body)
|
||||
links, err := linksFromContent(content)
|
||||
links, err := link.ParseCollection(string(body))
|
||||
if len(links) > 0 {
|
||||
if err != nil {
|
||||
s.logger.Warn("some links failed", err)
|
||||
s.logger.Warn("links parsed with error:", err)
|
||||
}
|
||||
return links, nil
|
||||
}
|
||||
// try decoded
|
||||
decoded, err := base64Decode(content)
|
||||
links, err = linksFromContent(string(decoded))
|
||||
if len(links) > 0 {
|
||||
if err != nil {
|
||||
s.logger.Warn("some links failed", err)
|
||||
}
|
||||
return links, nil
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return nil, E.New("no links found")
|
||||
}
|
||||
|
||||
func linksFromContent(content string) ([]link.Link, error) {
|
||||
links := make([]link.Link, 0)
|
||||
errs := make([]error, 0)
|
||||
for _, line := range strings.Split(content, "\n") {
|
||||
line = strings.TrimSpace(line)
|
||||
if line == "" {
|
||||
continue
|
||||
}
|
||||
u, err := url.Parse(line)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
link, err := link.Parse(u)
|
||||
if err != nil {
|
||||
errs = append(errs, err)
|
||||
continue
|
||||
}
|
||||
links = append(links, link)
|
||||
}
|
||||
return links, E.Errors(errs...)
|
||||
}
|
||||
|
||||
func base64Decode(b64 string) ([]byte, error) {
|
||||
b64 = strings.TrimSpace(b64)
|
||||
stdb64 := b64
|
||||
if pad := len(b64) % 4; pad != 0 {
|
||||
stdb64 += strings.Repeat("=", 4-pad)
|
||||
}
|
||||
|
||||
b, err := base64.StdEncoding.DecodeString(stdb64)
|
||||
if err != nil {
|
||||
return base64.URLEncoding.DecodeString(b64)
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
|
||||
func (s *Subscription) client() (*http.Client, error) {
|
||||
var detour adapter.Outbound
|
||||
if s.options.DownloadDetour != "" {
|
||||
|
Loading…
x
Reference in New Issue
Block a user