diff --git a/app/post_metadata.go b/app/post_metadata.go index 2696e3ce36..798233e70e 100644 --- a/app/post_metadata.go +++ b/app/post_metadata.go @@ -7,6 +7,7 @@ import ( "image" "io" "net/http" + "net/url" "strings" "github.com/dyatlov/go-opengraph/opengraph" @@ -315,6 +316,8 @@ func getImagesInMessageAttachments(post *model.Post) []string { } func (a *App) getLinkMetadata(requestURL string, useCache bool) (*opengraph.OpenGraph, *model.PostImage, error) { + requestURL = resolveMetadataURL(requestURL, a.GetSiteURL()) + // Check cache if useCache { og, image, ok := getLinkMetadataFromCache(requestURL) @@ -349,6 +352,21 @@ func (a *App) getLinkMetadata(requestURL string, useCache bool) (*opengraph.Open return og, image, err } +// resolveMetadataURL resolves a given URL relative to the server's site URL. +func resolveMetadataURL(requestURL string, siteURL string) string { + base, err := url.Parse(siteURL) + if err != nil { + return "" + } + + resolved, err := base.Parse(requestURL) + if err != nil { + return "" + } + + return resolved.String() +} + func getLinkMetadataFromCache(requestURL string) (*opengraph.OpenGraph, *model.PostImage, bool) { cached, ok := linkCache.Get(requestURL) if !ok { diff --git a/app/post_metadata_test.go b/app/post_metadata_test.go index d258ffe8a1..5adb7506df 100644 --- a/app/post_metadata_test.go +++ b/app/post_metadata_test.go @@ -994,6 +994,47 @@ func TestGetImagesInMessageAttachments(t *testing.T) { } } +func TestResolveMetadataURL(t *testing.T) { + for _, test := range []struct { + Name string + RequestURL string + SiteURL string + Expected string + }{ + { + Name: "with HTTPS", + RequestURL: "https://example.com/file?param=1", + Expected: "https://example.com/file?param=1", + }, + { + Name: "with HTTP", + RequestURL: "http://example.com/file?param=1", + Expected: "http://example.com/file?param=1", + }, + { + Name: "with FTP", + RequestURL: "ftp://example.com/file?param=1", + Expected: "ftp://example.com/file?param=1", + }, + { + Name: "relative to root", + RequestURL: "/file?param=1", + SiteURL: "https://mattermost.example.com:123", + Expected: "https://mattermost.example.com:123/file?param=1", + }, + { + Name: "relative to root with subpath", + RequestURL: "/file?param=1", + SiteURL: "https://mattermost.example.com:123/subpath", + Expected: "https://mattermost.example.com:123/file?param=1", + }, + } { + t.Run(test.Name, func(t *testing.T) { + assert.Equal(t, resolveMetadataURL(test.RequestURL, test.SiteURL), test.Expected) + }) + } +} + func TestParseLinkMetadata(t *testing.T) { th := Setup().InitBasic() defer th.TearDown()