From dc52153fb43526ce2a4ca962568a1b9a0284a2d2 Mon Sep 17 00:00:00 2001 From: Sergey Solodyagin Date: Tue, 3 Jun 2025 11:20:29 +0300 Subject: [PATCH] feat: directory permissions --- httpfs.go | 11 ++++++++--- store.go | 32 +++++++++++++++++++++++++++----- 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/httpfs.go b/httpfs.go index 4bb5bf7..7c5c572 100644 --- a/httpfs.go +++ b/httpfs.go @@ -14,36 +14,41 @@ type HttpFS struct { remoteStorage remote.Storage } -type Option func(*HttpFS) +type HttpFSOption func(*HttpFS) // WithRemoteStorage -func WithRemoteStorage(storage remote.Storage) Option { +func WithRemoteStorage(storage remote.Storage) HttpFSOption { return func(httpFS *HttpFS) { httpFS.remoteStorage = storage } } // NewHttpFS -func NewHttpFS(dir string, opts ...Option) (*HttpFS, error) { +func NewHttpFS(dir string, opts ...HttpFSOption) (*HttpFS, error) { store, err := NewStore(dir) if err != nil { return nil, err } + f := &HttpFS{store: store} + for _, opt := range opts { if opt != nil { opt(f) } } + return f, nil } // Open func (f *HttpFS) Open(name string) (http.File, error) { n := strings.TrimPrefix(name, "/") + if f.remoteStorage != nil { return f.remoteStorage.Open(name) } + return f.store.Open(n) } diff --git a/store.go b/store.go index af0e60e..2291030 100644 --- a/store.go +++ b/store.go @@ -19,7 +19,8 @@ const tmpfileName = "" // Store описывает хранилище файлов. type Store struct { - dir string + dir string + permissions os.FileMode mutexes struct { sync.Mutex @@ -28,6 +29,15 @@ type Store struct { } } +type StoreOption func(*Store) + +// WithPermissions +func WithPermissions(permissions os.FileMode) StoreOption { + return func(store *Store) { + store.permissions = permissions + } +} + // FileInfo описывает информацию о сохраненном файле. type FileInfo struct { Location string `json:"location"` @@ -39,12 +49,24 @@ type FileInfo struct { } // NewStore открывает и возвращает хранилище файлов. -func NewStore(dir string) (*Store, error) { +func NewStore(dir string, opts ...StoreOption) (*Store, error) { + s := &Store{ + dir: dir, + permissions: 0700, + } + + for _, opt := range opts { + if opt != nil { + opt(s) + } + } + // Создаём каталог, если он ещё не создан - if err := os.MkdirAll(dir, 0700); err != nil { + if err := os.MkdirAll(s.dir, s.permissions); err != nil { return nil, err } - return &Store{dir: dir}, nil + + return s, nil } // Create сохраняет файл в хранилище. В качестве имени файла используется комбинация из двух хешей. @@ -105,7 +127,7 @@ func (s *Store) Create(r io.Reader) (*FileInfo, error) { } // Если такого файла нет, то создаем для него каталог - if err := os.MkdirAll(filepath.Dir(fi.Location), 0700); err != nil { + if err := os.MkdirAll(filepath.Dir(fi.Location), s.permissions); err != nil { err.(*os.PathError).Path = fi.Name return nil, err }