diff --git a/server/channels/app/post_metadata.go b/server/channels/app/post_metadata.go index 460354eaa5..9048f3c5d3 100644 --- a/server/channels/app/post_metadata.go +++ b/server/channels/app/post_metadata.go @@ -4,6 +4,7 @@ package app import ( + "bufio" "bytes" "fmt" "image" @@ -764,7 +765,24 @@ func cacheLinkMetadata(requestURL string, timestamp int64, og *opengraph.OpenGra platform.LinkCache().SetWithExpiry(strconv.FormatInt(model.GenerateLinkMetadataHash(requestURL, timestamp), 16), metadata, platform.LinkCacheDuration) } +// peekContentType peeks at the first 512 bytes of p, and attempts to detect +// the content type. Returns empty string if error occurs. +func peekContentType(p *bufio.Reader) string { + byt, err := p.Peek(512) + if err != nil && err != bufio.ErrBufferFull && err != io.EOF { + return "" + } + return http.DetectContentType(byt) +} + func (a *App) parseLinkMetadata(requestURL string, body io.Reader, contentType string) (*opengraph.OpenGraph, *model.PostImage, error) { + if contentType == "" { + bufRd := bufio.NewReader(body) + // If the content-type is missing we try to detect it from the actual data. + contentType = peekContentType(bufRd) + body = bufRd + } + if contentType == "image/svg+xml" { image := &model.PostImage{ Format: "svg", diff --git a/server/channels/app/post_metadata_test.go b/server/channels/app/post_metadata_test.go index 8ee5f71d3b..9b3e0602fa 100644 --- a/server/channels/app/post_metadata_test.go +++ b/server/channels/app/post_metadata_test.go @@ -2595,6 +2595,18 @@ func TestParseLinkMetadata(t *testing.T) { }, dimensions) }) + t.Run("image with no content-type given", func(t *testing.T) { + og, dimensions, err := th.App.parseLinkMetadata(imageURL, makeImageReader(), "") + assert.NoError(t, err) + + assert.Nil(t, og) + assert.Equal(t, &model.PostImage{ + Format: "png", + Width: 408, + Height: 336, + }, dimensions) + }) + t.Run("malformed image", func(t *testing.T) { og, dimensions, err := th.App.parseLinkMetadata(imageURL, makeOpenGraphReader(), "image/png") assert.Error(t, err)