fix: resolve padding_scheme decode error in WebSocket config sync
This commit is contained in:
@@ -8,6 +8,7 @@ import (
|
|||||||
"log/slog"
|
"log/slog"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
"reflect"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"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.
|
// 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{
|
config := &mapstructure.DecoderConfig{
|
||||||
Metadata: nil,
|
Metadata: nil,
|
||||||
Result: output,
|
Result: output,
|
||||||
WeaklyTypedInput: true,
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return StringOrArray(strings.Join(strs, "\n")), nil
|
||||||
|
}
|
||||||
|
return v, nil
|
||||||
|
},
|
||||||
|
mapstructure.StringToSliceHookFunc(","),
|
||||||
|
),
|
||||||
}
|
}
|
||||||
|
decoder, _ := mapstructure.NewDecoder(config)
|
||||||
decoder, err := mapstructure.NewDecoder(config)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return decoder.Decode(input)
|
return decoder.Decode(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -293,3 +293,45 @@ func TestClient_NodeTypeInQuery(t *testing.T) {
|
|||||||
})
|
})
|
||||||
client.GetConfig()
|
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
|
// Helper to unmarshal and decode with weak Typing
|
||||||
decodeData := func(data []byte, target interface{}) error {
|
decodeData := func(data []byte, target interface{}) error {
|
||||||
var raw any
|
var raw map[string]interface{}
|
||||||
if err := json.Unmarshal(data, &raw); err != nil {
|
if err := json.Unmarshal(data, &raw); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user