From 5d1094c8664166036fab1e48c3955a768875f61e Mon Sep 17 00:00:00 2001 From: Laptop Date: Sat, 26 Oct 2024 22:27:19 +0300 Subject: [PATCH] optionally load up config from soundcloak.json --- .gitignore | 3 +- lib/cfg/init.go | 148 ++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 132 insertions(+), 19 deletions(-) diff --git a/.gitignore b/.gitignore index 909ceb6..f966298 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,5 @@ main package-lock.json *_templ.go fly.toml -*.fiber.gz \ No newline at end of file +*.fiber.gz +soundcloak.json \ No newline at end of file diff --git a/lib/cfg/init.go b/lib/cfg/init.go index 18d667a..d454640 100644 --- a/lib/cfg/init.go +++ b/lib/cfg/init.go @@ -1,75 +1,187 @@ package cfg import ( + "log" + "os" "time" jsoniter "github.com/json-iterator/go" ) +// You can now use a soundcloak.json file to configure! +// or you can specify a different path with environment variable SOUNDCLOAK_CONFIG +// it's not needed to specify every key in your config, it will use the default values for keys you haven't specified +// also, when specifying time, specify it in seconds (instead of nanoseconds as time.Duration) + +// // config // // + // fully loads the track on page load // this option is here since the stream expires after some time (5 minutes? correct me if im wrong) // if the stream isn't fully loaded before it expires - you'll need to reload the page -const FullyPreloadTrack = false +var FullyPreloadTrack = false // proxy images (user avatars, track/playlist covers) -const ProxyImages = false -const ImageCacheControl = "max-age=600; public" // 10 minutes by default, only used for proxied images +var ProxyImages = false +var ImageCacheControl = "max-age=600; public" // 10 minutes by default, only used for proxied images // proxy streams (hls playlist files and track parts) -const ProxyStreams = false +var ProxyStreams = false // enable /_/info endpoint (shows if some settings are enabled/disabled) -const InstanceInfo = true +var InstanceInfo = true // time-to-live for clientid cache // larger number will improve performance (no need to recheck everytime) but might make soundcloak briefly unusable for a larger amount of time if the client id is invalidated -const ClientIDTTL = 30 * time.Minute +var ClientIDTTL = 30 * time.Minute // time-to-live for user profile cache -const UserTTL = 10 * time.Minute +var UserTTL = 10 * time.Minute // delay between cleanup of user cache -const UserCacheCleanDelay = UserTTL / 4 +var UserCacheCleanDelay = UserTTL / 4 // time-to-live for track cache -const TrackTTL = 10 * time.Minute +var TrackTTL = 10 * time.Minute // delay between cleanup of track cache -const TrackCacheCleanDelay = TrackTTL / 4 +var TrackCacheCleanDelay = TrackTTL / 4 // time-to-live for playlist cache -const PlaylistTTL = 10 * time.Minute +var PlaylistTTL = 10 * time.Minute // delay between cleanup of playlist cache -const PlaylistCacheCleanDelay = PlaylistTTL / 4 +var PlaylistCacheCleanDelay = PlaylistTTL / 4 // default fasthttp one was causing connections to be stuck? todo make it cycle browser useragents or just choose random at startup -const UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.3" +var UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.3" // time-to-live for dns cache -const DNSCacheTTL = 10 * time.Minute +var DNSCacheTTL = 10 * time.Minute // // // some webserver configuration, put here to make it easier to configure what you need // // // // more info can be found here: https://docs.gofiber.io/api/fiber#config // run soundcloak on this address (localhost:4664 by default) -const Addr = ":4664" +var Addr = ":4664" // run multiple instances of soundcloud locally to be able to handle more requests // each one will be a separate process, so they will have separate cache -const Prefork = false +var Prefork = false // Enables TLS Early Data (0-RTT / zero round trip time) // This can reduce latency, but also makes requests replayable (not that much of a concern for soundcloak, since there are no authenticated operations) // There might be breakage when used together with TrustedProxyCheck and the proxy is untrusted -const EarlyData = false +var EarlyData = false // use X-Forwarded-* headers ONLY when ip is in TrustedProxies list // when disabled, the X-Forwarded-* headers will be blindly used -const TrustedProxyCheck = true +var TrustedProxyCheck = true // list of ips or ip ranges of trusted proxies (check above) var TrustedProxies = []string{} +// // end of config // // + // what JSON library should be used var JSON = jsoniter.ConfigFastest + +func init() { + filename := "soundcloak.json" + if env := os.Getenv("SOUNDCLOAK_CONFIG"); env != "" { + filename = env + } + + data, err := os.ReadFile(filename) + if err != nil { + log.Printf("failed to load config from %s: %s\n", filename, err) + return + } + + var config struct { + FullyPreloadTrack *bool + ProxyImages *bool + ImageCacheControl *string + ProxyStreams *bool + InstanceInfo *bool + ClientIDTTL *time.Duration + UserTTL *time.Duration + UserCacheCleanDelay *time.Duration + TrackTTL *time.Duration + TrackCacheCleanDelay *time.Duration + PlaylistTTL *time.Duration + PlaylistCacheCleanDelay *time.Duration + UserAgent *string + DNSCacheTTL *time.Duration + Addr *string + Prefork *bool + EarlyData *bool + TrustedProxyCheck *bool + TrustedProxies *[]string + } + + err = JSON.Unmarshal(data, &config) + if err != nil { + log.Printf("failed to parse config from %s: %s\n", filename, err) + return + } + + // tedious + // i've decided to fully override to make it easier to change default config later on + if config.FullyPreloadTrack != nil { + FullyPreloadTrack = *config.FullyPreloadTrack + } + if config.ProxyImages != nil { + ProxyImages = *config.ProxyImages + } + if config.ImageCacheControl != nil { + ImageCacheControl = *config.ImageCacheControl + } + if config.ProxyStreams != nil { + ProxyStreams = *config.ProxyStreams + } + if config.InstanceInfo != nil { + InstanceInfo = *config.InstanceInfo + } + if config.ClientIDTTL != nil { + ClientIDTTL = *config.ClientIDTTL * time.Second + } + if config.UserTTL != nil { + UserTTL = *config.UserTTL * time.Second + } + if config.UserCacheCleanDelay != nil { + UserCacheCleanDelay = *config.UserCacheCleanDelay * time.Second + } + if config.TrackTTL != nil { + TrackTTL = *config.TrackTTL * time.Second + } + if config.TrackCacheCleanDelay != nil { + TrackCacheCleanDelay = *config.TrackCacheCleanDelay * time.Second + } + if config.PlaylistTTL != nil { + PlaylistTTL = *config.PlaylistTTL * time.Second + } + if config.PlaylistCacheCleanDelay != nil { + PlaylistCacheCleanDelay = *config.PlaylistCacheCleanDelay * time.Second + } + if config.UserAgent != nil { + UserAgent = *config.UserAgent + } + if config.DNSCacheTTL != nil { + DNSCacheTTL = *config.DNSCacheTTL * time.Second + } + if config.Addr != nil { + Addr = *config.Addr + } + if config.Prefork != nil { + Prefork = *config.Prefork + } + if config.EarlyData != nil { + EarlyData = *config.EarlyData + } + if config.TrustedProxyCheck != nil { + TrustedProxyCheck = *config.TrustedProxyCheck + } + if config.TrustedProxies != nil { + TrustedProxies = *config.TrustedProxies + } +}