Make remote rule sets support multiple URLs

This commit is contained in:
MoonFruit 2024-04-02 11:06:53 +08:00
parent c5e620ed7b
commit 10d1733ceb
No known key found for this signature in database
GPG key ID: 86EE2A2C61AB27B3
3 changed files with 19 additions and 5 deletions

View file

@ -83,9 +83,9 @@ type LocalRuleSet struct {
}
type RemoteRuleSet struct {
URL string `json:"url"`
DownloadDetour string `json:"download_detour,omitempty"`
UpdateInterval Duration `json:"update_interval,omitempty"`
URL Listable[string] `json:"url"`
DownloadDetour string `json:"download_detour,omitempty"`
UpdateInterval Duration `json:"update_interval,omitempty"`
}
type _HeadlessRule struct {

View file

@ -23,6 +23,9 @@ func NewRuleSet(ctx context.Context, router adapter.Router, logger logger.Contex
case C.RuleSetTypeInline, C.RuleSetTypeLocal, "":
return NewLocalRuleSet(router, logger, options)
case C.RuleSetTypeRemote:
if len(options.RemoteOptions.URL) == 0 {
return nil, E.New("missing urls")
}
return NewRemoteRuleSet(ctx, router, logger, options), nil
default:
return nil, E.New("unknown rule-set type: ", options.Type)

View file

@ -227,7 +227,18 @@ func (s *RemoteRuleSet) loopUpdate() {
}
func (s *RemoteRuleSet) fetchOnce(ctx context.Context, startContext adapter.RuleSetStartContext) error {
s.logger.Debug("updating rule-set ", s.options.Tag, " from URL: ", s.options.RemoteOptions.URL)
var err error
for _, url := range s.options.RemoteOptions.URL {
err = s.fetchURL(ctx, url, startContext)
if err == nil {
return nil
}
}
return err
}
func (s *RemoteRuleSet) fetchURL(ctx context.Context, url string, startContext adapter.RuleSetStartContext) error {
s.logger.Debug("updating rule-set ", s.options.Tag, " from URL: ", url)
var httpClient *http.Client
if startContext != nil {
httpClient = startContext.HTTPClient(s.options.RemoteOptions.DownloadDetour, s.dialer)
@ -242,7 +253,7 @@ func (s *RemoteRuleSet) fetchOnce(ctx context.Context, startContext adapter.Rule
},
}
}
request, err := http.NewRequest("GET", s.options.RemoteOptions.URL, nil)
request, err := http.NewRequest("GET", url, nil)
if err != nil {
return err
}