diff --git a/lib/cfg/init.go b/lib/cfg/init.go index 8fd3b56..aed5fed 100644 --- a/lib/cfg/init.go +++ b/lib/cfg/init.go @@ -2,13 +2,16 @@ package cfg import ( "fmt" + "io" "log" "os" "strconv" "strings" + "sync" "time" "github.com/segmentio/encoding/json" + "github.com/valyala/fasthttp" ) // You can now use a soundcloak.json file to configure! @@ -514,3 +517,28 @@ const ImageCDN = "i1.sndcdn.com" var True = true var False = false + +var prpool = sync.Pool{ + New: func() any { + return &ProxyReader{} + }, +} + +func AcquireProxyReader() *ProxyReader { + return prpool.Get().(*ProxyReader) +} + +type ProxyReader struct { + Reader io.Reader + Resp *fasthttp.Response +} + +func (pr *ProxyReader) Read(p []byte) (n int, err error) { + return pr.Reader.Read(p) +} + +func (pr *ProxyReader) Close() error { + defer fasthttp.ReleaseResponse(pr.Resp) + defer prpool.Put(pr) + return pr.Resp.CloseBodyStream() +} diff --git a/lib/proxy_images/init.go b/lib/proxy_images/init.go index d2504c1..6e6ff73 100644 --- a/lib/proxy_images/init.go +++ b/lib/proxy_images/init.go @@ -9,8 +9,6 @@ import ( "github.com/valyala/fasthttp" ) -var sndcdn = []byte(".sndcdn.com") - func Load(r fiber.Router) { r.Get("/_/proxy/images", func(c *fiber.Ctx) error { url := c.Query("url") @@ -26,7 +24,7 @@ func Load(r fiber.Router) { return err } - if !bytes.HasSuffix(parsed.Host(), sndcdn) { + if !bytes.HasSuffix(parsed.Host(), []byte(".sndcdn.com")) { return fiber.ErrBadRequest } @@ -37,23 +35,22 @@ func Load(r fiber.Router) { req.SetURI(parsed) req.Header.Set("User-Agent", cfg.UserAgent) - req.Header.Set("Accept-Encoding", "gzip, deflate, br, zstd") + //req.Header.Set("Accept-Encoding", "gzip, deflate, br, zstd") images not big enough to be compressed resp := fasthttp.AcquireResponse() - defer fasthttp.ReleaseResponse(resp) + //defer fasthttp.ReleaseResponse(resp) moved to proxyreader!!! err = sc.DoWithRetry(sc.ImageClient, req, resp) if err != nil { return err } - data, err := resp.BodyUncompressed() - if err != nil { - data = resp.Body() - } - - c.Response().Header.SetBytesV("Content-Type", resp.Header.Peek("Content-Type")) + c.Set("Content-Type", "image/jpeg") c.Set("Cache-Control", cfg.ImageCacheControl) - return c.Send(data) + //return c.Send(resp.Body()) + pr := cfg.AcquireProxyReader() + pr.Reader = resp.BodyStream() + pr.Resp = resp + return c.SendStream(pr) }) } diff --git a/lib/proxy_streams/init.go b/lib/proxy_streams/init.go index 689329e..8e64c70 100644 --- a/lib/proxy_streams/init.go +++ b/lib/proxy_streams/init.go @@ -12,14 +12,13 @@ import ( const cdn = "cf-hls-media.sndcdn.com" -var cdnb = []byte(cdn) - var httpc = &fasthttp.HostClient{ Addr: cdn + ":443", IsTLS: true, DialDualStack: true, Dial: (&fasthttp.TCPDialer{DNSCacheDuration: cfg.DNSCacheTTL}).Dial, MaxIdleConnDuration: 1<<63 - 1, + StreamResponseBody: true, } func Load(r fiber.Router) { @@ -37,7 +36,7 @@ func Load(r fiber.Router) { return err } - if !bytes.Equal(parsed.Host(), cdnb) { + if !bytes.Equal(parsed.Host(), []byte(cdn)) { return fiber.ErrBadRequest } @@ -49,14 +48,17 @@ func Load(r fiber.Router) { req.Header.Set("Accept-Encoding", "gzip, deflate, br, zstd") resp := fasthttp.AcquireResponse() - defer fasthttp.ReleaseResponse(resp) + //defer fasthttp.ReleaseResponse(resp) err = sc.DoWithRetry(httpc, req, resp) if err != nil { return err } - - return c.Send(resp.Body()) + //return c.Send(resp.Body()) + pr := cfg.AcquireProxyReader() + pr.Reader = resp.BodyStream() + pr.Resp = resp + return c.SendStream(pr) }) r.Get("/_/proxy/streams/playlist", func(c *fiber.Ctx) error { @@ -73,7 +75,7 @@ func Load(r fiber.Router) { return err } - if !bytes.Equal(parsed.Host(), cdnb) { + if !bytes.Equal(parsed.Host(), []byte(cdn)) { return fiber.ErrBadRequest } diff --git a/lib/sc/init.go b/lib/sc/init.go index 95fdddc..ef4a018 100644 --- a/lib/sc/init.go +++ b/lib/sc/init.go @@ -39,6 +39,7 @@ var ImageClient = &fasthttp.HostClient{ DialDualStack: true, Dial: (&fasthttp.TCPDialer{DNSCacheDuration: cfg.DNSCacheTTL}).Dial, MaxIdleConnDuration: 1<<63 - 1, + StreamResponseBody: true, } var genericClient = &fasthttp.Client{ diff --git a/lib/sc/track.go b/lib/sc/track.go index 6a57890..a6aac00 100644 --- a/lib/sc/track.go +++ b/lib/sc/track.go @@ -414,15 +414,13 @@ func (t Track) DownloadImage() ([]byte, string, error) { req.SetRequestURI(t.Artwork) req.Header.Set("User-Agent", cfg.UserAgent) - req.Header.Set("Accept-Encoding", "gzip, deflate, br, zstd") + //req.Header.Set("Accept-Encoding", "gzip, deflate, br, zstd") images not big enough to be compressed resp := fasthttp.AcquireResponse() defer fasthttp.ReleaseResponse(resp) err := DoWithRetry(ImageClient, req, resp) if err != nil { - fmt.Println(t.Artwork) - fmt.Println("hi", err) return nil, "", err }