diff options
Diffstat (limited to 'app')
-rw-r--r-- | app/post.go | 54 | ||||
-rw-r--r-- | app/post_test.go | 92 |
2 files changed, 142 insertions, 4 deletions
diff --git a/app/post.go b/app/post.go index be9374e10..1964bd3cf 100644 --- a/app/post.go +++ b/app/post.go @@ -12,6 +12,7 @@ import ( "encoding/json" "fmt" "net/http" + "net/url" "regexp" "strings" @@ -734,23 +735,68 @@ func (a *App) GetFileInfosForPost(postId string, readFromMaster bool) ([]*model. return infos, nil } -func (a *App) GetOpenGraphMetadata(url string) *opengraph.OpenGraph { +func (a *App) GetOpenGraphMetadata(requestURL string) *opengraph.OpenGraph { og := opengraph.NewOpenGraph() - res, err := a.HTTPClient(false).Get(url) + res, err := a.HTTPClient(false).Get(requestURL) if err != nil { - l4g.Error("GetOpenGraphMetadata request failed for url=%v with err=%v", url, err.Error()) + l4g.Error("GetOpenGraphMetadata request failed for url=%v with err=%v", requestURL, err.Error()) return og } defer consumeAndClose(res) if err := og.ProcessHTML(res.Body); err != nil { - l4g.Error("GetOpenGraphMetadata processing failed for url=%v with err=%v", url, err.Error()) + l4g.Error("GetOpenGraphMetadata processing failed for url=%v with err=%v", requestURL, err.Error()) } + makeOpenGraphURLsAbsolute(og, requestURL) + return og } +func makeOpenGraphURLsAbsolute(og *opengraph.OpenGraph, requestURL string) { + parsedRequestURL, err := url.Parse(requestURL) + if err != nil { + l4g.Warn("makeOpenGraphURLsAbsolute failed to parse url=%v", requestURL) + return + } + + makeURLAbsolute := func(resultURL string) string { + if resultURL == "" { + return resultURL + } + + parsedResultURL, err := url.Parse(resultURL) + if err != nil { + l4g.Warn("makeOpenGraphURLsAbsolute failed to parse result url=%v", resultURL) + return resultURL + } + + if parsedResultURL.IsAbs() { + return resultURL + } + + return parsedRequestURL.ResolveReference(parsedResultURL).String() + } + + og.URL = makeURLAbsolute(og.URL) + + for _, image := range og.Images { + image.URL = makeURLAbsolute(image.URL) + image.SecureURL = makeURLAbsolute(image.SecureURL) + } + + for _, audio := range og.Audios { + audio.URL = makeURLAbsolute(audio.URL) + audio.SecureURL = makeURLAbsolute(audio.SecureURL) + } + + for _, video := range og.Videos { + video.URL = makeURLAbsolute(video.URL) + video.SecureURL = makeURLAbsolute(video.SecureURL) + } +} + func (a *App) DoPostAction(postId string, actionId string, userId string) *model.AppError { pchan := a.Srv.Store.Post().GetSingle(postId) diff --git a/app/post_test.go b/app/post_test.go index 409bc043d..c8ed726b1 100644 --- a/app/post_test.go +++ b/app/post_test.go @@ -8,9 +8,11 @@ import ( "fmt" "net/http" "net/http/httptest" + "strings" "testing" "time" + "github.com/dyatlov/go-opengraph/opengraph" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -266,6 +268,96 @@ func TestImageProxy(t *testing.T) { } } +func TestMakeOpenGraphURLsAbsolute(t *testing.T) { + for name, tc := range map[string]struct { + HTML string + RequestURL string + URL string + ImageURL string + }{ + "absolute URLs": { + HTML: ` + <html> + <head> + <meta property="og:url" content="https://example.com/apps/mattermost"> + <meta property="og:image" content="https://images.example.com/image.png"> + </head> + </html>`, + RequestURL: "https://example.com", + URL: "https://example.com/apps/mattermost", + ImageURL: "https://images.example.com/image.png", + }, + "URLs starting with /": { + HTML: ` + <html> + <head> + <meta property="og:url" content="/apps/mattermost"> + <meta property="og:image" content="/image.png"> + </head> + </html>`, + RequestURL: "http://example.com", + URL: "http://example.com/apps/mattermost", + ImageURL: "http://example.com/image.png", + }, + "HTTPS URLs starting with /": { + HTML: ` + <html> + <head> + <meta property="og:url" content="/apps/mattermost"> + <meta property="og:image" content="/image.png"> + </head> + </html>`, + RequestURL: "https://example.com", + URL: "https://example.com/apps/mattermost", + ImageURL: "https://example.com/image.png", + }, + "missing image URL": { + HTML: ` + <html> + <head> + <meta property="og:url" content="/apps/mattermost"> + </head> + </html>`, + RequestURL: "http://example.com", + URL: "http://example.com/apps/mattermost", + ImageURL: "", + }, + "relative URLs": { + HTML: ` + <html> + <head> + <meta property="og:url" content="index.html"> + <meta property="og:image" content="../resources/image.png"> + </head> + </html>`, + RequestURL: "http://example.com/content/index.html", + URL: "http://example.com/content/index.html", + ImageURL: "http://example.com/resources/image.png", + }, + } { + t.Run(name, func(t *testing.T) { + og := opengraph.NewOpenGraph() + if err := og.ProcessHTML(strings.NewReader(tc.HTML)); err != nil { + t.Fatal(err) + } + + makeOpenGraphURLsAbsolute(og, tc.RequestURL) + + if og.URL != tc.URL { + t.Fatalf("incorrect url, expected %v, got %v", tc.URL, og.URL) + } + + if len(og.Images) > 0 { + if og.Images[0].URL != tc.ImageURL { + t.Fatalf("incorrect image url, expected %v, got %v", tc.ImageURL, og.Images[0].URL) + } + } else if tc.ImageURL != "" { + t.Fatalf("missing image url, expected %v, got nothing", tc.ImageURL) + } + }) + } +} + var imageProxyBenchmarkSink *model.Post func BenchmarkPostWithProxyRemovedFromImageURLs(b *testing.B) { |