Simplify nested action validation and fix FallbackNetworkType bug

- Rename nested_action.go to rule_nested_action.go for naming consistency
- Export error message constants from option package to deduplicate
- Fix RuleActionRouteOptions.Descriptions using wrong field for fallback-network-type
This commit is contained in:
世界
2026-04-01 13:22:54 +08:00
parent 9e95438463
commit 3036955776
5 changed files with 23 additions and 28 deletions

View File

@@ -13,8 +13,8 @@ import (
type nestedRuleDepthContextKey struct{}
const (
routeRuleActionNestedUnsupportedMessage = "rule action is not supported in nested rules"
dnsRuleActionNestedUnsupportedMessage = "DNS rule action is not supported in nested rules"
RouteRuleActionNestedUnsupportedMessage = "rule action is not supported in nested rules"
DNSRuleActionNestedUnsupportedMessage = "DNS rule action is not supported in nested rules"
)
var (
@@ -27,11 +27,11 @@ func nestedRuleChildContext(ctx context.Context) context.Context {
}
func rejectNestedRouteRuleAction(ctx context.Context, content []byte) error {
return rejectNestedRuleAction(ctx, content, routeRuleActionKeys, routeRuleActionNestedUnsupportedMessage)
return rejectNestedRuleAction(ctx, content, routeRuleActionKeys, RouteRuleActionNestedUnsupportedMessage)
}
func rejectNestedDNSRuleAction(ctx context.Context, content []byte) error {
return rejectNestedRuleAction(ctx, content, dnsRuleActionKeys, dnsRuleActionNestedUnsupportedMessage)
return rejectNestedRuleAction(ctx, content, dnsRuleActionKeys, DNSRuleActionNestedUnsupportedMessage)
}
func nestedRuleDepth(ctx context.Context) int {

View File

@@ -21,7 +21,7 @@ func TestRuleRejectsNestedDefaultRuleAction(t *testing.T) {
{"domain": "example.com", "outbound": "direct"}
]
}`), &rule)
require.ErrorContains(t, err, routeRuleActionNestedUnsupportedMessage)
require.ErrorContains(t, err, RouteRuleActionNestedUnsupportedMessage)
}
func TestRuleRejectsNestedLogicalRuleAction(t *testing.T) {
@@ -41,7 +41,7 @@ func TestRuleRejectsNestedLogicalRuleAction(t *testing.T) {
}
]
}`), &rule)
require.ErrorContains(t, err, routeRuleActionNestedUnsupportedMessage)
require.ErrorContains(t, err, RouteRuleActionNestedUnsupportedMessage)
}
func TestRuleRejectsNestedDefaultRuleZeroValueOutbound(t *testing.T) {
@@ -55,7 +55,7 @@ func TestRuleRejectsNestedDefaultRuleZeroValueOutbound(t *testing.T) {
{"domain": "example.com", "outbound": ""}
]
}`), &rule)
require.ErrorContains(t, err, routeRuleActionNestedUnsupportedMessage)
require.ErrorContains(t, err, RouteRuleActionNestedUnsupportedMessage)
}
func TestRuleRejectsNestedDefaultRuleZeroValueRouteOption(t *testing.T) {
@@ -69,7 +69,7 @@ func TestRuleRejectsNestedDefaultRuleZeroValueRouteOption(t *testing.T) {
{"domain": "example.com", "udp_connect": false}
]
}`), &rule)
require.ErrorContains(t, err, routeRuleActionNestedUnsupportedMessage)
require.ErrorContains(t, err, RouteRuleActionNestedUnsupportedMessage)
}
func TestRuleRejectsNestedLogicalRuleZeroValueAction(t *testing.T) {
@@ -88,7 +88,7 @@ func TestRuleRejectsNestedLogicalRuleZeroValueAction(t *testing.T) {
}
]
}`), &rule)
require.ErrorContains(t, err, routeRuleActionNestedUnsupportedMessage)
require.ErrorContains(t, err, RouteRuleActionNestedUnsupportedMessage)
}
func TestRuleRejectsNestedLogicalRuleZeroValueRouteOption(t *testing.T) {
@@ -107,7 +107,7 @@ func TestRuleRejectsNestedLogicalRuleZeroValueRouteOption(t *testing.T) {
}
]
}`), &rule)
require.ErrorContains(t, err, routeRuleActionNestedUnsupportedMessage)
require.ErrorContains(t, err, RouteRuleActionNestedUnsupportedMessage)
}
func TestRuleAllowsTopLevelLogicalAction(t *testing.T) {
@@ -137,7 +137,7 @@ func TestRuleLeavesUnknownNestedKeysToNormalValidation(t *testing.T) {
]
}`), &rule)
require.ErrorContains(t, err, "unknown field")
require.NotContains(t, err.Error(), routeRuleActionNestedUnsupportedMessage)
require.NotContains(t, err.Error(), RouteRuleActionNestedUnsupportedMessage)
}
func TestDNSRuleRejectsNestedDefaultRuleAction(t *testing.T) {
@@ -151,7 +151,7 @@ func TestDNSRuleRejectsNestedDefaultRuleAction(t *testing.T) {
{"domain": "example.com", "server": "default"}
]
}`), &rule)
require.ErrorContains(t, err, dnsRuleActionNestedUnsupportedMessage)
require.ErrorContains(t, err, DNSRuleActionNestedUnsupportedMessage)
}
func TestDNSRuleRejectsNestedLogicalRuleAction(t *testing.T) {
@@ -171,7 +171,7 @@ func TestDNSRuleRejectsNestedLogicalRuleAction(t *testing.T) {
}
]
}`), &rule)
require.ErrorContains(t, err, dnsRuleActionNestedUnsupportedMessage)
require.ErrorContains(t, err, DNSRuleActionNestedUnsupportedMessage)
}
func TestDNSRuleRejectsNestedDefaultRuleZeroValueServer(t *testing.T) {
@@ -185,7 +185,7 @@ func TestDNSRuleRejectsNestedDefaultRuleZeroValueServer(t *testing.T) {
{"domain": "example.com", "server": ""}
]
}`), &rule)
require.ErrorContains(t, err, dnsRuleActionNestedUnsupportedMessage)
require.ErrorContains(t, err, DNSRuleActionNestedUnsupportedMessage)
}
func TestDNSRuleRejectsNestedDefaultRuleZeroValueRouteOption(t *testing.T) {
@@ -199,7 +199,7 @@ func TestDNSRuleRejectsNestedDefaultRuleZeroValueRouteOption(t *testing.T) {
{"domain": "example.com", "disable_cache": false}
]
}`), &rule)
require.ErrorContains(t, err, dnsRuleActionNestedUnsupportedMessage)
require.ErrorContains(t, err, DNSRuleActionNestedUnsupportedMessage)
}
func TestDNSRuleRejectsNestedLogicalRuleZeroValueAction(t *testing.T) {
@@ -218,7 +218,7 @@ func TestDNSRuleRejectsNestedLogicalRuleZeroValueAction(t *testing.T) {
}
]
}`), &rule)
require.ErrorContains(t, err, dnsRuleActionNestedUnsupportedMessage)
require.ErrorContains(t, err, DNSRuleActionNestedUnsupportedMessage)
}
func TestDNSRuleRejectsNestedLogicalRuleZeroValueRouteOption(t *testing.T) {
@@ -237,7 +237,7 @@ func TestDNSRuleRejectsNestedLogicalRuleZeroValueRouteOption(t *testing.T) {
}
]
}`), &rule)
require.ErrorContains(t, err, dnsRuleActionNestedUnsupportedMessage)
require.ErrorContains(t, err, DNSRuleActionNestedUnsupportedMessage)
}
func TestDNSRuleAllowsTopLevelLogicalAction(t *testing.T) {
@@ -267,5 +267,5 @@ func TestDNSRuleLeavesUnknownNestedKeysToNormalValidation(t *testing.T) {
]
}`), &rule)
require.ErrorContains(t, err, "unknown field")
require.NotContains(t, err.Error(), dnsRuleActionNestedUnsupportedMessage)
require.NotContains(t, err.Error(), DNSRuleActionNestedUnsupportedMessage)
}

