github.com/lologarithm/mattermost-server@v5.3.2-0.20181002060438-c82a84ed765b+incompatible/services/filesstore/localstore.go (about) 1 // Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved. 2 // See License.txt for license information. 3 4 package filesstore 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 "github.com/mattermost/mattermost-server/utils" 17 ) 18 19 const ( 20 TEST_FILE_PATH = "/testfile" 21 ) 22 23 type LocalFileBackend struct { 24 directory string 25 } 26 27 func (b *LocalFileBackend) TestConnection() *model.AppError { 28 f := bytes.NewReader([]byte("testingwrite")) 29 if _, err := writeFileLocally(f, filepath.Join(b.directory, TEST_FILE_PATH)); err != nil { 30 return model.NewAppError("TestFileConnection", "api.file.test_connection.local.connection.app_error", nil, err.Error(), http.StatusInternalServerError) 31 } 32 os.Remove(filepath.Join(b.directory, TEST_FILE_PATH)) 33 mlog.Info("Able to write files to local storage.") 34 return nil 35 } 36 37 func (b *LocalFileBackend) Reader(path string) (io.ReadCloser, *model.AppError) { 38 if f, err := os.Open(filepath.Join(b.directory, path)); err != nil { 39 return nil, model.NewAppError("Reader", "api.file.reader.reading_local.app_error", nil, err.Error(), http.StatusInternalServerError) 40 } else { 41 return f, nil 42 } 43 } 44 45 func (b *LocalFileBackend) ReadFile(path string) ([]byte, *model.AppError) { 46 if f, err := ioutil.ReadFile(filepath.Join(b.directory, path)); err != nil { 47 return nil, model.NewAppError("ReadFile", "api.file.read_file.reading_local.app_error", nil, err.Error(), http.StatusInternalServerError) 48 } else { 49 return f, nil 50 } 51 } 52 53 func (b *LocalFileBackend) FileExists(path string) (bool, *model.AppError) { 54 _, err := os.Stat(filepath.Join(b.directory, path)) 55 56 if os.IsNotExist(err) { 57 return false, nil 58 } else if err == nil { 59 return true, nil 60 } 61 62 return false, model.NewAppError("ReadFile", "api.file.file_exists.exists_local.app_error", nil, err.Error(), http.StatusInternalServerError) 63 } 64 65 func (b *LocalFileBackend) CopyFile(oldPath, newPath string) *model.AppError { 66 if err := utils.CopyFile(filepath.Join(b.directory, oldPath), filepath.Join(b.directory, newPath)); err != nil { 67 return model.NewAppError("copyFile", "api.file.move_file.rename.app_error", nil, err.Error(), http.StatusInternalServerError) 68 } 69 return nil 70 } 71 72 func (b *LocalFileBackend) MoveFile(oldPath, newPath string) *model.AppError { 73 if err := os.MkdirAll(filepath.Dir(filepath.Join(b.directory, newPath)), 0774); err != nil { 74 return model.NewAppError("moveFile", "api.file.move_file.rename.app_error", nil, err.Error(), http.StatusInternalServerError) 75 } 76 77 if err := os.Rename(filepath.Join(b.directory, oldPath), filepath.Join(b.directory, newPath)); err != nil { 78 return model.NewAppError("moveFile", "api.file.move_file.rename.app_error", nil, err.Error(), http.StatusInternalServerError) 79 } 80 81 return nil 82 } 83 84 func (b *LocalFileBackend) WriteFile(fr io.Reader, path string) (int64, *model.AppError) { 85 return writeFileLocally(fr, filepath.Join(b.directory, path)) 86 } 87 88 func writeFileLocally(fr io.Reader, path string) (int64, *model.AppError) { 89 if err := os.MkdirAll(filepath.Dir(path), 0774); err != nil { 90 directory, _ := filepath.Abs(filepath.Dir(path)) 91 return 0, model.NewAppError("WriteFile", "api.file.write_file_locally.create_dir.app_error", nil, "directory="+directory+", err="+err.Error(), http.StatusInternalServerError) 92 } 93 fw, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644) 94 if err != nil { 95 return 0, model.NewAppError("WriteFile", "api.file.write_file_locally.writing.app_error", nil, err.Error(), http.StatusInternalServerError) 96 } 97 defer fw.Close() 98 written, err := io.Copy(fw, fr) 99 if err != nil { 100 return written, model.NewAppError("WriteFile", "api.file.write_file_locally.writing.app_error", nil, err.Error(), http.StatusInternalServerError) 101 } 102 return written, nil 103 } 104 105 func (b *LocalFileBackend) RemoveFile(path string) *model.AppError { 106 if err := os.Remove(filepath.Join(b.directory, path)); err != nil { 107 return model.NewAppError("RemoveFile", "utils.file.remove_file.local.app_error", nil, err.Error(), http.StatusInternalServerError) 108 } 109 return nil 110 } 111 112 func (b *LocalFileBackend) ListDirectory(path string) (*[]string, *model.AppError) { 113 var paths []string 114 if fileInfos, err := ioutil.ReadDir(filepath.Join(b.directory, path)); err != nil { 115 return nil, model.NewAppError("ListDirectory", "utils.file.list_directory.local.app_error", nil, err.Error(), http.StatusInternalServerError) 116 } else { 117 for _, fileInfo := range fileInfos { 118 if fileInfo.IsDir() { 119 paths = append(paths, filepath.Join(path, fileInfo.Name())) 120 } 121 } 122 } 123 return &paths, nil 124 } 125 126 func (b *LocalFileBackend) RemoveDirectory(path string) *model.AppError { 127 if err := os.RemoveAll(filepath.Join(b.directory, path)); err != nil { 128 return model.NewAppError("RemoveDirectory", "utils.file.remove_directory.local.app_error", nil, err.Error(), http.StatusInternalServerError) 129 } 130 return nil 131 }