fix: resolve padding_scheme decode error in WebSocket config sync
This commit is contained in:
@@ -8,6 +8,7 @@ import (
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
@@ -145,19 +146,31 @@ func (c *Client) Report(traffic map[int][2]int64, alive map[int][]string, online
|
||||
}
|
||||
|
||||
// decodeWeakRaw decodes an interface (from JSON map) into a struct using weak type conversion.
|
||||
func decodeWeakRaw(input interface{}, output interface{}) error {
|
||||
func decodeWeakRaw(input map[string]interface{}, output interface{}) error {
|
||||
config := &mapstructure.DecoderConfig{
|
||||
Metadata: nil,
|
||||
Result: output,
|
||||
WeaklyTypedInput: true,
|
||||
TagName: "json", // Follow JSON tags
|
||||
TagName: "json",
|
||||
DecodeHook: mapstructure.ComposeDecodeHookFunc(
|
||||
func(f, t reflect.Type, v interface{}) (interface{}, error) {
|
||||
// Handle []interface{} -> StringOrArray
|
||||
if t == reflect.TypeOf(StringOrArray("")) && f.Kind() == reflect.Slice {
|
||||
arr, _ := v.([]interface{})
|
||||
var strs []string
|
||||
for _, x := range arr {
|
||||
if s, ok := x.(string); ok {
|
||||
strs = append(strs, s)
|
||||
}
|
||||
|
||||
decoder, err := mapstructure.NewDecoder(config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return StringOrArray(strings.Join(strs, "\n")), nil
|
||||
}
|
||||
return v, nil
|
||||
},
|
||||
mapstructure.StringToSliceHookFunc(","),
|
||||
),
|
||||
}
|
||||
decoder, _ := mapstructure.NewDecoder(config)
|
||||
return decoder.Decode(input)
|
||||
}
|
||||
|
||||
|
||||
@@ -293,3 +293,45 @@ func TestClient_NodeTypeInQuery(t *testing.T) {
|
||||
})
|
||||
client.GetConfig()
|
||||
}
|
||||
|
||||
func TestStringOrArrayDecodeHook(t *testing.T) {
|
||||
// Test case: []interface{} -> StringOrArray
|
||||
input := map[string]interface{}{
|
||||
"padding_scheme": []interface{}{"stop=8", "0=30-30", "1=100-400"},
|
||||
}
|
||||
|
||||
type TestConfig struct {
|
||||
PaddingScheme StringOrArray `json:"padding_scheme"`
|
||||
}
|
||||
|
||||
var cfg TestConfig
|
||||
if err := decodeWeakRaw(input, &cfg); err != nil {
|
||||
t.Fatalf("decodeWeakRaw failed: %v", err)
|
||||
}
|
||||
|
||||
want := "stop=8\n0=30-30\n1=100-400"
|
||||
if string(cfg.PaddingScheme) != want {
|
||||
t.Errorf("got %q, want %q", cfg.PaddingScheme, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStringOrArrayDecodeHook_String(t *testing.T) {
|
||||
// Test case: string -> StringOrArray
|
||||
input := map[string]interface{}{
|
||||
"padding_scheme": "stop=8\n0=30-30",
|
||||
}
|
||||
|
||||
type TestConfig struct {
|
||||
PaddingScheme StringOrArray `json:"padding_scheme"`
|
||||
}
|
||||
|
||||
var cfg TestConfig
|
||||
if err := decodeWeakRaw(input, &cfg); err != nil {
|
||||
t.Fatalf("decodeWeakRaw failed: %v", err)
|
||||
}
|
||||
|
||||
want := "stop=8\n0=30-30"
|
||||
if string(cfg.PaddingScheme) != want {
|
||||
t.Errorf("got %q, want %q", cfg.PaddingScheme, want)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -303,7 +303,7 @@ func (w *WSClient) handleDataEvent(msg wsMessage) {
|
||||
|
||||
// Helper to unmarshal and decode with weak Typing
|
||||
decodeData := func(data []byte, target interface{}) error {
|
||||
var raw any
|
||||
var raw map[string]interface{}
|
||||
if err := json.Unmarshal(data, &raw); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user