mirror of
https://github.com/hackdiaz-dev/free-turn-proxy.git
synced 2026-10-12 09:41:53 +02:00
184 lines
5.7 KiB
Go
184 lines
5.7 KiB
Go
package config
|
|
|
|
import (
|
|
"encoding/json"
|
|
"reflect"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/samosvalishe/free-turn-proxy/internal/transport/kcpmux"
|
|
"github.com/samosvalishe/free-turn-proxy/internal/uri"
|
|
)
|
|
|
|
const minimalJSON = `{"peer":"1.2.3.4:5000","vk":{"links":["https://vk.ru/call/join/CODE"]}}`
|
|
|
|
func TestParseClientJSONFillsDefaults(t *testing.T) {
|
|
c, err := ParseClientJSON([]byte(minimalJSON), "")
|
|
if err != nil {
|
|
t.Fatalf("ParseClientJSON() error = %v", err)
|
|
}
|
|
|
|
want := Defaults()
|
|
want.Proxy.Peer = "1.2.3.4:5000"
|
|
want.VK.Links = []string{"CODE"}
|
|
|
|
if !reflect.DeepEqual(*c, want) {
|
|
t.Errorf("parsed config differs from defaults:\n got %+v\nwant %+v", *c, want)
|
|
}
|
|
}
|
|
|
|
func TestParseClientJSONAppliesFields(t *testing.T) {
|
|
in := `{
|
|
"peer": "5.6.7.8:56000",
|
|
"clientId": "abc",
|
|
"turn": {"n": 3, "transport": "udp"},
|
|
"proxy": {"listen": "127.0.0.1:1080"},
|
|
"vk": {"links": ["A", "B"], "streamsPerCred": 4, "manualCaptcha": true, "platform": "mobile"},
|
|
"obf": {"profile": "rtpopus3", "key": "` + testObfKey + `"},
|
|
"dns": {"mode": "doh", "servers": ["1.1.1.1", "8.8.8.8"]},
|
|
"log": {"debug": true}
|
|
}`
|
|
c, err := ParseClientJSON([]byte(in), "")
|
|
if err != nil {
|
|
t.Fatalf("ParseClientJSON() error = %v", err)
|
|
}
|
|
|
|
if c.TURN.N != 3 || !c.TURN.TransportUDP {
|
|
t.Errorf("TURN = %+v", c.TURN)
|
|
}
|
|
if c.Proxy.Listen != "127.0.0.1:1080" {
|
|
t.Errorf("Proxy = %+v", c.Proxy)
|
|
}
|
|
if len(c.VK.Links) != 2 || c.VK.Platform != PlatformMobile || !c.VK.ManualCaptcha {
|
|
t.Errorf("VK = %+v", c.VK)
|
|
}
|
|
if c.Obf.Profile != ObfProfileRTPOpus3 || len(c.Obf.Key) != 32 {
|
|
t.Errorf("Obf = %+v", c.Obf)
|
|
}
|
|
if c.DNS.Mode != DNSModeDoH || len(c.DNS.Servers) != 2 {
|
|
t.Errorf("DNS = %+v", c.DNS)
|
|
}
|
|
if !c.Log.Debug || c.ClientID != "abc" {
|
|
t.Errorf("Log/ClientID = %+v / %q", c.Log, c.ClientID)
|
|
}
|
|
}
|
|
|
|
func TestParseClientJSONRunsValidate(t *testing.T) {
|
|
in := `{"peer":"1.2.3.4:5000","vk":{"links":["A"]},` +
|
|
`"obf":{"profile":"none","timingMs":20}}`
|
|
_, err := ParseClientJSON([]byte(in), "")
|
|
if err == nil || !strings.Contains(err.Error(), "-obf-timing") {
|
|
t.Fatalf("ParseClientJSON() error = %v, want obf-timing rule", err)
|
|
}
|
|
}
|
|
|
|
func TestParseClientJSONRejectsUnknownField(t *testing.T) {
|
|
in := `{"peer":"1.2.3.4:5000","vk":{"links":["A"]},"treads":12}`
|
|
_, err := ParseClientJSON([]byte(in), "")
|
|
if err == nil || !strings.Contains(err.Error(), "treads") {
|
|
t.Fatalf("ParseClientJSON() error = %v, want unknown field error", err)
|
|
}
|
|
}
|
|
|
|
func TestParseClientJSONRejectsMalformed(t *testing.T) {
|
|
if _, err := ParseClientJSON([]byte("{"), ""); err == nil {
|
|
t.Fatal("ParseClientJSON() error = nil for malformed input")
|
|
}
|
|
}
|
|
|
|
func TestParseClientJSONOverlayURI(t *testing.T) {
|
|
node := &uri.Config{Version: 1, Provider: ProviderVK, Peer: "9.9.9.9:56000", N: 5}
|
|
|
|
c, err := ParseClientJSON([]byte(minimalJSON), node.String())
|
|
if err != nil {
|
|
t.Fatalf("ParseClientJSON() error = %v", err)
|
|
}
|
|
if c.Proxy.Peer != "9.9.9.9:56000" || c.TURN.N != 5 {
|
|
t.Errorf("overlay not applied: peer %q, n %d", c.Proxy.Peer, c.TURN.N)
|
|
}
|
|
if len(c.VK.Links) != 1 || c.VK.Links[0] != "CODE" {
|
|
t.Errorf("links overwritten by overlay: %v", c.VK.Links)
|
|
}
|
|
}
|
|
|
|
func TestParseClientJSONRejectsBadOverlay(t *testing.T) {
|
|
if _, err := ParseClientJSON([]byte(minimalJSON), "freeturn://not-base64!!"); err == nil {
|
|
t.Fatal("ParseClientJSON() error = nil for broken URI")
|
|
}
|
|
}
|
|
|
|
func TestPeekSubURLJSON(t *testing.T) {
|
|
if got := PeekSubURLJSON([]byte(`{"subUrl":"https://example.org/sub"}`)); got != "https://example.org/sub" {
|
|
t.Errorf("PeekSubURLJSON() = %q", got)
|
|
}
|
|
if got := PeekSubURLJSON([]byte(minimalJSON)); got != "" {
|
|
t.Errorf("PeekSubURLJSON() = %q, want empty", got)
|
|
}
|
|
if got := PeekSubURLJSON([]byte("{")); got != "" {
|
|
t.Errorf("PeekSubURLJSON() on malformed = %q, want empty", got)
|
|
}
|
|
}
|
|
|
|
func TestDefaultClientJSONRoundTrip(t *testing.T) {
|
|
var dto ClientJSON
|
|
if err := json.Unmarshal([]byte(DefaultClientJSON()), &dto); err != nil {
|
|
t.Fatalf("DefaultClientJSON() is not valid JSON: %v", err)
|
|
}
|
|
if !reflect.DeepEqual(dto, defaultClientJSON()) {
|
|
t.Errorf("round-trip changed defaults:\n got %+v\nwant %+v", dto, defaultClientJSON())
|
|
}
|
|
|
|
dto.Peer = "1.2.3.4:5000"
|
|
dto.VK.Links = []string{"CODE"}
|
|
b, err := json.Marshal(dto)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
c, err := ParseClientJSON(b, "")
|
|
if err != nil {
|
|
t.Fatalf("ParseClientJSON(DefaultClientJSON + required) error = %v", err)
|
|
}
|
|
if c.Obf.Timing != 0 || c.TURN.N != DefaultStreams {
|
|
t.Errorf("unexpected config from defaults: %+v", c)
|
|
}
|
|
}
|
|
|
|
func TestClientJSONTimingMsMapsToDuration(t *testing.T) {
|
|
in := `{"peer":"1.2.3.4:5000","vk":{"links":["A"]},` +
|
|
`"obf":{"profile":"rtpopus","key":"` + testObfKey + `","timingMs":25}}`
|
|
c, err := ParseClientJSON([]byte(in), "")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if c.Obf.Timing != 25*time.Millisecond {
|
|
t.Errorf("Obf.Timing = %v, want 25ms", c.Obf.Timing)
|
|
}
|
|
}
|
|
|
|
// Старый JSON без секций mode/kcp обязан читаться: поля optional, дефолт - udp.
|
|
func TestParseClientJSONLegacyWithoutMode(t *testing.T) {
|
|
data := `{"peer":"1.2.3.4:5000","vk":{"links":["abcdef"]}}`
|
|
c, err := ParseClientJSON([]byte(data), "")
|
|
if err != nil {
|
|
t.Fatalf("ParseClientJSON() error = %v", err)
|
|
}
|
|
if c.Proxy.Mode != ProxyModeUDP {
|
|
t.Errorf("Proxy.Mode = %q, want udp", c.Proxy.Mode)
|
|
}
|
|
if c.KCP.Profile != kcpmux.DefaultProfile() {
|
|
t.Errorf("KCP profile = %+v, want default", c.KCP.Profile)
|
|
}
|
|
}
|
|
|
|
func TestParseClientJSONTCPMode(t *testing.T) {
|
|
data := `{"peer":"1.2.3.4:5000","vk":{"links":["abcdef"]},"proxy":{"mode":"tcp"}}`
|
|
c, err := ParseClientJSON([]byte(data), "")
|
|
if err != nil {
|
|
t.Fatalf("ParseClientJSON() error = %v", err)
|
|
}
|
|
if c.Proxy.Mode != ProxyModeTCP {
|
|
t.Errorf("Proxy.Mode = %q, want tcp", c.Proxy.Mode)
|
|
}
|
|
}
|