fix(waf): handle empty rule bindings

Encode empty site bindings as arrays and normalize legacy JSON null values in the OpenResty runtime to prevent request-time Lua failures.
This commit is contained in:
ryan
2026-07-13 16:43:02 +08:00
parent 0c2961ae6d
commit 46941f65d5
9 changed files with 62 additions and 12 deletions
@@ -223,6 +223,8 @@ func TestBuildCurrentConfigBundleEnablesGlobalPoWWithoutExplicitBinding(t *testi
continue
}
foundWAFConfig = true
assert.Contains(t, file.Content, `"rule_group_ids":[]`)
assert.NotContains(t, file.Content, `"rule_group_ids":null`)
require.NoError(t, json.Unmarshal([]byte(file.Content), &wafRuntime))
}
require.True(t, foundWAFConfig, "expected rendered WAF support file")
@@ -370,7 +370,7 @@ func buildSnapshotWAFDocument(ctx context.Context, routes []*model.ProxyRoute) (
bindings = append(bindings, snapshotWAFBinding{
RouteID: routeID,
SiteName: siteName,
RuleGroupIDs: groupIDsByRoute[routeID],
RuleGroupIDs: nonNilUintSlice(groupIDsByRoute[routeID]),
})
}
sort.Slice(bindings, func(i, j int) bool {
@@ -382,6 +382,13 @@ func buildSnapshotWAFDocument(ctx context.Context, routes []*model.ProxyRoute) (
return snapshotWAFDocument{RuleGroups: ruleGroups, IPGroups: ipGroups, Bindings: bindings}, nil
}
func nonNilUintSlice(values []uint) []uint {
if values == nil {
return make([]uint, 0)
}
return values
}
func validateSnapshotWAFIPGroupSize(groups []snapshotWAFIPGroup) error {
runtimeGroups := make(map[string]protocol.WAFIPGroup, len(groups))
for _, group := range groups {
@@ -85,6 +85,26 @@ func TestWAFGraphSnapshotPreservesOrderAndGraphReferences(t *testing.T) {
assert.NotContains(t, string(raw), "ip_whitelist")
}
func TestWAFGraphSnapshotEncodesEmptyBindingsAsArrays(t *testing.T) {
cleanup := setupConfigVersionTestDB(t)
defer cleanup()
ctx := context.Background()
route := &model.ProxyRoute{SiteName: "empty-binding.example.com", OriginURL: "http://origin:8080", Upstreams: `["http://origin:8080"]`, Enabled: true}
require.NoError(t, model.CreateProxyRouteRecord(ctx, route))
createSnapshotZoneDomains(t, ctx, route, route.SiteName)
snapshot, err := buildSnapshotWAFDocument(ctx, []*model.ProxyRoute{route})
require.NoError(t, err)
require.Len(t, snapshot.Bindings, 1)
require.NotNil(t, snapshot.Bindings[0].RuleGroupIDs)
raw, err := json.Marshal(snapshot)
require.NoError(t, err)
assert.Contains(t, string(raw), `"rule_group_ids":[]`)
assert.NotContains(t, string(raw), `"rule_group_ids":null`)
}
func TestBuildSnapshotRejectsInvalidWAFGraph(t *testing.T) {
cleanup := setupConfigVersionTestDB(t)
defer cleanup()