From 388dfdfbca766d1f7c0be18eee37fd32331e0a94 Mon Sep 17 00:00:00 2001 From: daveseo901 <55063490+daveseo901@users.noreply.github.com> Date: Mon, 9 Sep 2024 08:00:25 -0400 Subject: [PATCH] [MM-56792] Clarify large plugin upload error (#26271) Co-authored-by: Ben Schumacher --- server/channels/api4/plugin.go | 9 +++++++-- server/channels/api4/plugin_test.go | 17 +++++++++++++++++ server/channels/testlib/resources.go | 1 + server/i18n/en.json | 4 ++++ 4 files changed, 29 insertions(+), 2 deletions(-) diff --git a/server/channels/api4/plugin.go b/server/channels/api4/plugin.go index 849c512f0e..972fe46f06 100644 --- a/server/channels/api4/plugin.go +++ b/server/channels/api4/plugin.go @@ -20,7 +20,8 @@ import ( ) const ( - MaximumPluginFileSize = 50 * 1024 * 1024 + // MaxPluginMemory is the maximum number of bytes to hold in memory when reading a plugin bundle. + MaxPluginMemory = 50 * 1024 * 1024 ) func (api *API) InitPlugin() { @@ -57,7 +58,11 @@ func uploadPlugin(c *Context, w http.ResponseWriter, r *http.Request) { return } - if err := r.ParseMultipartForm(MaximumPluginFileSize); err != nil { + if err := r.ParseMultipartForm(MaxPluginMemory); err != nil { + if err.Error() == "http: request body too large" { + c.Err = model.NewAppError("uploadPlugin", "api.plugin.upload.file_too_large.app_error", nil, "", http.StatusRequestEntityTooLarge) + return + } http.Error(w, err.Error(), http.StatusBadRequest) return } diff --git a/server/channels/api4/plugin_test.go b/server/channels/api4/plugin_test.go index ce7e66836a..71a1349bdb 100644 --- a/server/channels/api4/plugin_test.go +++ b/server/channels/api4/plugin_test.go @@ -126,6 +126,23 @@ func TestPlugin(t *testing.T) { require.Error(t, err) CheckBadRequestStatus(t, resp) + plugin_sz := int64(111 * 1024 * 1024) + fd, err := os.Create(filepath.Join(path, "big_testplugin.tar.gz")) + require.NoError(t, err) + _, err = fd.Seek(plugin_sz-1, 0) + require.NoError(t, err) + _, err = fd.Write([]byte{0}) + require.NoError(t, err) + err = fd.Close() + require.NoError(t, err) + bigData, err := os.ReadFile(filepath.Join(path, "big_testplugin.tar.gz")) + require.NoError(t, err) + _, resp, err = client.UploadPlugin(context.Background(), bytes.NewReader(bigData)) + require.Error(t, err) + CheckRequestEntityTooLargeStatus(t, resp) + err = os.Remove(filepath.Join(path, "big_testplugin.tar.gz")) + require.NoError(t, err) + th.App.UpdateConfig(func(cfg *model.Config) { *cfg.PluginSettings.Enable = false }) _, resp, err = client.UploadPlugin(context.Background(), bytes.NewReader(tarData)) require.Error(t, err) diff --git a/server/channels/testlib/resources.go b/server/channels/testlib/resources.go index 3468c4278f..fd3640510b 100644 --- a/server/channels/testlib/resources.go +++ b/server/channels/testlib/resources.go @@ -83,6 +83,7 @@ func getTestResourcesToSetup() []testResourceDetails { {"templates", "templates", resourceTypeFolder, actionSymlink}, {"tests", "tests", resourceTypeFolder, actionSymlink}, {"fonts", "fonts", resourceTypeFolder, actionSymlink}, + {"channels/app/plugin_api_tests", "channels/app/plugin_api_tests", resourceTypeFolder, actionSymlink}, {"channels/utils/policies-roles-mapping.json", "channels/utils/policies-roles-mapping.json", resourceTypeFile, actionSymlink}, } diff --git a/server/i18n/en.json b/server/i18n/en.json index 3f385a63d8..98ff80a2ad 100644 --- a/server/i18n/en.json +++ b/server/i18n/en.json @@ -2448,6 +2448,10 @@ "id": "api.plugin.upload.file.app_error", "translation": "Unable to open file in multipart/form request." }, + { + "id": "api.plugin.upload.file_too_large.app_error", + "translation": "Uploaded plugin size exceeds limit. This limit can be changed in the System Console via File Storage > Maximum File Size" + }, { "id": "api.plugin.upload.no_file.app_error", "translation": "Missing file in multipart/form request."