feat(webrtc): add Config with defaults and validation
This commit is contained in:
parent
7ea1844869
commit
2250cb0a8f
2 changed files with 107 additions and 0 deletions
59
core/webrtc/config.go
Normal file
59
core/webrtc/config.go
Normal file
|
|
@ -0,0 +1,59 @@
|
||||||
|
package webrtc
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
// PortRange represents an inclusive UDP port range.
|
||||||
|
type PortRange struct {
|
||||||
|
Low, High int
|
||||||
|
}
|
||||||
|
|
||||||
|
// Config controls the WebRTC egress module.
|
||||||
|
type Config struct {
|
||||||
|
// Enabled toggles the entire module. When false, no endpoints are served.
|
||||||
|
Enabled bool
|
||||||
|
|
||||||
|
// WHEPListen is the address the WHEP HTTP endpoint binds to (e.g. ":8787").
|
||||||
|
WHEPListen string
|
||||||
|
|
||||||
|
// PublicIP is the server's externally-reachable IP, advertised in ICE
|
||||||
|
// candidates via NAT1To1. Empty means rely on STUN discovery.
|
||||||
|
PublicIP string
|
||||||
|
|
||||||
|
// UDPPortRange bounds the local UDP ports allocated for FFmpeg→Pion RTP.
|
||||||
|
UDPPortRange PortRange
|
||||||
|
|
||||||
|
// ICEServers is the list of STUN/TURN URIs given to each PeerConnection.
|
||||||
|
ICEServers []string
|
||||||
|
|
||||||
|
// MaxPeersTotal is a hard safety cap on concurrent subscribers.
|
||||||
|
MaxPeersTotal int
|
||||||
|
}
|
||||||
|
|
||||||
|
// DefaultConfig returns production-reasonable defaults.
|
||||||
|
func DefaultConfig() Config {
|
||||||
|
return Config{
|
||||||
|
Enabled: true,
|
||||||
|
WHEPListen: ":8787",
|
||||||
|
PublicIP: "",
|
||||||
|
UDPPortRange: PortRange{Low: 10000, High: 10100},
|
||||||
|
ICEServers: []string{"stun:stun.cloudflare.com:3478", "stun:stun.l.google.com:19302"},
|
||||||
|
MaxPeersTotal: 32,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate returns an error if the config is internally inconsistent.
|
||||||
|
func (c Config) Validate() error {
|
||||||
|
if c.WHEPListen == "" {
|
||||||
|
return fmt.Errorf("webrtc: WHEPListen must not be empty")
|
||||||
|
}
|
||||||
|
if c.UDPPortRange.Low <= 0 || c.UDPPortRange.High <= 0 {
|
||||||
|
return fmt.Errorf("webrtc: UDPPortRange must have positive bounds, got %v", c.UDPPortRange)
|
||||||
|
}
|
||||||
|
if c.UDPPortRange.Low > c.UDPPortRange.High {
|
||||||
|
return fmt.Errorf("webrtc: UDPPortRange.Low > High (%d > %d)", c.UDPPortRange.Low, c.UDPPortRange.High)
|
||||||
|
}
|
||||||
|
if c.MaxPeersTotal <= 0 {
|
||||||
|
return fmt.Errorf("webrtc: MaxPeersTotal must be positive, got %d", c.MaxPeersTotal)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
48
core/webrtc/config_test.go
Normal file
48
core/webrtc/config_test.go
Normal file
|
|
@ -0,0 +1,48 @@
|
||||||
|
package webrtc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestConfig_Defaults(t *testing.T) {
|
||||||
|
c := DefaultConfig()
|
||||||
|
if !c.Enabled {
|
||||||
|
t.Error("default Enabled should be true")
|
||||||
|
}
|
||||||
|
if c.WHEPListen != ":8787" {
|
||||||
|
t.Errorf("default WHEPListen = %q, want :8787", c.WHEPListen)
|
||||||
|
}
|
||||||
|
if c.UDPPortRange.Low != 10000 || c.UDPPortRange.High != 10100 {
|
||||||
|
t.Errorf("default UDPPortRange = %v, want 10000-10100", c.UDPPortRange)
|
||||||
|
}
|
||||||
|
if c.MaxPeersTotal != 32 {
|
||||||
|
t.Errorf("default MaxPeersTotal = %d, want 32", c.MaxPeersTotal)
|
||||||
|
}
|
||||||
|
if len(c.ICEServers) == 0 {
|
||||||
|
t.Error("default ICEServers should have at least one STUN entry")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestConfig_Validate(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
mutate func(*Config)
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
{"defaults are valid", func(c *Config) {}, false},
|
||||||
|
{"empty listen", func(c *Config) { c.WHEPListen = "" }, true},
|
||||||
|
{"inverted port range", func(c *Config) { c.UDPPortRange.Low = 20000; c.UDPPortRange.High = 10000 }, true},
|
||||||
|
{"zero max peers", func(c *Config) { c.MaxPeersTotal = 0 }, true},
|
||||||
|
{"negative max peers", func(c *Config) { c.MaxPeersTotal = -1 }, true},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
c := DefaultConfig()
|
||||||
|
tt.mutate(&c)
|
||||||
|
err := c.Validate()
|
||||||
|
if (err != nil) != tt.wantErr {
|
||||||
|
t.Errorf("Validate() err = %v, wantErr %v", err, tt.wantErr)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue