diff --git a/internal/config/config.go b/internal/config/config.go index 2b7954af..d4979076 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -256,6 +256,7 @@ func FromEnv() *Config { map[string]string{"url": "stun:stun.l.google.com:19302", "username": "", "credential": ""}, } } + iceServers = normalizeICEServers(iceServers) hashSchemaVersion := os.Getenv(envHashSchemaVersion) if hashSchemaVersion == "" { @@ -287,6 +288,74 @@ func FromEnv() *Config { return &cfg } +// normalizeICEServers expands "urls" arrays into singular "url" entries; xochitl rejects anything else +func normalizeICEServers(servers []interface{}) []interface{} { + normalized := make([]interface{}, 0, len(servers)) + for _, s := range servers { + m, ok := toStringMap(s) + if !ok { + normalized = append(normalized, s) + continue + } + _, hasURL := m["url"] + _, hasURLs := m["urls"] + urls := collectICEURLs(m) + if len(urls) == 0 { + if !hasURL && !hasURLs { + normalized = append(normalized, s) + } + continue + } + for _, u := range urls { + entry := map[string]interface{}{"url": u} + for k, v := range m { + if k == "url" || k == "urls" { + continue + } + entry[k] = v + } + normalized = append(normalized, entry) + } + } + return normalized +} + +func toStringMap(v interface{}) (map[string]interface{}, bool) { + switch t := v.(type) { + case map[string]interface{}: + return t, true + case map[string]string: + m := make(map[string]interface{}, len(t)) + for k, val := range t { + m[k] = val + } + return m, true + default: + return nil, false + } +} + +func collectICEURLs(m map[string]interface{}) []string { + var urls []string + add := func(v interface{}) { + switch t := v.(type) { + case string: + if t != "" { + urls = append(urls, t) + } + case []interface{}: + for _, item := range t { + if str, ok := item.(string); ok && str != "" { + urls = append(urls, str) + } + } + } + } + add(m["url"]) + add(m["urls"]) + return urls +} + // EnvVars env vars usage func EnvVars() string { return fmt.Sprintf(`