diff --git a/server/middlewares.go b/server/middlewares.go index 624803f6..5131b49d 100644 --- a/server/middlewares.go +++ b/server/middlewares.go @@ -11,6 +11,8 @@ import ( "github.com/go-chi/chi/v5" "github.com/go-chi/cors" + "github.com/navidrome/navidrome/conf" + . "github.com/navidrome/navidrome/utils/gg" "github.com/go-chi/chi/v5/middleware" "github.com/navidrome/navidrome/consts" @@ -129,7 +131,7 @@ func clientUniqueIDMiddleware(next http.Handler) http.Handler { HttpOnly: true, Secure: true, SameSite: http.SameSiteStrictMode, - Path: "/", + Path: IfZero(conf.Server.BaseURL, "/"), } http.SetCookie(w, c) } else { diff --git a/server/subsonic/middlewares.go b/server/subsonic/middlewares.go index 8e0f930f..91c75f60 100644 --- a/server/subsonic/middlewares.go +++ b/server/subsonic/middlewares.go @@ -12,6 +12,7 @@ import ( "strings" ua "github.com/mileusna/useragent" + "github.com/navidrome/navidrome/conf" "github.com/navidrome/navidrome/consts" "github.com/navidrome/navidrome/core" "github.com/navidrome/navidrome/core/auth" @@ -20,6 +21,7 @@ import ( "github.com/navidrome/navidrome/model/request" "github.com/navidrome/navidrome/server/subsonic/responses" "github.com/navidrome/navidrome/utils" + . "github.com/navidrome/navidrome/utils/gg" ) func postFormToQueryParams(next http.Handler) http.Handler { @@ -164,7 +166,7 @@ func getPlayer(players core.Players) func(next http.Handler) http.Handler { MaxAge: consts.CookieExpiry, HttpOnly: true, SameSite: http.SameSiteStrictMode, - Path: "/", + Path: IfZero(conf.Server.BaseURL, "/"), } http.SetCookie(w, cookie) } diff --git a/utils/gg/gg.go b/utils/gg/gg.go new file mode 100644 index 00000000..e5cb8812 --- /dev/null +++ b/utils/gg/gg.go @@ -0,0 +1,14 @@ +// Package gg implements simple "extensions" to Go language. Based on https://github.com/icza/gog +package gg + +// IfZero returns v if it is a non-zero value, orElse otherwise. +// +// This is similar to elvis operator (?:) in Groovy and other languages. +// Note: Different from the real elvis operator, the orElse expression will always get evaluated. +func IfZero[T comparable](v T, orElse T) T { + var zero T + if v != zero { + return v + } + return orElse +} diff --git a/utils/gg/gg_test.go b/utils/gg/gg_test.go new file mode 100644 index 00000000..59e46082 --- /dev/null +++ b/utils/gg/gg_test.go @@ -0,0 +1,43 @@ +package gg_test + +import ( + "testing" + + "github.com/navidrome/navidrome/tests" + "github.com/navidrome/navidrome/utils/gg" + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +func TestGG(t *testing.T) { + tests.Init(t, false) + RegisterFailHandler(Fail) + RunSpecs(t, "GG Suite") +} + +var _ = Describe("IfZero", func() { + DescribeTable("string", + func(v, orElse, expected string) { + Expect(gg.IfZero(v, orElse)).To(Equal(expected)) + }, + Entry("zero value", "", "default", "default"), + Entry("non-zero value", "anything", "default", "anything"), + ) + DescribeTable("numeric", + func(v, orElse, expected int) { + Expect(gg.IfZero(v, orElse)).To(Equal(expected)) + }, + Entry("zero value", 0, 2, 2), + Entry("non-zero value", -1, 2, -1), + ) + type testStruct struct { + field1 int + } + DescribeTable("struct", + func(v, orElse, expected testStruct) { + Expect(gg.IfZero(v, orElse)).To(Equal(expected)) + }, + Entry("zero value", testStruct{}, testStruct{123}, testStruct{123}), + Entry("non-zero value", testStruct{456}, testStruct{123}, testStruct{456}), + ) +})