diff --git a/core/agents/placeholders.go b/core/agents/placeholders.go
index 45ab5f591..1210b8db9 100644
--- a/core/agents/placeholders.go
+++ b/core/agents/placeholders.go
@@ -3,21 +3,22 @@ package agents
import (
"context"
+ "github.com/navidrome/navidrome/consts"
"github.com/navidrome/navidrome/model"
)
const PlaceholderAgentName = "placeholder"
const (
- placeholderArtistImageSmallUrl = "https://lastfm.freetls.fastly.net/i/u/64s/2a96cbd8b46e442fc41c2b86b821562f.png"
- placeholderArtistImageMediumUrl = "https://lastfm.freetls.fastly.net/i/u/174s/2a96cbd8b46e442fc41c2b86b821562f.png"
- placeholderArtistImageLargeUrl = "https://lastfm.freetls.fastly.net/i/u/300x300/2a96cbd8b46e442fc41c2b86b821562f.png"
+ placeholderArtistImageSmallUrl = consts.URLPathUI + "/artist-placeholder.webp"
+ placeholderArtistImageMediumUrl = consts.URLPathUI + "/artist-placeholder.webp"
+ placeholderArtistImageLargeUrl = consts.URLPathUI + "/artist-placeholder.webp"
placeholderBiography = "Biography not available"
)
type placeholderAgent struct{}
-func placeholdersConstructor(ds model.DataStore) Interface {
+func placeholdersConstructor(_ model.DataStore) Interface {
return &placeholderAgent{}
}
diff --git a/server/middlewares.go b/server/middlewares.go
index effed7721..1c374fa2b 100644
--- a/server/middlewares.go
+++ b/server/middlewares.go
@@ -115,7 +115,7 @@ func compressMiddleware() func(http.Handler) http.Handler {
)
}
-func clientUniqueIdAdder(next http.Handler) http.Handler {
+func clientUniqueIDMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
clientUniqueId := r.Header.Get(consts.UIClientUniqueIDHeader)
@@ -145,3 +145,57 @@ func clientUniqueIdAdder(next http.Handler) http.Handler {
next.ServeHTTP(w, r)
})
}
+
+func serverAddressMiddleware(h http.Handler) http.Handler {
+ fn := func(w http.ResponseWriter, r *http.Request) {
+ if rScheme, rHost := serverAddress(r); rHost != "" {
+ r.Host = rHost
+ r.URL.Scheme = rScheme
+ }
+ h.ServeHTTP(w, r)
+ }
+
+ return http.HandlerFunc(fn)
+}
+
+var (
+ xForwardedHost = http.CanonicalHeaderKey("X-Forwarded-Host")
+ xForwardedProto = http.CanonicalHeaderKey("X-Forwarded-Scheme")
+ xForwardedScheme = http.CanonicalHeaderKey("X-Forwarded-Proto")
+)
+
+func serverAddress(r *http.Request) (scheme, host string) {
+ origHost := r.Host
+ protocol := "http"
+ if r.TLS != nil {
+ protocol = "https"
+ }
+ xfh := r.Header.Get(xForwardedHost)
+ if xfh != "" {
+ i := strings.Index(xfh, ",")
+ if i == -1 {
+ i = len(xfh)
+ }
+ xfh = xfh[:i]
+ }
+ scheme = firstOr(
+ protocol,
+ r.Header.Get(xForwardedProto),
+ r.Header.Get(xForwardedScheme),
+ r.URL.Scheme,
+ )
+ host = firstOr(r.Host, xfh)
+ if host != origHost {
+ log.Trace(r.Context(), "Request host has changed", "origHost", origHost, "host", host, "scheme", scheme, "url", r.URL)
+ }
+ return scheme, host
+}
+
+func firstOr(or string, strings ...string) string {
+ for _, s := range strings {
+ if s != "" {
+ return s
+ }
+ }
+ return or
+}
diff --git a/server/server.go b/server/server.go
index d095d586c..f96b1c3d3 100644
--- a/server/server.go
+++ b/server/server.go
@@ -6,6 +6,7 @@ import (
"fmt"
"net/http"
"path"
+ "strings"
"time"
"github.com/go-chi/chi/v5"
@@ -94,7 +95,8 @@ func (s *Server) initRoutes() {
r.Use(middleware.Recoverer)
r.Use(compressMiddleware())
r.Use(middleware.Heartbeat("/ping"))
- r.Use(clientUniqueIdAdder)
+ r.Use(serverAddressMiddleware)
+ r.Use(clientUniqueIDMiddleware)
r.Use(loggerInjector)
r.Use(requestLogger)
r.Use(robotsTXT(ui.BuildAssets()))
@@ -135,3 +137,11 @@ func (s *Server) frontendAssetsHandler() http.Handler {
r.Handle("/*", http.StripPrefix(s.appRoot, http.FileServer(http.FS(ui.BuildAssets()))))
return r
}
+
+func AbsoluteURL(r *http.Request, url string) string {
+ if strings.HasPrefix(url, "/") {
+ appRoot := path.Join(r.Host, conf.Server.BaseURL, url)
+ url = r.URL.Scheme + "://" + appRoot
+ }
+ return url
+}
diff --git a/server/subsonic/browsing.go b/server/subsonic/browsing.go
index 9d17dcd47..044a535b2 100644
--- a/server/subsonic/browsing.go
+++ b/server/subsonic/browsing.go
@@ -10,6 +10,7 @@ import (
"github.com/navidrome/navidrome/conf"
"github.com/navidrome/navidrome/log"
"github.com/navidrome/navidrome/model"
+ "github.com/navidrome/navidrome/server"
"github.com/navidrome/navidrome/server/subsonic/filter"
"github.com/navidrome/navidrome/server/subsonic/responses"
"github.com/navidrome/navidrome/utils"
@@ -231,9 +232,9 @@ func (api *Router) GetArtistInfo(r *http.Request) (*responses.Subsonic, error) {
response := newResponse()
response.ArtistInfo = &responses.ArtistInfo{}
response.ArtistInfo.Biography = artist.Biography
- response.ArtistInfo.SmallImageUrl = artist.SmallImageUrl
- response.ArtistInfo.MediumImageUrl = artist.MediumImageUrl
- response.ArtistInfo.LargeImageUrl = artist.LargeImageUrl
+ response.ArtistInfo.SmallImageUrl = server.AbsoluteURL(r, artist.SmallImageUrl)
+ response.ArtistInfo.MediumImageUrl = server.AbsoluteURL(r, artist.MediumImageUrl)
+ response.ArtistInfo.LargeImageUrl = server.AbsoluteURL(r, artist.LargeImageUrl)
response.ArtistInfo.LastFmUrl = artist.ExternalUrl
response.ArtistInfo.MusicBrainzID = artist.MbzArtistID
for _, s := range artist.SimilarArtists {
@@ -259,7 +260,7 @@ func (api *Router) GetArtistInfo2(r *http.Request) (*responses.Subsonic, error)
similar.AlbumCount = s.AlbumCount
similar.Starred = s.Starred
similar.UserRating = s.UserRating
- similar.ArtistImageUrl = s.ArtistImageUrl
+ similar.ArtistImageUrl = server.AbsoluteURL(r, s.ArtistImageUrl)
response.ArtistInfo2.SimilarArtist = append(response.ArtistInfo2.SimilarArtist, similar)
}
return response, nil
diff --git a/server/subsonic/responses/responses.go b/server/subsonic/responses/responses.go
index 9593f6706..795e1290f 100644
--- a/server/subsonic/responses/responses.go
+++ b/server/subsonic/responses/responses.go
@@ -78,8 +78,9 @@ type Artist struct {
Starred *time.Time `xml:"starred,attr,omitempty" json:"starred,omitempty"`
UserRating int `xml:"userRating,attr,omitempty" json:"userRating,omitempty"`
ArtistImageUrl string `xml:"artistImageUrl,attr,omitempty" json:"artistImageUrl,omitempty"`
- /*
-
+ /* TODO:
+
+
*/
}
diff --git a/ui/public/artist-placeholder.webp b/ui/public/artist-placeholder.webp
new file mode 100644
index 000000000..2729158d2
Binary files /dev/null and b/ui/public/artist-placeholder.webp differ