diff --git a/app/file.go b/app/file.go index 3dc20d4f37..056c70fe0e 100644 --- a/app/file.go +++ b/app/file.go @@ -647,6 +647,11 @@ func (a *App) UploadFileX(channelId, name string, input io.Reader, func (t *uploadFileTask) readAll() *model.AppError { _, err := t.buf.ReadFrom(t.limitedInput) if err != nil { + // Ugly hack: the error is not exported from net/http. + if err.Error() == "http: request body too large" { + return t.newAppError("api.file.upload_file.too_large_detailed.app_error", + "", http.StatusRequestEntityTooLarge, "Length", t.buf.Len(), "Limit", t.limit) + } return t.newAppError("api.file.upload_file.read_request.app_error", err.Error(), http.StatusBadRequest) } diff --git a/web/handlers.go b/web/handlers.go index ac650836fc..59a396f7ec 100644 --- a/web/handlers.go +++ b/web/handlers.go @@ -4,6 +4,7 @@ package web import ( + "bytes" "fmt" "net/http" "reflect" @@ -90,6 +91,14 @@ func (h Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { c.App.Path = r.URL.Path c.Log = c.App.Log + // Set the max request body size to be equal to MaxFileSize. + // Ideally, non-file request bodies should be smaller than file request bodies, + // but we don't have a clean way to identify all file upload handlers. + // So to keep it simple, we clamp it to the max file size. + // We add a buffer of bytes.MinRead so that file sizes close to max file size + // do not get cut off. + r.Body = http.MaxBytesReader(w, r.Body, *c.App.Config().FileSettings.MaxFileSize+bytes.MinRead) + subpath, _ := utils.GetSubpathFromConfig(c.App.Config()) siteURLHeader := app.GetProtocol(r) + "://" + r.Host + subpath c.SetSiteURLHeader(siteURLHeader)