View File

@@ -240,7 +240,7 @@ func (r *RuleActionRouteOptions) Descriptions() []string {
descriptions = append(descriptions, F.ToString("network-type=", strings.Join(common.Map(r.NetworkType, C.InterfaceType.String), ",")))
}
if r.FallbackNetworkType != nil {
descriptions = append(descriptions, F.ToString("fallback-network-type="+strings.Join(common.Map(r.NetworkType, C.InterfaceType.String), ",")))
descriptions = append(descriptions, F.ToString("fallback-network-type=", strings.Join(common.Map(r.FallbackNetworkType, C.InterfaceType.String), ",")))
}
if r.FallbackDelay > 0 {
descriptions = append(descriptions, F.ToString("fallback-delay=", r.FallbackDelay.String()))

View File

@@ -8,11 +8,6 @@ import (
E "github.com/sagernet/sing/common/exceptions"
)
const (
routeRuleActionNestedUnsupportedMessage = "rule action is not supported in nested rules"
dnsRuleActionNestedUnsupportedMessage = "DNS rule action is not supported in nested rules"
)
func ValidateNoNestedRuleActions(rule option.Rule) error {
return validateNoNestedRuleActions(rule, false)
}
@@ -23,7 +18,7 @@ func ValidateNoNestedDNSRuleActions(rule option.DNSRule) error {
func validateNoNestedRuleActions(rule option.Rule, nested bool) error {
if nested && ruleHasConfiguredAction(rule) {
return E.New(routeRuleActionNestedUnsupportedMessage)
return E.New(option.RouteRuleActionNestedUnsupportedMessage)
}
if rule.Type != C.RuleTypeLogical {
return nil
@@ -39,7 +34,7 @@ func validateNoNestedRuleActions(rule option.Rule, nested bool) error {
func validateNoNestedDNSRuleActions(rule option.DNSRule, nested bool) error {
if nested && dnsRuleHasConfiguredAction(rule) {
return E.New(dnsRuleActionNestedUnsupportedMessage)
return E.New(option.DNSRuleActionNestedUnsupportedMessage)
}
if rule.Type != C.RuleTypeLogical {
return nil

View File

@@ -68,7 +68,7 @@ func TestNewRuleRejectsNestedRuleAction(t *testing.T) {
},
},
}, false)
require.ErrorContains(t, err, routeRuleActionNestedUnsupportedMessage)
require.ErrorContains(t, err, option.RouteRuleActionNestedUnsupportedMessage)
}
func TestNewDNSRulePreservesImplicitTopLevelDefaultAction(t *testing.T) {
@@ -133,7 +133,7 @@ func TestNewDNSRuleRejectsNestedRuleAction(t *testing.T) {
},
},
}, true, false)
require.ErrorContains(t, err, dnsRuleActionNestedUnsupportedMessage)
require.ErrorContains(t, err, option.DNSRuleActionNestedUnsupportedMessage)
}
func TestNewDNSRuleRejectsReplyRejectMethod(t *testing.T) {