From 8387d92ea22562162a00fae60286dc6ec68942c1 Mon Sep 17 00:00:00 2001 From: Hyeseong Kim Date: Wed, 25 Jul 2018 03:23:54 +0900 Subject: MM-10381: Change the file downloading API to stream file (#9144) * Change the file downloading to stream file * Change file downloading to chunk only for preview * Remove unnecessary else case --- api4/file.go | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) (limited to 'api4') diff --git a/api4/file.go b/api4/file.go index ab0fbce14..dba8b8649 100644 --- a/api4/file.go +++ b/api4/file.go @@ -154,14 +154,14 @@ func getFile(c *Context, w http.ResponseWriter, r *http.Request) { return } - data, err := c.App.ReadFile(info.Path) + fileReader, err := c.App.FileReader(info.Path) if err != nil { c.Err = err c.Err.StatusCode = http.StatusNotFound return } - err = writeFileResponse(info.Name, info.MimeType, data, forceDownload, w, r) + err = writeFileResponse(info.Name, info.MimeType, info.Size, fileReader, forceDownload, w, r) if err != nil { c.Err = err return @@ -195,10 +195,10 @@ func getFileThumbnail(c *Context, w http.ResponseWriter, r *http.Request) { return } - if data, err := c.App.ReadFile(info.ThumbnailPath); err != nil { + if fileReader, err := c.App.FileReader(info.ThumbnailPath); err != nil { c.Err = err c.Err.StatusCode = http.StatusNotFound - } else if err := writeFileResponse(info.Name, THUMBNAIL_IMAGE_TYPE, data, forceDownload, w, r); err != nil { + } else if err := writeFileResponse(info.Name, THUMBNAIL_IMAGE_TYPE, 0, fileReader, forceDownload, w, r); err != nil { c.Err = err return } @@ -264,10 +264,10 @@ func getFilePreview(c *Context, w http.ResponseWriter, r *http.Request) { return } - if data, err := c.App.ReadFile(info.PreviewPath); err != nil { + if fileReader, err := c.App.FileReader(info.PreviewPath); err != nil { c.Err = err c.Err.StatusCode = http.StatusNotFound - } else if err := writeFileResponse(info.Name, PREVIEW_IMAGE_TYPE, data, forceDownload, w, r); err != nil { + } else if err := writeFileResponse(info.Name, PREVIEW_IMAGE_TYPE, 0, fileReader, forceDownload, w, r); err != nil { c.Err = err return } @@ -325,20 +325,23 @@ func getPublicFile(c *Context, w http.ResponseWriter, r *http.Request) { return } - if data, err := c.App.ReadFile(info.Path); err != nil { + if fileReader, err := c.App.FileReader(info.Path); err != nil { c.Err = err c.Err.StatusCode = http.StatusNotFound - } else if err := writeFileResponse(info.Name, info.MimeType, data, true, w, r); err != nil { + } else if err := writeFileResponse(info.Name, info.MimeType, info.Size, fileReader, true, w, r); err != nil { c.Err = err return } } -func writeFileResponse(filename string, contentType string, bytes []byte, forceDownload bool, w http.ResponseWriter, r *http.Request) *model.AppError { +func writeFileResponse(filename string, contentType string, contentSize int64, fileReader io.Reader, forceDownload bool, w http.ResponseWriter, r *http.Request) *model.AppError { w.Header().Set("Cache-Control", "max-age=2592000, private") - w.Header().Set("Content-Length", strconv.Itoa(len(bytes))) w.Header().Set("X-Content-Type-Options", "nosniff") + if contentSize > 0 { + w.Header().Set("Content-Length", strconv.Itoa(int(contentSize))) + } + if contentType == "" { contentType = "application/octet-stream" } else { @@ -380,7 +383,7 @@ func writeFileResponse(filename string, contentType string, bytes []byte, forceD w.Header().Set("X-Frame-Options", "DENY") w.Header().Set("Content-Security-Policy", "Frame-ancestors 'none'") - w.Write(bytes) + io.Copy(w, fileReader) return nil } -- cgit v1.2.3-1-g7c22