Browse Source

CGS: implement MimeTyper interface

Nicola Murino 4 years ago
parent
commit
d1f0e9ae9f
5 changed files with 23 additions and 50 deletions
  1. 2 2
      docs/howto/rest-api-https-auth.md
  2. 0 18
      vfs/fileinfo.go
  3. 16 8
      vfs/gcsfs.go
  4. 2 9
      webdavd/file.go
  5. 3 13
      webdavd/internal_test.go

+ 2 - 2
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.
 Now restart the SFTPGo service to apply the changes.
 
 
 ```shell
 ```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.
 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.
 Now restart the SFTPGo service to apply the changes.
 
 
 ```shell
 ```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.
 You are done! Now SFTPGo web admin and REST API are exposed over HTTPS and password protected.

+ 0 - 18
vfs/fileinfo.go

@@ -6,27 +6,19 @@ import (
 	"time"
 	"time"
 )
 )
 
 
-// FileContentTyper is an optional interface for vfs.FileInfo
-type FileContentTyper interface {
-	GetContentType() string
-}
-
 // FileInfo implements os.FileInfo for a Cloud Storage file.
 // FileInfo implements os.FileInfo for a Cloud Storage file.
 type FileInfo struct {
 type FileInfo struct {
 	name        string
 	name        string
 	sizeInBytes int64
 	sizeInBytes int64
 	modTime     time.Time
 	modTime     time.Time
 	mode        os.FileMode
 	mode        os.FileMode
-	contentType string
 }
 }
 
 
 // NewFileInfo creates file info.
 // NewFileInfo creates file info.
 func NewFileInfo(name string, isDirectory bool, sizeInBytes int64, modTime time.Time, fullName bool) FileInfo {
 func NewFileInfo(name string, isDirectory bool, sizeInBytes int64, modTime time.Time, fullName bool) FileInfo {
 	mode := os.FileMode(0644)
 	mode := os.FileMode(0644)
-	contentType := ""
 	if isDirectory {
 	if isDirectory {
 		mode = os.FileMode(0755) | os.ModeDir
 		mode = os.FileMode(0755) | os.ModeDir
-		contentType = "inode/directory"
 	}
 	}
 	if !fullName {
 	if !fullName {
 		// we have always Unix style paths here
 		// we have always Unix style paths here
@@ -38,7 +30,6 @@ func NewFileInfo(name string, isDirectory bool, sizeInBytes int64, modTime time.
 		sizeInBytes: sizeInBytes,
 		sizeInBytes: sizeInBytes,
 		modTime:     modTime,
 		modTime:     modTime,
 		mode:        mode,
 		mode:        mode,
-		contentType: contentType,
 	}
 	}
 }
 }
 
 
@@ -71,12 +62,3 @@ func (fi FileInfo) IsDir() bool {
 func (fi FileInfo) Sys() interface{} {
 func (fi FileInfo) Sys() interface{} {
 	return fi.getFileInfoSys()
 	return fi.getFileInfoSys()
 }
 }
-
-func (fi *FileInfo) setContentType(contenType string) {
-	fi.contentType = contenType
-}
-
-// GetContentType implements FileContentTyper interface
-func (fi FileInfo) GetContentType() string {
-	return fi.contentType
-}

+ 16 - 8
vfs/gcsfs.go

@@ -27,7 +27,7 @@ import (
 )
 )
 
 
 var (
 var (
-	gcsDefaultFieldsSelection = []string{"Name", "Size", "Deleted", "Updated", "ContentType"}
+	gcsDefaultFieldsSelection = []string{"Name", "Size", "Deleted", "Updated"}
 )
 )
 
 
 // GCSFs is a Fs implementation for Google Cloud Storage.
 // 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) {
 			if fs.isEqual(attrs.Name, name) {
 				isDir := strings.HasSuffix(attrs.Name, "/")
 				isDir := strings.HasSuffix(attrs.Name, "/")
 				result = NewFileInfo(name, isDir, attrs.Size, attrs.Updated, false)
 				result = NewFileInfo(name, isDir, attrs.Size, attrs.Updated, false)
-				if !isDir {
-					result.setContentType(attrs.ContentType)
-				}
 				break
 				break
 			}
 			}
 		}
 		}
@@ -184,7 +181,7 @@ func (fs GCSFs) Create(name string, flag int) (*os.File, *PipeWriter, func(), er
 	objectWriter := obj.NewWriter(ctx)
 	objectWriter := obj.NewWriter(ctx)
 	contentType := mime.TypeByExtension(path.Ext(name))
 	contentType := mime.TypeByExtension(path.Ext(name))
 	if contentType != "" {
 	if contentType != "" {
-	    objectWriter.ObjectAttrs.ContentType = contentType
+		objectWriter.ObjectAttrs.ContentType = contentType
 	}
 	}
 	if len(fs.config.StorageClass) > 0 {
 	if len(fs.config.StorageClass) > 0 {
 		objectWriter.ObjectAttrs.StorageClass = fs.config.StorageClass
 		objectWriter.ObjectAttrs.StorageClass = fs.config.StorageClass
@@ -359,9 +356,6 @@ func (fs GCSFs) ReadDir(dirname string) ([]os.FileInfo, error) {
 				continue
 				continue
 			}
 			}
 			fi := NewFileInfo(name, isDir, attrs.Size, attrs.Updated, false)
 			fi := NewFileInfo(name, isDir, attrs.Size, attrs.Updated, false)
-			if !isDir {
-				fi.setContentType(attrs.ContentType)
-			}
 			result = append(result, fi)
 			result = append(result, fi)
 		}
 		}
 	}
 	}
@@ -596,3 +590,17 @@ func (fs *GCSFs) getPrefixForStat(name string) string {
 	}
 	}
 	return prefix
 	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
+}

+ 2 - 9
webdavd/file.go

@@ -57,15 +57,8 @@ type webDavFileInfo struct {
 
 
 // ContentType implements webdav.ContentTyper interface
 // ContentType implements webdav.ContentTyper interface
 func (fi webDavFileInfo) ContentType(ctx context.Context) (string, error) {
 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
 		return contentType, nil
 	}
 	}
 	if c, ok := fi.file.Fs.(vfs.MimeTyper); ok {
 	if c, ok := fi.file.Fs.(vfs.MimeTyper); ok {

+ 3 - 13
webdavd/internal_test.go

@@ -430,22 +430,12 @@ func TestContentType(t *testing.T) {
 	ctx := context.Background()
 	ctx := context.Background()
 	baseTransfer := common.NewBaseTransfer(nil, connection.BaseConnection, nil, testFilePath, testFile,
 	baseTransfer := common.NewBaseTransfer(nil, connection.BaseConnection, nil, testFilePath, testFile,
 		common.TransferDownload, 0, 0, 0, false, fs)
 		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())
 	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)
 	assert.NoError(t, err)
-	fi, err = os.Stat(testFilePath)
+	fi, err := os.Stat(testFilePath)
 	assert.NoError(t, err)
 	assert.NoError(t, err)
-	davFile = newWebDavFile(baseTransfer, nil, nil, fi)
+	davFile := newWebDavFile(baseTransfer, nil, nil, fi)
 	davFile.Fs = fs
 	davFile.Fs = fs
 	fi, err = davFile.Stat()
 	fi, err = davFile.Stat()
 	if assert.NoError(t, err) {
 	if assert.NoError(t, err) {