move json marshalling and error checking into parsOpenGraphMetadata fn

This commit is contained in:
Christopher Poile 2023-08-04 11:15:04 +09:00
parent d1de4a8fa4
commit ba9a1e13b0
No known key found for this signature in database
GPG Key ID: 9A44D32A3E15A411
3 changed files with 52 additions and 10 deletions

View File

@ -35,17 +35,11 @@ func (a *App) GetOpenGraphMetadata(requestURL string) ([]byte, error) {
} }
defer res.Body.Close() defer res.Body.Close()
graph := a.parseOpenGraphMetadata(requestURL, res.Body, res.Header.Get("Content-Type")) _, ogJSON, err := a.parseOpenGraphMetadata(requestURL, res.Body, res.Header.Get("Content-Type"))
ogJSON, err := graph.ToJSON()
if err != nil { if err != nil {
return nil, err return nil, err
} }
if len(ogJSON) > openGraphMetadataCacheEntrySizeLimit {
return nil, errors.New("opengraph data exceeds cache entry size limit")
}
err = a.Srv().openGraphDataCache.SetWithExpiry(requestURL, ogJSON, 1*time.Hour) err = a.Srv().openGraphDataCache.SetWithExpiry(requestURL, ogJSON, 1*time.Hour)
if err != nil { if err != nil {
return nil, err return nil, err
@ -54,7 +48,7 @@ func (a *App) GetOpenGraphMetadata(requestURL string) ([]byte, error) {
return ogJSON, nil return ogJSON, nil
} }
func (a *App) parseOpenGraphMetadata(requestURL string, body io.Reader, contentType string) *opengraph.OpenGraph { func (a *App) parseOpenGraphMetadata(requestURL string, body io.Reader, contentType string) (*opengraph.OpenGraph, []byte, error) {
og := opengraph.NewOpenGraph() og := opengraph.NewOpenGraph()
body = forceHTMLEncodingToUTF8(io.LimitReader(body, MaxOpenGraphResponseSize), contentType) body = forceHTMLEncodingToUTF8(io.LimitReader(body, MaxOpenGraphResponseSize), contentType)
@ -76,7 +70,16 @@ func (a *App) parseOpenGraphMetadata(requestURL string, body io.Reader, contentT
og.URL = requestURL og.URL = requestURL
} }
return og ogJSON, err := og.ToJSON()
if err != nil {
return nil, nil, err
}
if len(ogJSON) > openGraphMetadataCacheEntrySizeLimit {
return nil, nil, errors.New("opengraph data exceeds cache entry size limit")
}
return og, ogJSON, nil
} }
func forceHTMLEncodingToUTF8(body io.Reader, contentType string) io.Reader { func forceHTMLEncodingToUTF8(body io.Reader, contentType string) io.Reader {

View File

@ -4,6 +4,9 @@
package app package app
import ( import (
"bytes"
"github.com/mattermost/mattermost/server/public/model"
"html/template"
"strings" "strings"
"testing" "testing"
@ -135,3 +138,39 @@ func TestOpenGraphDecodeHTMLEntities(t *testing.T) {
assert.Equal(t, og.Title, "Test's are the best.©") assert.Equal(t, og.Title, "Test's are the best.©")
assert.Equal(t, og.Description, "Test's are the worst.©") assert.Equal(t, og.Description, "Test's are the worst.©")
} }
func TestParseOpenGraphMetadata(t *testing.T) {
th := Setup(t)
defer th.TearDown()
opengraphPage := `<html prefix="og: https://ogp.me/ns#">
<head>
<meta property="og:title" content="{{.Title}}" />
<meta property="og:type" content="video.movie" />
</head></html>
`
sizeOfJsonExceptTitle := 169
type Title struct {
Title string
}
tmpl, err := template.New("Test").Parse(opengraphPage)
assert.NoError(t, err)
page := new(bytes.Buffer)
title := Title{Title: model.NewRandomString(openGraphMetadataCacheEntrySizeLimit - sizeOfJsonExceptTitle + 1)}
err = tmpl.Execute(page, title)
assert.NoError(t, err)
_, _, err = th.App.parseOpenGraphMetadata("https://example.com", page, "")
assert.Error(t, err)
assert.Equal(t, err.Error(), "opengraph data exceeds cache entry size limit")
page.Reset()
title.Title = title.Title[1:]
err = tmpl.Execute(page, title)
assert.NoError(t, err)
_, _, err = th.App.parseOpenGraphMetadata("https://example.com", page, "")
assert.NoError(t, err)
}

View File

@ -800,7 +800,7 @@ func (a *App) parseLinkMetadata(requestURL string, body io.Reader, contentType s
image, err := parseImages(io.LimitReader(body, MaxMetadataImageSize)) image, err := parseImages(io.LimitReader(body, MaxMetadataImageSize))
return nil, image, err return nil, image, err
} else if strings.HasPrefix(contentType, "text/html") { } else if strings.HasPrefix(contentType, "text/html") {
og := a.parseOpenGraphMetadata(requestURL, body, contentType) og, _, _ := a.parseOpenGraphMetadata(requestURL, body, contentType)
// The OpenGraph library and Go HTML library don't error for malformed input, so check that at least // The OpenGraph library and Go HTML library don't error for malformed input, so check that at least
// one of these required fields exists before returning the OpenGraph data // one of these required fields exists before returning the OpenGraph data