From d1f0e9ae9f735ddfba5c60dfbe0619cf21e4f581 Mon Sep 17 00:00:00 2001 From: Nicola Murino Date: Mon, 28 Sep 2020 22:12:46 +0200 Subject: [PATCH] CGS: implement MimeTyper interface --- docs/howto/rest-api-https-auth.md | 4 ++-- vfs/fileinfo.go | 18 ------------------ vfs/gcsfs.go | 24 ++++++++++++++++-------- webdavd/file.go | 11 ++--------- webdavd/internal_test.go | 16 +++------------- 5 files changed, 23 insertions(+), 50 deletions(-) diff --git a/docs/howto/rest-api-https-auth.md b/docs/howto/rest-api-https-auth.md index afb5107a..c9411511 100644 --- a/docs/howto/rest-api-https-auth.md +++ b/docs/howto/rest-api-https-auth.md @@ -58,7 +58,7 @@ Setting an empty `bind_address` means that the service will listen on all availa Now restart the SFTPGo service to apply the changes. ```shell -systemctl restart sftpgo +sudo systemctl restart sftpgo ``` You are done! Now login to the Web Admin interface using the username and password created above. @@ -108,7 +108,7 @@ Search for the `httpd` section and change it as follow. Now restart the SFTPGo service to apply the changes. ```shell -systemctl restart sftpgo +sudo systemctl restart sftpgo ``` You are done! Now SFTPGo web admin and REST API are exposed over HTTPS and password protected. diff --git a/vfs/fileinfo.go b/vfs/fileinfo.go index b0692f14..57b6531e 100644 --- a/vfs/fileinfo.go +++ b/vfs/fileinfo.go @@ -6,27 +6,19 @@ import ( "time" ) -// FileContentTyper is an optional interface for vfs.FileInfo -type FileContentTyper interface { - GetContentType() string -} - // FileInfo implements os.FileInfo for a Cloud Storage file. type FileInfo struct { name string sizeInBytes int64 modTime time.Time mode os.FileMode - contentType string } // NewFileInfo creates file info. func NewFileInfo(name string, isDirectory bool, sizeInBytes int64, modTime time.Time, fullName bool) FileInfo { mode := os.FileMode(0644) - contentType := "" if isDirectory { mode = os.FileMode(0755) | os.ModeDir - contentType = "inode/directory" } if !fullName { // we have always Unix style paths here @@ -38,7 +30,6 @@ func NewFileInfo(name string, isDirectory bool, sizeInBytes int64, modTime time. sizeInBytes: sizeInBytes, modTime: modTime, mode: mode, - contentType: contentType, } } @@ -71,12 +62,3 @@ func (fi FileInfo) IsDir() bool { func (fi FileInfo) Sys() interface{} { return fi.getFileInfoSys() } - -func (fi *FileInfo) setContentType(contenType string) { - fi.contentType = contenType -} - -// GetContentType implements FileContentTyper interface -func (fi FileInfo) GetContentType() string { - return fi.contentType -} diff --git a/vfs/gcsfs.go b/vfs/gcsfs.go index 0766a4aa..d045c05f 100644 --- a/vfs/gcsfs.go +++ b/vfs/gcsfs.go @@ -27,7 +27,7 @@ import ( ) var ( - gcsDefaultFieldsSelection = []string{"Name", "Size", "Deleted", "Updated", "ContentType"} + gcsDefaultFieldsSelection = []string{"Name", "Size", "Deleted", "Updated"} ) // GCSFs is a Fs implementation for Google Cloud Storage. @@ -121,9 +121,6 @@ func (fs GCSFs) Stat(name string) (os.FileInfo, error) { if fs.isEqual(attrs.Name, name) { isDir := strings.HasSuffix(attrs.Name, "/") result = NewFileInfo(name, isDir, attrs.Size, attrs.Updated, false) - if !isDir { - result.setContentType(attrs.ContentType) - } break } } @@ -184,7 +181,7 @@ func (fs GCSFs) Create(name string, flag int) (*os.File, *PipeWriter, func(), er objectWriter := obj.NewWriter(ctx) contentType := mime.TypeByExtension(path.Ext(name)) if contentType != "" { - objectWriter.ObjectAttrs.ContentType = contentType + objectWriter.ObjectAttrs.ContentType = contentType } if len(fs.config.StorageClass) > 0 { objectWriter.ObjectAttrs.StorageClass = fs.config.StorageClass @@ -359,9 +356,6 @@ func (fs GCSFs) ReadDir(dirname string) ([]os.FileInfo, error) { continue } fi := NewFileInfo(name, isDir, attrs.Size, attrs.Updated, false) - if !isDir { - fi.setContentType(attrs.ContentType) - } result = append(result, fi) } } @@ -596,3 +590,17 @@ func (fs *GCSFs) getPrefixForStat(name string) string { } return prefix } + +// GetMimeType implements MimeTyper interface +func (fs GCSFs) GetMimeType(name string) (string, error) { + ctx, cancelFn := context.WithDeadline(context.Background(), time.Now().Add(fs.ctxTimeout)) + defer cancelFn() + bkt := fs.svc.Bucket(fs.config.Bucket) + obj := bkt.Object(name) + attrs, err := obj.Attrs(ctx) + if err != nil { + return "", err + } + logger.DebugToConsole("content type: %v", attrs.ContentType) + return attrs.ContentType, nil +} diff --git a/webdavd/file.go b/webdavd/file.go index 921015f0..2462d9cc 100644 --- a/webdavd/file.go +++ b/webdavd/file.go @@ -57,15 +57,8 @@ type webDavFileInfo struct { // ContentType implements webdav.ContentTyper interface func (fi webDavFileInfo) ContentType(ctx context.Context) (string, error) { - var contentType string - if c, ok := fi.FileInfo.(vfs.FileContentTyper); ok { - contentType = c.GetContentType() - } - if len(contentType) > 0 { - return contentType, nil - } - contentType = mime.TypeByExtension(path.Ext(fi.file.GetVirtualPath())) - if len(contentType) > 0 { + contentType := mime.TypeByExtension(path.Ext(fi.file.GetVirtualPath())) + if contentType != "" { return contentType, nil } if c, ok := fi.file.Fs.(vfs.MimeTyper); ok { diff --git a/webdavd/internal_test.go b/webdavd/internal_test.go index 36207c18..b5d5ee60 100644 --- a/webdavd/internal_test.go +++ b/webdavd/internal_test.go @@ -430,22 +430,12 @@ func TestContentType(t *testing.T) { ctx := context.Background() baseTransfer := common.NewBaseTransfer(nil, connection.BaseConnection, nil, testFilePath, testFile, common.TransferDownload, 0, 0, 0, false, fs) - info := vfs.NewFileInfo(testFilePath, true, 0, time.Now(), false) - davFile := newWebDavFile(baseTransfer, nil, nil, info) - fi, err := davFile.Stat() - if assert.NoError(t, err) { - ctype, err := fi.(webDavFileInfo).ContentType(ctx) - assert.NoError(t, err) - assert.Equal(t, "inode/directory", ctype) - } - err = davFile.Close() - assert.NoError(t, err) fs = newMockOsFs(nil, false, fs.ConnectionID(), user.GetHomeDir()) - err = ioutil.WriteFile(testFilePath, []byte(""), os.ModePerm) + err := ioutil.WriteFile(testFilePath, []byte(""), os.ModePerm) assert.NoError(t, err) - fi, err = os.Stat(testFilePath) + fi, err := os.Stat(testFilePath) assert.NoError(t, err) - davFile = newWebDavFile(baseTransfer, nil, nil, fi) + davFile := newWebDavFile(baseTransfer, nil, nil, fi) davFile.Fs = fs fi, err = davFile.Stat() if assert.NoError(t, err) {