feat: support subscription tag and subtag filter (#13)

This commit is contained in:
mzz
2023-02-10 11:04:16 +08:00
committed by GitHub
parent 636b749776
commit c54a5a0c30
9 changed files with 89 additions and 37 deletions

View File

@ -94,7 +94,7 @@ func resolveFile(u *url.URL, configDir string) (b []byte, err error) {
if err = common.EnsureFileInSubDir(path, configDir); err != nil {
return nil, err
}
/// Read and resolve
/// Read and resolve.
f, err := os.Open(path)
if err != nil {
return nil, err
@ -131,10 +131,25 @@ func resolveFile(u *url.URL, configDir string) (b []byte, err error) {
return bytes.TrimSpace(b), err
}
func ResolveSubscription(log *logrus.Logger, configDir string, subscription string) (nodes []string, err error) {
func ResolveSubscription(log *logrus.Logger, configDir string, subscription string) (tag string, nodes []string, err error) {
/// Get tag.
iColon := strings.Index(subscription, ":")
if iColon == -1 {
goto parseUrl
}
// If first colon is like "://" in "scheme://linkbody", no tag is present.
if strings.HasPrefix(subscription[iColon:], "://") {
goto parseUrl
}
// Else tag is the part before colon.
tag = subscription[:iColon]
subscription = subscription[iColon+1:]
/// Parse url.
parseUrl:
u, err := url.Parse(subscription)
if err != nil {
return nil, fmt.Errorf("failed to parse subscription \"%v\": %w", subscription, err)
return tag, nil, fmt.Errorf("failed to parse subscription \"%v\": %w", subscription, err)
}
log.Debugf("ResolveSubscription: %v", subscription)
var (
@ -145,25 +160,25 @@ func ResolveSubscription(log *logrus.Logger, configDir string, subscription stri
case "file":
b, err = resolveFile(u, configDir)
if err != nil {
return nil, err
return "", nil, err
}
goto resolve
default:
}
resp, err = http.Get(subscription)
if err != nil {
return nil, err
return "", nil, err
}
defer resp.Body.Close()
b, err = io.ReadAll(resp.Body)
if err != nil {
return nil, err
return "", nil, err
}
resolve:
if nodes, err = resolveSubscriptionAsSIP008(log, b); err == nil {
return nodes, nil
return tag, nodes, nil
} else {
log.Debugln(err)
}
return resolveSubscriptionAsBase64(log, b), nil
return tag, resolveSubscriptionAsBase64(log, b), nil
}

View File

@ -54,17 +54,22 @@ func init() {
func Run(log *logrus.Logger, param *config.Params) (err error) {
/// Get tag -> nodeList mapping.
tagToNodeList := map[string][]string{}
if len(param.Node) > 0 {
tagToNodeList[""] = append(tagToNodeList[""], param.Node...)
}
// Resolve subscriptions to nodes.
nodeList := make([]string, len(param.Node))
copy(nodeList, param.Node)
for _, sub := range param.Subscription {
nodes, err := internal.ResolveSubscription(log, filepath.Dir(cfgFile), sub)
tag, nodes, err := internal.ResolveSubscription(log, filepath.Dir(cfgFile), sub)
if err != nil {
log.Warnf(`failed to resolve subscription "%v": %v`, sub, err)
}
nodeList = append(nodeList, nodes...)
if len(nodes) > 0 {
tagToNodeList[tag] = append(tagToNodeList[tag], nodes...)
}
}
if len(nodeList) == 0 {
if len(tagToNodeList) == 0 {
return fmt.Errorf("no node found, which could because all subscription resolving failed")
}
@ -75,7 +80,7 @@ func Run(log *logrus.Logger, param *config.Params) (err error) {
// New ControlPlane.
t, err := control.NewControlPlane(
log,
nodeList,
tagToNodeList,
param.Group,
&param.Routing,
&param.Global,