github.com/gigforks/mattermost-server@v4.9.1-0.20180619094218-800d97fa55d0+incompatible/utils/file_backend_local.go (about) 1 // Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved. 2 // See License.txt for license information. 3 4 package utils 5 6 import ( 7 "bytes" 8 "io" 9 "io/ioutil" 10 "net/http" 11 "os" 12 "path/filepath" 13 14 "github.com/mattermost/mattermost-server/mlog" 15 "github.com/mattermost/mattermost-server/model" 16 ) 17 18 const ( 19 TEST_FILE_PATH = "/testfile" 20 ) 21 22 type LocalFileBackend struct { 23 directory string 24 } 25 26 func (b *LocalFileBackend) TestConnection() *model.AppError { 27 f := bytes.NewReader([]byte("testingwrite")) 28 if _, err := writeFileLocally(f, filepath.Join(b.directory, TEST_FILE_PATH)); err != nil { 29 return model.NewAppError("TestFileConnection", "Don't have permissions to write to local path specified or other error.", nil, err.Error(), http.StatusInternalServerError) 30 } 31 os.Remove(filepath.Join(b.directory, TEST_FILE_PATH)) 32 mlog.Info("Able to write files to local storage.") 33 return nil 34 } 35 36 func (b *LocalFileBackend) ReadFile(path string) ([]byte, *model.AppError) { 37 if f, err := ioutil.ReadFile(filepath.Join(b.directory, path)); err != nil { 38 return nil, model.NewAppError("ReadFile", "api.file.read_file.reading_local.app_error", nil, err.Error(), http.StatusInternalServerError) 39 } else { 40 return f, nil 41 } 42 } 43 44 func (b *LocalFileBackend) CopyFile(oldPath, newPath string) *model.AppError { 45 if err := CopyFile(filepath.Join(b.directory, oldPath), filepath.Join(b.directory, newPath)); err != nil { 46 return model.NewAppError("copyFile", "api.file.move_file.rename.app_error", nil, err.Error(), http.StatusInternalServerError) 47 } 48 return nil 49 } 50 51 func (b *LocalFileBackend) MoveFile(oldPath, newPath string) *model.AppError { 52 if err := os.MkdirAll(filepath.Dir(filepath.Join(b.directory, newPath)), 0774); err != nil { 53 return model.NewAppError("moveFile", "api.file.move_file.rename.app_error", nil, err.Error(), http.StatusInternalServerError) 54 } 55 56 if err := os.Rename(filepath.Join(b.directory, oldPath), filepath.Join(b.directory, newPath)); err != nil { 57 return model.NewAppError("moveFile", "api.file.move_file.rename.app_error", nil, err.Error(), http.StatusInternalServerError) 58 } 59 60 return nil 61 } 62 63 func (b *LocalFileBackend) WriteFile(fr io.Reader, path string) (int64, *model.AppError) { 64 return writeFileLocally(fr, filepath.Join(b.directory, path)) 65 } 66 67 func writeFileLocally(fr io.Reader, path string) (int64, *model.AppError) { 68 if err := os.MkdirAll(filepath.Dir(path), 0774); err != nil { 69 directory, _ := filepath.Abs(filepath.Dir(path)) 70 return 0, model.NewAppError("WriteFile", "api.file.write_file_locally.create_dir.app_error", nil, "directory="+directory+", err="+err.Error(), http.StatusInternalServerError) 71 } 72 fw, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644) 73 if err != nil { 74 return 0, model.NewAppError("WriteFile", "api.file.write_file_locally.writing.app_error", nil, err.Error(), http.StatusInternalServerError) 75 } 76 defer fw.Close() 77 written, err := io.Copy(fw, fr) 78 if err != nil { 79 return written, model.NewAppError("WriteFile", "api.file.write_file_locally.writing.app_error", nil, err.Error(), http.StatusInternalServerError) 80 } 81 return written, nil 82 } 83 84 func (b *LocalFileBackend) RemoveFile(path string) *model.AppError { 85 if err := os.Remove(filepath.Join(b.directory, path)); err != nil { 86 return model.NewAppError("RemoveFile", "utils.file.remove_file.local.app_error", nil, err.Error(), http.StatusInternalServerError) 87 } 88 return nil 89 } 90 91 func (b *LocalFileBackend) ListDirectory(path string) (*[]string, *model.AppError) { 92 var paths []string 93 if fileInfos, err := ioutil.ReadDir(filepath.Join(b.directory, path)); err != nil { 94 return nil, model.NewAppError("ListDirectory", "utils.file.list_directory.local.app_error", nil, err.Error(), http.StatusInternalServerError) 95 } else { 96 for _, fileInfo := range fileInfos { 97 if fileInfo.IsDir() { 98 paths = append(paths, filepath.Join(path, fileInfo.Name())) 99 } 100 } 101 } 102 return &paths, nil 103 } 104 105 func (b *LocalFileBackend) RemoveDirectory(path string) *model.AppError { 106 if err := os.RemoveAll(filepath.Join(b.directory, path)); err != nil { 107 return model.NewAppError("RemoveDirectory", "utils.file.remove_directory.local.app_error", nil, err.Error(), http.StatusInternalServerError) 108 } 109 return nil 110 }