Some checks are pending
CI Pipeline / Run Tests (push) Waiting to run
CI Pipeline / Lint Code (push) Waiting to run
CI Pipeline / Security Scan (push) Waiting to run
CI Pipeline / Build Docker Images (push) Blocked by required conditions
CI Pipeline / E2E Tests (push) Blocked by required conditions
294 lines
9.1 KiB
Go
294 lines
9.1 KiB
Go
package config
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"time"
|
|
|
|
"gopkg.in/yaml.v2"
|
|
)
|
|
|
|
// Config represents the unified configuration for all services
|
|
type Config struct {
|
|
Mode string `yaml:"mode"`
|
|
|
|
Gateway GatewayConfig `yaml:"gateway"`
|
|
BlossomServer BlossomServerConfig `yaml:"blossom_server"`
|
|
DHT DHTConfig `yaml:"dht"`
|
|
Storage StorageConfig `yaml:"storage"`
|
|
Blossom BlossomConfig `yaml:"blossom"`
|
|
Torrent TorrentConfig `yaml:"torrent"`
|
|
Tracker TrackerConfig `yaml:"tracker"`
|
|
Nostr NostrConfig `yaml:"nostr"`
|
|
Proxy ProxyConfig `yaml:"proxy"`
|
|
Admin AdminConfig `yaml:"admin"`
|
|
RateLimiting RateLimitingConfig `yaml:"rate_limiting"`
|
|
}
|
|
|
|
// GatewayConfig configures the HTTP API gateway
|
|
type GatewayConfig struct {
|
|
Enabled bool `yaml:"enabled"`
|
|
Port int `yaml:"port"`
|
|
MaxUploadSize string `yaml:"max_upload_size"`
|
|
}
|
|
|
|
// BlossomServerConfig configures the embedded Blossom server
|
|
type BlossomServerConfig struct {
|
|
Enabled bool `yaml:"enabled"`
|
|
Port int `yaml:"port"`
|
|
StoragePath string `yaml:"storage_path"`
|
|
MaxBlobSize string `yaml:"max_blob_size"`
|
|
RateLimit RateLimit `yaml:"rate_limit"`
|
|
}
|
|
|
|
// RateLimit configures rate limiting for the Blossom server
|
|
type RateLimit struct {
|
|
RequestsPerMinute int `yaml:"requests_per_minute"`
|
|
BurstSize int `yaml:"burst_size"`
|
|
}
|
|
|
|
// DHTConfig configures the DHT node
|
|
type DHTConfig struct {
|
|
Enabled bool `yaml:"enabled"`
|
|
Port int `yaml:"port"`
|
|
NodeID string `yaml:"node_id"` // auto-generate if empty
|
|
BootstrapSelf bool `yaml:"bootstrap_self"` // add self as bootstrap node
|
|
BootstrapNodes []string `yaml:"bootstrap_nodes"`
|
|
AnnounceInterval time.Duration `yaml:"announce_interval"` // torrent announce interval
|
|
CleanupInterval time.Duration `yaml:"cleanup_interval"` // node cleanup interval
|
|
MaxTorrents int `yaml:"max_torrents"` // max torrents to track
|
|
MaxNodes int `yaml:"max_nodes"` // max nodes to store
|
|
MaxPeersPerTorrent int `yaml:"max_peers_per_torrent"`
|
|
}
|
|
|
|
// StorageConfig configures shared storage settings
|
|
type StorageConfig struct {
|
|
BlobThreshold int64 `yaml:"blob_threshold"`
|
|
ChunkSize int64 `yaml:"chunk_size"`
|
|
MetadataDB string `yaml:"metadata_db"`
|
|
BlobStorage string `yaml:"blob_storage"`
|
|
ChunkStorage string `yaml:"chunk_storage"`
|
|
Strategy StorageStrategy `yaml:"strategy"`
|
|
}
|
|
|
|
// StorageStrategy defines how files should be stored based on size
|
|
type StorageStrategy struct {
|
|
SmallFiles string `yaml:"small_files"` // "blob"
|
|
LargeFiles string `yaml:"large_files"` // "torrent"
|
|
}
|
|
|
|
// BlossomConfig configures external Blossom servers
|
|
type BlossomConfig struct {
|
|
Servers []string `yaml:"servers"`
|
|
}
|
|
|
|
// TorrentConfig configures BitTorrent settings
|
|
type TorrentConfig struct {
|
|
Trackers []string `yaml:"trackers"`
|
|
}
|
|
|
|
// TrackerConfig configures the built-in BitTorrent tracker
|
|
type TrackerConfig struct {
|
|
Enabled bool `yaml:"enabled"`
|
|
AnnounceInterval int `yaml:"announce_interval"` // seconds
|
|
MinInterval int `yaml:"min_interval"` // seconds
|
|
DefaultNumWant int `yaml:"default_numwant"` // peers to return
|
|
MaxNumWant int `yaml:"max_numwant"` // maximum peers
|
|
CleanupInterval time.Duration `yaml:"cleanup_interval"` // cleanup frequency
|
|
PeerTimeout time.Duration `yaml:"peer_timeout"` // peer expiration
|
|
}
|
|
|
|
// NostrConfig configures Nostr relay settings
|
|
type NostrConfig struct {
|
|
Relays []string `yaml:"relays"`
|
|
}
|
|
|
|
// ProxyConfig configures smart proxy settings
|
|
type ProxyConfig struct {
|
|
Enabled bool `yaml:"enabled"`
|
|
CacheSize int `yaml:"cache_size"`
|
|
CacheMaxAge time.Duration `yaml:"cache_max_age"`
|
|
}
|
|
|
|
// AdminConfig configures admin functionality
|
|
type AdminConfig struct {
|
|
Enabled bool `yaml:"enabled"`
|
|
Pubkeys []string `yaml:"pubkeys"`
|
|
AutoCleanup bool `yaml:"auto_cleanup"`
|
|
CleanupAge string `yaml:"cleanup_age"`
|
|
MaxFileAge string `yaml:"max_file_age"`
|
|
ReportThreshold int `yaml:"report_threshold"`
|
|
DefaultUserStorageLimit string `yaml:"default_user_storage_limit"`
|
|
}
|
|
|
|
// RateLimitingConfig configures rate limiting for different operations
|
|
type RateLimitingConfig struct {
|
|
Upload UploadRateConfig `yaml:"upload"`
|
|
Download DownloadRateConfig `yaml:"download"`
|
|
Stream StreamRateConfig `yaml:"stream"`
|
|
Auth AuthRateConfig `yaml:"auth"`
|
|
}
|
|
|
|
// UploadRateConfig configures upload rate limiting
|
|
type UploadRateConfig struct {
|
|
RequestsPerSecond float64 `yaml:"requests_per_second"`
|
|
BurstSize int `yaml:"burst_size"`
|
|
MaxFileSize string `yaml:"max_file_size"`
|
|
}
|
|
|
|
// DownloadRateConfig configures download rate limiting
|
|
type DownloadRateConfig struct {
|
|
RequestsPerSecond float64 `yaml:"requests_per_second"`
|
|
BurstSize int `yaml:"burst_size"`
|
|
}
|
|
|
|
// StreamRateConfig configures streaming rate limiting
|
|
type StreamRateConfig struct {
|
|
RequestsPerSecond float64 `yaml:"requests_per_second"`
|
|
BurstSize int `yaml:"burst_size"`
|
|
MaxConcurrent int `yaml:"max_concurrent"`
|
|
}
|
|
|
|
// AuthRateConfig configures authentication rate limiting
|
|
type AuthRateConfig struct {
|
|
LoginAttemptsPerMinute int `yaml:"login_attempts_per_minute"`
|
|
BurstSize int `yaml:"burst_size"`
|
|
}
|
|
|
|
// LoadConfig loads configuration from a YAML file
|
|
func LoadConfig(filename string) (*Config, error) {
|
|
data, err := os.ReadFile(filename)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to read config file %s: %w", filename, err)
|
|
}
|
|
|
|
var config Config
|
|
if err := yaml.Unmarshal(data, &config); err != nil {
|
|
return nil, fmt.Errorf("failed to parse config file %s: %w", filename, err)
|
|
}
|
|
|
|
// Set defaults
|
|
if config.Mode == "" {
|
|
config.Mode = "unified"
|
|
}
|
|
|
|
return &config, nil
|
|
}
|
|
|
|
// IsServiceEnabled checks if a specific service should be enabled based on mode
|
|
func (c *Config) IsServiceEnabled(service string) bool {
|
|
switch c.Mode {
|
|
case "unified":
|
|
switch service {
|
|
case "gateway":
|
|
return c.Gateway.Enabled
|
|
case "blossom":
|
|
return c.BlossomServer.Enabled
|
|
case "dht":
|
|
return c.DHT.Enabled
|
|
case "tracker":
|
|
return c.Tracker.Enabled
|
|
}
|
|
case "gateway-only":
|
|
return service == "gateway" && c.Gateway.Enabled
|
|
case "blossom-only":
|
|
return service == "blossom" && c.BlossomServer.Enabled
|
|
case "dht-only":
|
|
return service == "dht" && c.DHT.Enabled
|
|
}
|
|
return false
|
|
}
|
|
|
|
// GetBlobThreshold returns the blob threshold in bytes
|
|
func (c *Config) GetBlobThreshold() int64 {
|
|
return c.Storage.BlobThreshold
|
|
}
|
|
|
|
// GetChunkSize returns the chunk size in bytes
|
|
func (c *Config) GetChunkSize() int64 {
|
|
return c.Storage.ChunkSize
|
|
}
|
|
|
|
// GetMaxBlobSizeBytes converts the max blob size string to bytes
|
|
func (c *Config) GetMaxBlobSizeBytes() (int64, error) {
|
|
return parseSize(c.BlossomServer.MaxBlobSize)
|
|
}
|
|
|
|
// GetMaxUploadSizeBytes converts the max upload size string to bytes
|
|
func (c *Config) GetMaxUploadSizeBytes() (int64, error) {
|
|
return parseSize(c.Gateway.MaxUploadSize)
|
|
}
|
|
|
|
// GetDefaultUserStorageLimitBytes converts the default user storage limit to bytes
|
|
func (c *Config) GetDefaultUserStorageLimitBytes() (int64, error) {
|
|
if c.Admin.DefaultUserStorageLimit == "" {
|
|
return 10 * 1024 * 1024 * 1024, nil // 10GB default
|
|
}
|
|
return parseSize(c.Admin.DefaultUserStorageLimit)
|
|
}
|
|
|
|
// parseSize parses size strings like "2MB", "100MB", "10GB"
|
|
func parseSize(sizeStr string) (int64, error) {
|
|
if sizeStr == "" {
|
|
return 0, fmt.Errorf("empty size string")
|
|
}
|
|
|
|
var size int64
|
|
var unit string
|
|
n, err := fmt.Sscanf(sizeStr, "%d%s", &size, &unit)
|
|
if err != nil || n != 2 {
|
|
return 0, fmt.Errorf("invalid size format: %s", sizeStr)
|
|
}
|
|
|
|
switch unit {
|
|
case "B", "b":
|
|
return size, nil
|
|
case "KB", "kb", "K", "k":
|
|
return size * 1024, nil
|
|
case "MB", "mb", "M", "m":
|
|
return size * 1024 * 1024, nil
|
|
case "GB", "gb", "G", "g":
|
|
return size * 1024 * 1024 * 1024, nil
|
|
case "TB", "tb", "T", "t":
|
|
return size * 1024 * 1024 * 1024 * 1024, nil
|
|
default:
|
|
return 0, fmt.Errorf("unknown unit: %s", unit)
|
|
}
|
|
}
|
|
|
|
// GetRateLimitValues returns rate limiting values for middleware
|
|
func (c *Config) GetRateLimitValues() (float64, int, float64, int, float64, int) {
|
|
upload := c.RateLimiting.Upload
|
|
download := c.RateLimiting.Download
|
|
stream := c.RateLimiting.Stream
|
|
|
|
// Provide defaults if not configured
|
|
uploadRate := upload.RequestsPerSecond
|
|
if uploadRate <= 0 {
|
|
uploadRate = 1.0
|
|
}
|
|
uploadBurst := upload.BurstSize
|
|
if uploadBurst <= 0 {
|
|
uploadBurst = 5
|
|
}
|
|
|
|
downloadRate := download.RequestsPerSecond
|
|
if downloadRate <= 0 {
|
|
downloadRate = 50.0
|
|
}
|
|
downloadBurst := download.BurstSize
|
|
if downloadBurst <= 0 {
|
|
downloadBurst = 100
|
|
}
|
|
|
|
streamRate := stream.RequestsPerSecond
|
|
if streamRate <= 0 {
|
|
streamRate = 10.0
|
|
}
|
|
streamBurst := stream.BurstSize
|
|
if streamBurst <= 0 {
|
|
streamBurst = 20
|
|
}
|
|
|
|
return uploadRate, uploadBurst, downloadRate, downloadBurst, streamRate, streamBurst
|
|
} |