Make rule_set.format optional

This commit is contained in:
世界 2025-05-01 11:00:01 +08:00
parent d574e9eb52
commit af1bfe4e3e
No known key found for this signature in database
GPG Key ID: CD109927C34A63C4
4 changed files with 53 additions and 4 deletions

View File

@ -5,6 +5,7 @@ import (
"context" "context"
"io" "io"
"os" "os"
"path/filepath"
"github.com/sagernet/sing-box/adapter" "github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/common/srs" "github.com/sagernet/sing-box/common/srs"
@ -56,6 +57,14 @@ func ruleSetMatch(sourcePath string, domain string) error {
if err != nil { if err != nil {
return E.Cause(err, "read rule-set") return E.Cause(err, "read rule-set")
} }
if flagRuleSetMatchFormat == "" {
switch filepath.Ext(sourcePath) {
case ".json":
flagRuleSetMatchFormat = C.RuleSetFormatSource
case ".srs":
flagRuleSetMatchFormat = C.RuleSetFormatBinary
}
}
var ruleSet option.PlainRuleSetCompat var ruleSet option.PlainRuleSetCompat
switch flagRuleSetMatchFormat { switch flagRuleSetMatchFormat {
case C.RuleSetFormatSource: case C.RuleSetFormatSource:

View File

@ -84,6 +84,8 @@ List of [Headless Rule](./headless-rule/).
Format of rule-set file, `source` or `binary`. Format of rule-set file, `source` or `binary`.
Optional when `path` or `url` uses `json` or `srs` as extension.
### Local Fields ### Local Fields
#### path #### path

View File

@ -84,6 +84,8 @@ icon: material/new-box
规则集格式, `source``binary` 规则集格式, `source``binary`
`path``url` 使用 `json``srs` 作为扩展名时可选。
### 本地字段 ### 本地字段
#### path #### path

View File

@ -1,6 +1,8 @@
package option package option
import ( import (
"net/url"
"path/filepath"
"reflect" "reflect"
C "github.com/sagernet/sing-box/constant" C "github.com/sagernet/sing-box/constant"
@ -27,6 +29,18 @@ type _RuleSet struct {
type RuleSet _RuleSet type RuleSet _RuleSet
func (r RuleSet) MarshalJSON() ([]byte, error) { func (r RuleSet) MarshalJSON() ([]byte, error) {
if r.Type != C.RuleSetTypeInline {
var defaultFormat string
switch r.Type {
case C.RuleSetTypeLocal:
defaultFormat = ruleSetDefaultFormat(r.LocalOptions.Path)
case C.RuleSetTypeRemote:
defaultFormat = ruleSetDefaultFormat(r.RemoteOptions.URL)
}
if r.Format == defaultFormat {
r.Format = ""
}
}
var v any var v any
switch r.Type { switch r.Type {
case "", C.RuleSetTypeInline: case "", C.RuleSetTypeInline:
@ -62,7 +76,19 @@ func (r *RuleSet) UnmarshalJSON(bytes []byte) error {
default: default:
return E.New("unknown rule-set type: " + r.Type) return E.New("unknown rule-set type: " + r.Type)
} }
err = badjson.UnmarshallExcluded(bytes, (*_RuleSet)(r), v)
if err != nil {
return err
}
if r.Type != C.RuleSetTypeInline { if r.Type != C.RuleSetTypeInline {
if r.Format == "" {
switch r.Type {
case C.RuleSetTypeLocal:
r.Format = ruleSetDefaultFormat(r.LocalOptions.Path)
case C.RuleSetTypeRemote:
r.Format = ruleSetDefaultFormat(r.RemoteOptions.URL)
}
}
switch r.Format { switch r.Format {
case "": case "":
return E.New("missing format") return E.New("missing format")
@ -73,13 +99,23 @@ func (r *RuleSet) UnmarshalJSON(bytes []byte) error {
} else { } else {
r.Format = "" r.Format = ""
} }
err = badjson.UnmarshallExcluded(bytes, (*_RuleSet)(r), v)
if err != nil {
return err
}
return nil return nil
} }
func ruleSetDefaultFormat(path string) string {
if pathURL, err := url.Parse(path); err == nil {
path = pathURL.Path
}
switch filepath.Ext(path) {
case ".json":
return C.RuleSetFormatSource
case ".srs":
return C.RuleSetFormatBinary
default:
return ""
}
}
type LocalRuleSet struct { type LocalRuleSet struct {
Path string `json:"path,omitempty"` Path string `json:"path,omitempty"`
} }