MM-15480: Add server support for Range on files (#10892)
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
87ff64ea6d
Коммит
edd3cc890f
12
api4/file.go
12
api4/file.go
@@ -546,7 +546,7 @@ func getFile(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
defer fileReader.Close()
|
defer fileReader.Close()
|
||||||
|
|
||||||
err = writeFileResponse(info.Name, info.MimeType, info.Size, *c.App.Config().ServiceSettings.WebserverMode, fileReader, forceDownload, w, r)
|
err = writeFileResponse(info.Name, info.MimeType, info.Size, time.Unix(0, info.UpdateAt*int64(1000*1000)), *c.App.Config().ServiceSettings.WebserverMode, fileReader, forceDownload, w, r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Err = err
|
c.Err = err
|
||||||
return
|
return
|
||||||
@@ -588,7 +588,7 @@ func getFileThumbnail(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
defer fileReader.Close()
|
defer fileReader.Close()
|
||||||
|
|
||||||
err = writeFileResponse(info.Name, THUMBNAIL_IMAGE_TYPE, 0, *c.App.Config().ServiceSettings.WebserverMode, fileReader, forceDownload, w, r)
|
err = writeFileResponse(info.Name, THUMBNAIL_IMAGE_TYPE, 0, time.Unix(0, info.UpdateAt*int64(1000*1000)), *c.App.Config().ServiceSettings.WebserverMode, fileReader, forceDownload, w, r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Err = err
|
c.Err = err
|
||||||
return
|
return
|
||||||
@@ -663,7 +663,7 @@ func getFilePreview(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
defer fileReader.Close()
|
defer fileReader.Close()
|
||||||
|
|
||||||
err = writeFileResponse(info.Name, PREVIEW_IMAGE_TYPE, 0, *c.App.Config().ServiceSettings.WebserverMode, fileReader, forceDownload, w, r)
|
err = writeFileResponse(info.Name, PREVIEW_IMAGE_TYPE, 0, time.Unix(0, info.UpdateAt*int64(1000*1000)), *c.App.Config().ServiceSettings.WebserverMode, fileReader, forceDownload, w, r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Err = err
|
c.Err = err
|
||||||
return
|
return
|
||||||
@@ -729,14 +729,14 @@ func getPublicFile(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
defer fileReader.Close()
|
defer fileReader.Close()
|
||||||
|
|
||||||
err = writeFileResponse(info.Name, info.MimeType, info.Size, *c.App.Config().ServiceSettings.WebserverMode, fileReader, false, w, r)
|
err = writeFileResponse(info.Name, info.MimeType, info.Size, time.Unix(0, info.UpdateAt*int64(1000*1000)), *c.App.Config().ServiceSettings.WebserverMode, fileReader, false, w, r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Err = err
|
c.Err = err
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeFileResponse(filename string, contentType string, contentSize int64, webserverMode string, fileReader io.Reader, forceDownload bool, w http.ResponseWriter, r *http.Request) *model.AppError {
|
func writeFileResponse(filename string, contentType string, contentSize int64, lastModification time.Time, webserverMode string, fileReader io.ReadSeeker, forceDownload bool, w http.ResponseWriter, r *http.Request) *model.AppError {
|
||||||
w.Header().Set("Cache-Control", "private, no-cache")
|
w.Header().Set("Cache-Control", "private, no-cache")
|
||||||
w.Header().Set("X-Content-Type-Options", "nosniff")
|
w.Header().Set("X-Content-Type-Options", "nosniff")
|
||||||
|
|
||||||
@@ -790,7 +790,7 @@ func writeFileResponse(filename string, contentType string, contentSize int64, w
|
|||||||
w.Header().Set("X-Frame-Options", "DENY")
|
w.Header().Set("X-Frame-Options", "DENY")
|
||||||
w.Header().Set("Content-Security-Policy", "Frame-ancestors 'none'")
|
w.Header().Set("Content-Security-Policy", "Frame-ancestors 'none'")
|
||||||
|
|
||||||
io.Copy(w, fileReader)
|
http.ServeContent(w, r, filename, lastModification, fileReader)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ func (a *App) ReadFile(path string) ([]byte, *model.AppError) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Caller must close the first return value
|
// Caller must close the first return value
|
||||||
func (a *App) FileReader(path string) (io.ReadCloser, *model.AppError) {
|
func (a *App) FileReader(path string) (filesstore.ReadCloseSeeker, *model.AppError) {
|
||||||
backend, err := a.FileBackend()
|
backend, err := a.FileBackend()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
@@ -10,10 +10,15 @@ import (
|
|||||||
"github.com/mattermost/mattermost-server/model"
|
"github.com/mattermost/mattermost-server/model"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type ReadCloseSeeker interface {
|
||||||
|
io.ReadCloser
|
||||||
|
io.Seeker
|
||||||
|
}
|
||||||
|
|
||||||
type FileBackend interface {
|
type FileBackend interface {
|
||||||
TestConnection() *model.AppError
|
TestConnection() *model.AppError
|
||||||
|
|
||||||
Reader(path string) (io.ReadCloser, *model.AppError)
|
Reader(path string) (ReadCloseSeeker, *model.AppError)
|
||||||
ReadFile(path string) ([]byte, *model.AppError)
|
ReadFile(path string) ([]byte, *model.AppError)
|
||||||
FileExists(path string) (bool, *model.AppError)
|
FileExists(path string) (bool, *model.AppError)
|
||||||
CopyFile(oldPath, newPath string) *model.AppError
|
CopyFile(oldPath, newPath string) *model.AppError
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ func (b *LocalFileBackend) TestConnection() *model.AppError {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *LocalFileBackend) Reader(path string) (io.ReadCloser, *model.AppError) {
|
func (b *LocalFileBackend) Reader(path string) (ReadCloseSeeker, *model.AppError) {
|
||||||
f, err := os.Open(filepath.Join(b.directory, path))
|
f, err := os.Open(filepath.Join(b.directory, path))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, model.NewAppError("Reader", "api.file.reader.reading_local.app_error", nil, err.Error(), http.StatusInternalServerError)
|
return nil, model.NewAppError("Reader", "api.file.reader.reading_local.app_error", nil, err.Error(), http.StatusInternalServerError)
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ func (b *S3FileBackend) TestConnection() *model.AppError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Caller must close the first return value
|
// Caller must close the first return value
|
||||||
func (b *S3FileBackend) Reader(path string) (io.ReadCloser, *model.AppError) {
|
func (b *S3FileBackend) Reader(path string) (ReadCloseSeeker, *model.AppError) {
|
||||||
s3Clnt, err := b.s3New()
|
s3Clnt, err := b.s3New()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, model.NewAppError("Reader", "api.file.reader.s3.app_error", nil, err.Error(), http.StatusInternalServerError)
|
return nil, model.NewAppError("Reader", "api.file.reader.s3.app_error", nil, err.Error(), http.StatusInternalServerError)
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user