PLT-5455 Added caching for OG metadata of link preview. (#5361)
Этот коммит содержится в:
коммит произвёл
Joram Wilander
родитель
37222ec1b3
Коммит
eab15da321
18
api/post.go
18
api/post.go
@@ -14,6 +14,10 @@ import (
|
|||||||
"github.com/mattermost/platform/utils"
|
"github.com/mattermost/platform/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const OPEN_GRAPH_METADATA_CACHE_SIZE = 10000
|
||||||
|
|
||||||
|
var openGraphDataCache = utils.NewLru(OPEN_GRAPH_METADATA_CACHE_SIZE)
|
||||||
|
|
||||||
func InitPost() {
|
func InitPost() {
|
||||||
l4g.Debug(utils.T("api.post.init.debug"))
|
l4g.Debug(utils.T("api.post.init.debug"))
|
||||||
|
|
||||||
@@ -432,8 +436,14 @@ func getFileInfosForPost(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
func getOpenGraphMetadata(c *Context, w http.ResponseWriter, r *http.Request) {
|
func getOpenGraphMetadata(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||||
props := model.StringInterfaceFromJson(r.Body)
|
props := model.StringInterfaceFromJson(r.Body)
|
||||||
|
|
||||||
|
ogJSONGeneric, ok := openGraphDataCache.Get(props["url"])
|
||||||
|
if ok {
|
||||||
|
w.Write(ogJSONGeneric.([]byte))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
url := ""
|
url := ""
|
||||||
ok := false
|
ok = false
|
||||||
if url, ok = props["url"].(string); len(url) == 0 || !ok {
|
if url, ok = props["url"].(string); len(url) == 0 || !ok {
|
||||||
c.SetInvalidParam("getOpenGraphMetadata", "url")
|
c.SetInvalidParam("getOpenGraphMetadata", "url")
|
||||||
return
|
return
|
||||||
@@ -441,10 +451,12 @@ func getOpenGraphMetadata(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
og := app.GetOpenGraphMetadata(url)
|
og := app.GetOpenGraphMetadata(url)
|
||||||
|
|
||||||
ogJson, err := og.ToJSON()
|
ogJSON, err := og.ToJSON()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.Write([]byte(`{"url": ""}`))
|
w.Write([]byte(`{"url": ""}`))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
w.Write(ogJson)
|
|
||||||
|
openGraphDataCache.AddWithExpiresInSecs(props["url"], ogJSON, 3600) // Cache would expire after 1 houre
|
||||||
|
w.Write(ogJSON)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1306,7 +1306,11 @@ func TestGetOpenGraphMetadata(t *testing.T) {
|
|||||||
th := Setup().InitBasic()
|
th := Setup().InitBasic()
|
||||||
Client := th.BasicClient
|
Client := th.BasicClient
|
||||||
|
|
||||||
|
ogDataCacheMissCount := 0
|
||||||
|
|
||||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
ogDataCacheMissCount++
|
||||||
|
|
||||||
if r.URL.Path == "/og-data/" {
|
if r.URL.Path == "/og-data/" {
|
||||||
fmt.Fprintln(w, `
|
fmt.Fprintln(w, `
|
||||||
<html><head><meta property="og:type" content="article" />
|
<html><head><meta property="og:type" content="article" />
|
||||||
@@ -1319,15 +1323,35 @@ func TestGetOpenGraphMetadata(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
|
|
||||||
for _, data := range [](map[string]string){{"path": "/og-data/", "title": "Test Title"}, {"path": "/no-og-data/", "title": ""}} {
|
for _, data := range [](map[string]interface{}){
|
||||||
res, err := Client.DoApiPost("/get_opengraph_metadata", fmt.Sprintf("{\"url\":\"%s\"}", ts.URL+data["path"]))
|
{"path": "/og-data/", "title": "Test Title", "cacheMissCount": 1},
|
||||||
|
{"path": "/no-og-data/", "title": "", "cacheMissCount": 2},
|
||||||
|
|
||||||
|
// Data should be cached for following
|
||||||
|
{"path": "/og-data/", "title": "Test Title", "cacheMissCount": 2},
|
||||||
|
{"path": "/no-og-data/", "title": "", "cacheMissCount": 2},
|
||||||
|
} {
|
||||||
|
res, err := Client.DoApiPost(
|
||||||
|
"/get_opengraph_metadata",
|
||||||
|
fmt.Sprintf("{\"url\":\"%s\"}", ts.URL+data["path"].(string)),
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
ogData := model.StringInterfaceFromJson(res.Body)
|
ogData := model.StringInterfaceFromJson(res.Body)
|
||||||
if strings.Compare(ogData["title"].(string), data["title"]) != 0 {
|
if strings.Compare(ogData["title"].(string), data["title"].(string)) != 0 {
|
||||||
t.Fatal(fmt.Sprintf("OG data title mismatch for path \"%s\". Expected title: \"%s\". Actual title: \"%s\"", data["path"], data["title"], ogData["title"]))
|
t.Fatal(fmt.Sprintf(
|
||||||
|
"OG data title mismatch for path \"%s\". Expected title: \"%s\". Actual title: \"%s\"",
|
||||||
|
data["path"].(string), data["title"].(string), ogData["title"].(string),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
if ogDataCacheMissCount != data["cacheMissCount"].(int) {
|
||||||
|
t.Fatal(fmt.Sprintf(
|
||||||
|
"Cache miss count didn't match. Expected value %d. Actual value %d.",
|
||||||
|
data["cacheMissCount"].(int), ogDataCacheMissCount,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user