Browse Source

try harder to convert transfer errors in well-known error types

Signed-off-by: Nicola Murino <[email protected]>
Nicola Murino 2 năm trước cách đây
mục cha
commit
4294659785

+ 2 - 1
internal/common/connection.go

@@ -1675,7 +1675,8 @@ func (c *BaseConnection) GetGenericError(err error) error {
 		return sftp.ErrSSHFxFailure
 	default:
 		if err == ErrPermissionDenied || err == ErrNotExist || err == ErrOpUnsupported ||
-			err == ErrQuotaExceeded || err == vfs.ErrStorageSizeUnavailable || err == ErrShuttingDown {
+			err == ErrQuotaExceeded || err == ErrReadQuotaExceeded || err == vfs.ErrStorageSizeUnavailable ||
+			err == ErrShuttingDown {
 			return err
 		}
 		c.Log(logger.LevelError, "generic error: %+v", err)

+ 12 - 0
internal/common/transfer.go

@@ -211,6 +211,18 @@ func (t *BaseTransfer) SetCancelFn(cancelFn func()) {
 	t.cancelFn = cancelFn
 }
 
+// ConvertError accepts an error that occurs during a read or write and
+// converts it into a more understandable form for the client if it is a
+// well-known type of error
+func (t *BaseTransfer) ConvertError(err error) error {
+	if t.Fs.IsNotExist(err) {
+		return t.Connection.GetNotExistError()
+	} else if t.Fs.IsPermission(err) {
+		return t.Connection.GetPermissionDeniedError()
+	}
+	return err
+}
+
 // CheckRead returns an error if read if not allowed
 func (t *BaseTransfer) CheckRead() error {
 	if t.transferQuota.AllowedDLSize == 0 && t.transferQuota.AllowedTotalSize == 0 {

+ 5 - 0
internal/common/transfer_test.go

@@ -21,6 +21,7 @@ import (
 	"testing"
 	"time"
 
+	"github.com/pkg/sftp"
 	"github.com/sftpgo/sdk"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
@@ -225,6 +226,10 @@ func TestTransferErrors(t *testing.T) {
 	conn := NewBaseConnection("id", ProtocolSFTP, "", "", u)
 	transfer := NewBaseTransfer(file, conn, nil, testFile, testFile, "/transfer_test_file", TransferUpload,
 		0, 0, 0, 0, true, fs, dataprovider.TransferQuota{})
+	err = transfer.ConvertError(os.ErrNotExist)
+	assert.ErrorIs(t, err, sftp.ErrSSHFxNoSuchFile)
+	err = transfer.ConvertError(os.ErrPermission)
+	assert.ErrorIs(t, err, sftp.ErrSSHFxPermissionDenied)
 	assert.Nil(t, transfer.cancelFn)
 	assert.Equal(t, testFile, transfer.GetFsPath())
 	transfer.SetCancelFn(cancelFn)

+ 2 - 0
internal/ftpd/transfer.go

@@ -67,6 +67,7 @@ func (t *transfer) Read(p []byte) (n int, err error) {
 	}
 	if err != nil && err != io.EOF {
 		t.TransferError(err)
+		err = t.ConvertError(err)
 		return
 	}
 	t.HandleThrottle()
@@ -85,6 +86,7 @@ func (t *transfer) Write(p []byte) (n int, err error) {
 	}
 	if err != nil {
 		t.TransferError(err)
+		err = t.ConvertError(err)
 		return
 	}
 	t.HandleThrottle()

+ 2 - 0
internal/httpd/file.go

@@ -67,6 +67,7 @@ func (f *httpdFile) Read(p []byte) (n int, err error) {
 	}
 	if err != nil && err != io.EOF {
 		f.TransferError(err)
+		err = f.ConvertError(err)
 		return
 	}
 	f.HandleThrottle()
@@ -91,6 +92,7 @@ func (f *httpdFile) Write(p []byte) (n int, err error) {
 	}
 	if err != nil {
 		f.TransferError(err)
+		err = f.ConvertError(err)
 		return
 	}
 	f.HandleThrottle()

+ 2 - 0
internal/sftpd/transfer.go

@@ -115,6 +115,7 @@ func (t *transfer) ReadAt(p []byte, off int64) (n int, err error) {
 		if t.GetType() == common.TransferDownload {
 			t.TransferError(err)
 		}
+		err = t.ConvertError(err)
 		return
 	}
 	t.HandleThrottle()
@@ -139,6 +140,7 @@ func (t *transfer) WriteAt(p []byte, off int64) (n int, err error) {
 	}
 	if err != nil {
 		t.TransferError(err)
+		err = t.ConvertError(err)
 		return
 	}
 	t.HandleThrottle()

+ 4 - 2
internal/webdavd/file.go

@@ -145,7 +145,7 @@ func (f *webDavFile) Stat() (os.FileInfo, error) {
 	}
 	info, err := f.Fs.Stat(f.GetFsPath())
 	if err != nil {
-		return nil, err
+		return nil, f.Connection.GetFsError(f.Fs, err)
 	}
 	if vfs.IsCryptOsFs(f.Fs) {
 		info = f.Fs.(*vfs.CryptFs).ConvertFileInfo(info)
@@ -216,7 +216,7 @@ func (f *webDavFile) Read(p []byte) (n int, err error) {
 		f.startOffset = 0
 		f.Unlock()
 		if e != nil {
-			return 0, e
+			return 0, f.Connection.GetFsError(f.Fs, e)
 		}
 	}
 
@@ -227,6 +227,7 @@ func (f *webDavFile) Read(p []byte) (n int, err error) {
 	}
 	if err != nil && err != io.EOF {
 		f.TransferError(err)
+		err = f.ConvertError(err)
 		return
 	}
 	f.HandleThrottle()
@@ -249,6 +250,7 @@ func (f *webDavFile) Write(p []byte) (n int, err error) {
 	}
 	if err != nil {
 		f.TransferError(err)
+		err = f.ConvertError(err)
 		return
 	}
 	f.HandleThrottle()