This commit is contained in:
2026-06-15 22:46:12 +08:00
commit f6508eccdb
38 changed files with 3133 additions and 0 deletions

View File

@@ -0,0 +1,123 @@
package config
import (
"encoding/json"
"errors"
"os"
"time"
)
type Config struct {
HTTP HTTPConfig `json:"http"`
Redis RedisConfig `json:"redis"`
Room RoomConfig `json:"room"`
Proxy ProxyConfig `json:"proxy"`
WebSocket WebSocketConfig `json:"websocket"`
Source SourceConfig `json:"source"`
}
type HTTPConfig struct {
Addr string `json:"addr"`
AllowedOrigins []string `json:"allowedOrigins"`
}
type RedisConfig struct {
Addr string `json:"addr"`
Password string `json:"password"`
DB int `json:"db"`
}
type RoomConfig struct {
CodeLength int `json:"codeLength"`
EmptyTTL Duration `json:"emptyTtl"`
OwnerReconnectHold Duration `json:"ownerReconnectHold"`
}
type ProxyConfig struct {
Enabled bool `json:"enabled"`
RequestTimeout Duration `json:"requestTimeout"`
MaxIdleConns int `json:"maxIdleConns"`
ResponseHeaderBytes int64 `json:"responseHeaderBytes"`
}
type WebSocketConfig struct {
PingInterval Duration `json:"pingInterval"`
PongTimeout Duration `json:"pongTimeout"`
WriteTimeout Duration `json:"writeTimeout"`
}
type SourceConfig struct {
DefaultMode string `json:"defaultMode"`
}
func Load(path string) (Config, error) {
if path == "" {
path = os.Getenv("SYNCTV_CONFIG")
}
if path == "" {
path = "config/config.json"
}
cfg := Default()
b, err := os.ReadFile(path)
if err != nil {
return Config{}, err
}
if err := json.Unmarshal(b, &cfg); err != nil {
return Config{}, err
}
if err := cfg.Validate(); err != nil {
return Config{}, err
}
return cfg, nil
}
func Default() Config {
return Config{
HTTP: HTTPConfig{
Addr: ":8080",
AllowedOrigins: []string{"*"},
},
Redis: RedisConfig{
Addr: "localhost:6379",
},
Room: RoomConfig{
CodeLength: 6,
EmptyTTL: Duration(30 * time.Minute),
OwnerReconnectHold: Duration(30 * time.Second),
},
Proxy: ProxyConfig{
Enabled: true,
RequestTimeout: 0,
MaxIdleConns: 256,
ResponseHeaderBytes: 1 << 20,
},
WebSocket: WebSocketConfig{
PingInterval: Duration(25 * time.Second),
PongTimeout: Duration(60 * time.Second),
WriteTimeout: Duration(10 * time.Second),
},
Source: SourceConfig{
DefaultMode: "direct",
},
}
}
func (c Config) Validate() error {
if c.HTTP.Addr == "" {
return errors.New("http.addr is required")
}
if c.Redis.Addr == "" {
return errors.New("redis.addr is required")
}
if c.Room.CodeLength < 4 {
return errors.New("room.codeLength must be at least 4")
}
if c.Room.EmptyTTL <= 0 {
return errors.New("room.emptyTtl must be positive")
}
if c.Source.DefaultMode != "direct" && c.Source.DefaultMode != "proxy" {
return errors.New("source.defaultMode must be direct or proxy")
}
return nil
}