From d7baf6ee7f9533f5fdd51a66f806f48a75fcbbf5 Mon Sep 17 00:00:00 2001 From: Deluan Date: Sun, 5 Apr 2026 12:12:15 -0400 Subject: [PATCH] fix(shares): honor path component of ShareURL config MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PublicURL() copied only the scheme and host from conf.Server.ShareURL, silently dropping any path component. This broke OpenGraph image URLs (and other share links) when ShareURL was configured with a path prefix like https://example.com/navi — generated URLs pointed to /share/img/... at the root instead of /navi/share/img/... Now the ShareURL path is prepended to the resource path, with trailing slashes trimmed. When ShareURL has no path, behavior is unchanged. --- core/publicurl/publicurl.go | 3 +++ core/publicurl/publicurl_test.go | 25 +++++++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/core/publicurl/publicurl.go b/core/publicurl/publicurl.go index c1b8e01c4..b0865e78b 100644 --- a/core/publicurl/publicurl.go +++ b/core/publicurl/publicurl.go @@ -45,6 +45,9 @@ func PublicURL(req *http.Request, u string, params url.Values) string { } buildUrl.Scheme = shareUrl.Scheme buildUrl.Host = shareUrl.Host + if basePath := strings.TrimRight(shareUrl.Path, "/"); basePath != "" { + buildUrl.Path = path.Join(basePath, buildUrl.Path) + } if len(params) > 0 { buildUrl.RawQuery = params.Encode() } diff --git a/core/publicurl/publicurl_test.go b/core/publicurl/publicurl_test.go index 18f8f8129..a195fb9cd 100644 --- a/core/publicurl/publicurl_test.go +++ b/core/publicurl/publicurl_test.go @@ -56,6 +56,31 @@ var _ = Describe("Public URL Utilities", func() { }) }) + When("ShareURL includes a path", func() { + BeforeEach(func() { + conf.Server.ShareURL = "https://example.com/navi" + }) + + It("prepends the ShareURL path to the resource", func() { + r, _ := http.NewRequest("GET", "http://localhost/test", nil) + result := publicurl.PublicURL(r, "/share/img/hash", nil) + Expect(result).To(Equal("https://example.com/navi/share/img/hash")) + }) + + It("prepends the ShareURL path and includes query parameters", func() { + r, _ := http.NewRequest("GET", "http://localhost/test", nil) + params := url.Values{"size": []string{"600"}} + result := publicurl.PublicURL(r, "/share/img/hash", params) + Expect(result).To(Equal("https://example.com/navi/share/img/hash?size=600")) + }) + + It("handles trailing slash in ShareURL path", func() { + conf.Server.ShareURL = "https://example.com/navi/" + result := publicurl.PublicURL(nil, "/share/img/hash", nil) + Expect(result).To(Equal("https://example.com/navi/share/img/hash")) + }) + }) + When("ShareURL is not set", func() { BeforeEach(func() { conf.Server.ShareURL = ""