Exclude sending file metadata to plugin hooks (#18454)
* Exclude sending file metadata to plugin hooks A FileInfo object contained a MiniPreview which is a slice of bytes. This can be particularly costly while marshalling to plugin hooks. We avoid this by refactoring the Embeds and Images population to a separate method and calling that to prevent posts from getting updated. https://community-daily.mattermost.com/boards/workspace/zyoahc9uapdn3xdptac6jb69ic/285b80a3-257d-41f6-8cf4-ed80ca9d92e5/495cdb4d-c13a-4992-8eb9-80cfee2819a4?c=9c0b5413-5401-4ef2-83d5-b9f756585bbc ```release-note NONE ``` * refactor to separate method ```release-note NONE ```
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
ef639973b7
Коммит
225461fd7e
@@ -128,7 +128,7 @@ func createEphemeralPost(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
w.WriteHeader(http.StatusCreated)
|
w.WriteHeader(http.StatusCreated)
|
||||||
rp = model.AddPostActionCookies(rp, c.App.PostActionCookieSecret())
|
rp = model.AddPostActionCookies(rp, c.App.PostActionCookieSecret())
|
||||||
rp = c.App.PreparePostForClient(rp, true, false)
|
rp = c.App.PreparePostForClientWithEmbedsAndImages(rp, true, false)
|
||||||
rp, err := c.App.SanitizePostMetadataForUser(rp, c.AppContext.Session().UserId)
|
rp, err := c.App.SanitizePostMetadataForUser(rp, c.AppContext.Session().UserId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Err = err
|
c.Err = err
|
||||||
@@ -376,7 +376,7 @@ func getPost(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
post = c.App.PreparePostForClient(post, false, false)
|
post = c.App.PreparePostForClientWithEmbedsAndImages(post, false, false)
|
||||||
post, err = c.App.SanitizePostMetadataForUser(post, c.AppContext.Session().UserId)
|
post, err = c.App.SanitizePostMetadataForUser(post, c.AppContext.Session().UserId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Err = err
|
c.Err = err
|
||||||
|
|||||||
@@ -880,7 +880,8 @@ type AppIface interface {
|
|||||||
PostUpdateChannelPurposeMessage(c *request.Context, userID string, channel *model.Channel, oldChannelPurpose string, newChannelPurpose string) *model.AppError
|
PostUpdateChannelPurposeMessage(c *request.Context, userID string, channel *model.Channel, oldChannelPurpose string, newChannelPurpose string) *model.AppError
|
||||||
PostWithProxyAddedToImageURLs(post *model.Post) *model.Post
|
PostWithProxyAddedToImageURLs(post *model.Post) *model.Post
|
||||||
PostWithProxyRemovedFromImageURLs(post *model.Post) *model.Post
|
PostWithProxyRemovedFromImageURLs(post *model.Post) *model.Post
|
||||||
PreparePostForClient(originalPost *model.Post, isNewPost bool, isEditPost bool) *model.Post
|
PreparePostForClient(originalPost *model.Post, isNewPost, isEditPost bool) *model.Post
|
||||||
|
PreparePostForClientWithEmbedsAndImages(originalPost *model.Post, isNewPost, isEditPost bool) *model.Post
|
||||||
PreparePostListForClient(originalList *model.PostList) *model.PostList
|
PreparePostListForClient(originalList *model.PostList) *model.PostList
|
||||||
ProcessSlackText(text string) string
|
ProcessSlackText(text string) string
|
||||||
Publish(message *model.WebSocketEvent)
|
Publish(message *model.WebSocketEvent)
|
||||||
|
|||||||
@@ -12220,6 +12220,23 @@ func (a *OpenTracingAppLayer) PreparePostForClient(originalPost *model.Post, isN
|
|||||||
return resultVar0
|
return resultVar0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *OpenTracingAppLayer) PreparePostForClientWithEmbedsAndImages(originalPost *model.Post, isNewPost bool, isEditPost bool) *model.Post {
|
||||||
|
origCtx := a.ctx
|
||||||
|
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.PreparePostForClientWithEmbedsAndImages")
|
||||||
|
|
||||||
|
a.ctx = newCtx
|
||||||
|
a.app.Srv().Store.SetContext(newCtx)
|
||||||
|
defer func() {
|
||||||
|
a.app.Srv().Store.SetContext(origCtx)
|
||||||
|
a.ctx = origCtx
|
||||||
|
}()
|
||||||
|
|
||||||
|
defer span.Finish()
|
||||||
|
resultVar0 := a.app.PreparePostForClientWithEmbedsAndImages(originalPost, isNewPost, isEditPost)
|
||||||
|
|
||||||
|
return resultVar0
|
||||||
|
}
|
||||||
|
|
||||||
func (a *OpenTracingAppLayer) PreparePostListForClient(originalList *model.PostList) *model.PostList {
|
func (a *OpenTracingAppLayer) PreparePostListForClient(originalList *model.PostList) *model.PostList {
|
||||||
origCtx := a.ctx
|
origCtx := a.ctx
|
||||||
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.PreparePostListForClient")
|
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.PreparePostListForClient")
|
||||||
|
|||||||
@@ -297,7 +297,7 @@ func (a *App) CreatePost(c *request.Context, post *model.Post, channel *model.Ch
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
post = a.PreparePostForClient(post, true, false)
|
post = a.getEmbedsAndImages(post, true)
|
||||||
previewPost := post.GetPreviewPost()
|
previewPost := post.GetPreviewPost()
|
||||||
if previewPost != nil {
|
if previewPost != nil {
|
||||||
post.AddProp(model.PostPropsPreviewedPost, previewPost.PostID)
|
post.AddProp(model.PostPropsPreviewedPost, previewPost.PostID)
|
||||||
@@ -521,7 +521,7 @@ func (a *App) SendEphemeralPost(userID string, post *model.Post) *model.Post {
|
|||||||
|
|
||||||
post.GenerateActionIds()
|
post.GenerateActionIds()
|
||||||
message := model.NewWebSocketEvent(model.WebsocketEventEphemeralMessage, "", post.ChannelId, userID, nil)
|
message := model.NewWebSocketEvent(model.WebsocketEventEphemeralMessage, "", post.ChannelId, userID, nil)
|
||||||
post = a.PreparePostForClient(post, true, false)
|
post = a.PreparePostForClientWithEmbedsAndImages(post, true, false)
|
||||||
post = model.AddPostActionCookies(post, a.PostActionCookieSecret())
|
post = model.AddPostActionCookies(post, a.PostActionCookieSecret())
|
||||||
|
|
||||||
postJSON, jsonErr := post.ToJSON()
|
postJSON, jsonErr := post.ToJSON()
|
||||||
@@ -544,7 +544,7 @@ func (a *App) UpdateEphemeralPost(userID string, post *model.Post) *model.Post {
|
|||||||
|
|
||||||
post.GenerateActionIds()
|
post.GenerateActionIds()
|
||||||
message := model.NewWebSocketEvent(model.WebsocketEventPostEdited, "", post.ChannelId, userID, nil)
|
message := model.NewWebSocketEvent(model.WebsocketEventPostEdited, "", post.ChannelId, userID, nil)
|
||||||
post = a.PreparePostForClient(post, true, false)
|
post = a.PreparePostForClientWithEmbedsAndImages(post, true, false)
|
||||||
post = model.AddPostActionCookies(post, a.PostActionCookieSecret())
|
post = model.AddPostActionCookies(post, a.PostActionCookieSecret())
|
||||||
postJSON, jsonErr := post.ToJSON()
|
postJSON, jsonErr := post.ToJSON()
|
||||||
if jsonErr != nil {
|
if jsonErr != nil {
|
||||||
@@ -685,7 +685,7 @@ func (a *App) UpdatePost(c *request.Context, post *model.Post, safeUpdate bool)
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
rpost = a.PreparePostForClient(rpost, false, true)
|
rpost = a.PreparePostForClientWithEmbedsAndImages(rpost, false, true)
|
||||||
|
|
||||||
// Ensure IsFollowing is nil since this updated post will be broadcast to all users
|
// Ensure IsFollowing is nil since this updated post will be broadcast to all users
|
||||||
// and we don't want to have to populate it for every single user and broadcast to each
|
// and we don't want to have to populate it for every single user and broadcast to each
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ func (a *App) PreparePostListForClient(originalList *model.PostList) *model.Post
|
|||||||
}
|
}
|
||||||
|
|
||||||
for id, originalPost := range originalList.Posts {
|
for id, originalPost := range originalList.Posts {
|
||||||
post := a.PreparePostForClient(originalPost, false, false)
|
post := a.PreparePostForClientWithEmbedsAndImages(originalPost, false, false)
|
||||||
|
|
||||||
list.Posts[id] = post
|
list.Posts[id] = post
|
||||||
}
|
}
|
||||||
@@ -94,15 +94,16 @@ func (a *App) OverrideIconURLIfEmoji(post *model.Post) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *App) PreparePostForClient(originalPost *model.Post, isNewPost bool, isEditPost bool) *model.Post {
|
func (a *App) PreparePostForClient(originalPost *model.Post, isNewPost, isEditPost bool) *model.Post {
|
||||||
post := originalPost.Clone()
|
post := originalPost.Clone()
|
||||||
|
|
||||||
// Proxy image links before constructing metadata so that requests go through the proxy
|
// Proxy image links before constructing metadata so that requests go through the proxy
|
||||||
post = a.PostWithProxyAddedToImageURLs(post)
|
post = a.PostWithProxyAddedToImageURLs(post)
|
||||||
|
|
||||||
a.OverrideIconURLIfEmoji(post)
|
a.OverrideIconURLIfEmoji(post)
|
||||||
|
if post.Metadata == nil {
|
||||||
post.Metadata = &model.PostMetadata{}
|
post.Metadata = &model.PostMetadata{}
|
||||||
|
}
|
||||||
|
|
||||||
if post.DeleteAt > 0 {
|
if post.DeleteAt > 0 {
|
||||||
// For deleted posts we don't fill out metadata nor do we return the post content
|
// For deleted posts we don't fill out metadata nor do we return the post content
|
||||||
@@ -125,9 +126,22 @@ func (a *App) PreparePostForClient(originalPost *model.Post, isNewPost bool, isE
|
|||||||
post.Metadata.Files = fileInfos
|
post.Metadata.Files = fileInfos
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return post
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *App) PreparePostForClientWithEmbedsAndImages(originalPost *model.Post, isNewPost, isEditPost bool) *model.Post {
|
||||||
|
post := a.PreparePostForClient(originalPost, isNewPost, isEditPost)
|
||||||
|
post = a.getEmbedsAndImages(post, true)
|
||||||
|
return post
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *App) getEmbedsAndImages(post *model.Post, isNewPost bool) *model.Post {
|
||||||
|
if post.Metadata == nil {
|
||||||
|
post.Metadata = &model.PostMetadata{}
|
||||||
|
}
|
||||||
|
|
||||||
// Embeds and image dimensions
|
// Embeds and image dimensions
|
||||||
firstLink, images := a.getFirstLinkAndImages(post.Message)
|
firstLink, images := a.getFirstLinkAndImages(post.Message)
|
||||||
|
|
||||||
if embed, err := a.getEmbedForPost(post, firstLink, isNewPost); err != nil {
|
if embed, err := a.getEmbedForPost(post, firstLink, isNewPost); err != nil {
|
||||||
appErr, ok := err.(*model.AppError)
|
appErr, ok := err.(*model.AppError)
|
||||||
isNotFound := ok && appErr.StatusCode == http.StatusNotFound
|
isNotFound := ok && appErr.StatusCode == http.StatusNotFound
|
||||||
@@ -142,7 +156,6 @@ func (a *App) PreparePostForClient(originalPost *model.Post, isNewPost bool, isE
|
|||||||
}
|
}
|
||||||
|
|
||||||
post.Metadata.Images = a.getImagesForPost(post, images, isNewPost)
|
post.Metadata.Images = a.getImagesForPost(post, images, isNewPost)
|
||||||
|
|
||||||
return post
|
return post
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ func TestPreparePostForClient(t *testing.T) {
|
|||||||
Message: message,
|
Message: message,
|
||||||
}
|
}
|
||||||
|
|
||||||
clientPost := th.App.PreparePostForClient(post, false, false)
|
clientPost := th.App.PreparePostForClient(post, false, true)
|
||||||
|
|
||||||
t.Run("doesn't mutate provided post", func(t *testing.T) {
|
t.Run("doesn't mutate provided post", func(t *testing.T) {
|
||||||
assert.NotEqual(t, clientPost, post, "should've returned a new post")
|
assert.NotEqual(t, clientPost, post, "should've returned a new post")
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user