feat: directory permissions
This commit is contained in:
@@ -14,36 +14,41 @@ type HttpFS struct {
|
|||||||
remoteStorage remote.Storage
|
remoteStorage remote.Storage
|
||||||
}
|
}
|
||||||
|
|
||||||
type Option func(*HttpFS)
|
type HttpFSOption func(*HttpFS)
|
||||||
|
|
||||||
// WithRemoteStorage
|
// WithRemoteStorage
|
||||||
func WithRemoteStorage(storage remote.Storage) Option {
|
func WithRemoteStorage(storage remote.Storage) HttpFSOption {
|
||||||
return func(httpFS *HttpFS) {
|
return func(httpFS *HttpFS) {
|
||||||
httpFS.remoteStorage = storage
|
httpFS.remoteStorage = storage
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewHttpFS
|
// NewHttpFS
|
||||||
func NewHttpFS(dir string, opts ...Option) (*HttpFS, error) {
|
func NewHttpFS(dir string, opts ...HttpFSOption) (*HttpFS, error) {
|
||||||
store, err := NewStore(dir)
|
store, err := NewStore(dir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
f := &HttpFS{store: store}
|
f := &HttpFS{store: store}
|
||||||
|
|
||||||
for _, opt := range opts {
|
for _, opt := range opts {
|
||||||
if opt != nil {
|
if opt != nil {
|
||||||
opt(f)
|
opt(f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return f, nil
|
return f, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Open
|
// Open
|
||||||
func (f *HttpFS) Open(name string) (http.File, error) {
|
func (f *HttpFS) Open(name string) (http.File, error) {
|
||||||
n := strings.TrimPrefix(name, "/")
|
n := strings.TrimPrefix(name, "/")
|
||||||
|
|
||||||
if f.remoteStorage != nil {
|
if f.remoteStorage != nil {
|
||||||
return f.remoteStorage.Open(name)
|
return f.remoteStorage.Open(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
return f.store.Open(n)
|
return f.store.Open(n)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,8 @@ const tmpfileName = "<temporary file>"
|
|||||||
|
|
||||||
// Store описывает хранилище файлов.
|
// Store описывает хранилище файлов.
|
||||||
type Store struct {
|
type Store struct {
|
||||||
dir string
|
dir string
|
||||||
|
permissions os.FileMode
|
||||||
|
|
||||||
mutexes struct {
|
mutexes struct {
|
||||||
sync.Mutex
|
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 описывает информацию о сохраненном файле.
|
// FileInfo описывает информацию о сохраненном файле.
|
||||||
type FileInfo struct {
|
type FileInfo struct {
|
||||||
Location string `json:"location"`
|
Location string `json:"location"`
|
||||||
@@ -39,12 +49,24 @@ type FileInfo struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewStore открывает и возвращает хранилище файлов.
|
// 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 nil, err
|
||||||
}
|
}
|
||||||
return &Store{dir: dir}, nil
|
|
||||||
|
return s, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create сохраняет файл в хранилище. В качестве имени файла используется комбинация из двух хешей.
|
// 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
|
err.(*os.PathError).Path = fi.Name
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user