mirror of
https://github.com/OpenListTeam/OpenList.git
synced 2025-07-18 17:38:07 +08:00

* fix(crypt): bug caused by link cache * perf(crypt,mega,halalcloud,quark,uc): optimize concurrent response link * chore: 删除无用代码 * ftp * 修复bug;资源释放 * 添加SyncClosers * local,sftp,smb * 重构,优化,增强 * Update internal/stream/util.go Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Signed-off-by: j2rong4cn <36783515+j2rong4cn@users.noreply.github.com> * chore * chore * 优化,修复bug * . --------- Signed-off-by: j2rong4cn <36783515+j2rong4cn@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
107 lines
2.3 KiB
Go
107 lines
2.3 KiB
Go
package sftp
|
|
|
|
import (
|
|
"fmt"
|
|
"path"
|
|
|
|
"github.com/OpenListTeam/OpenList/v4/pkg/singleflight"
|
|
"github.com/pkg/sftp"
|
|
log "github.com/sirupsen/logrus"
|
|
"golang.org/x/crypto/ssh"
|
|
)
|
|
|
|
// do others that not defined in Driver interface
|
|
|
|
func (d *SFTP) initClient() error {
|
|
err, _, _ := singleflight.ErrorGroup.Do(fmt.Sprintf("SFTP.initClient:%p", d), func() (error, error) {
|
|
return d._initClient(), nil
|
|
})
|
|
return err
|
|
}
|
|
func (d *SFTP) _initClient() error {
|
|
var auth ssh.AuthMethod
|
|
if len(d.PrivateKey) > 0 {
|
|
var err error
|
|
var signer ssh.Signer
|
|
if len(d.Passphrase) > 0 {
|
|
signer, err = ssh.ParsePrivateKeyWithPassphrase([]byte(d.PrivateKey), []byte(d.Passphrase))
|
|
} else {
|
|
signer, err = ssh.ParsePrivateKey([]byte(d.PrivateKey))
|
|
}
|
|
if err != nil {
|
|
return err
|
|
}
|
|
auth = ssh.PublicKeys(signer)
|
|
} else {
|
|
auth = ssh.Password(d.Password)
|
|
}
|
|
config := &ssh.ClientConfig{
|
|
User: d.Username,
|
|
Auth: []ssh.AuthMethod{auth},
|
|
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
|
|
}
|
|
conn, err := ssh.Dial("tcp", d.Address, config)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
d.client, err = sftp.NewClient(conn)
|
|
if err == nil {
|
|
d.clientConnectionError = nil
|
|
go func(d *SFTP) {
|
|
d.clientConnectionError = d.client.Wait()
|
|
}(d)
|
|
}
|
|
return err
|
|
}
|
|
|
|
func (d *SFTP) clientReconnectOnConnectionError() error {
|
|
err := d.clientConnectionError
|
|
if err == nil {
|
|
return nil
|
|
}
|
|
log.Debugf("[sftp] discarding closed sftp connection: %v", err)
|
|
if d.client != nil {
|
|
_ = d.client.Close()
|
|
}
|
|
err = d.initClient()
|
|
return err
|
|
}
|
|
|
|
func (d *SFTP) remove(remotePath string) error {
|
|
f, err := d.client.Stat(remotePath)
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
if f.IsDir() {
|
|
return d.removeDirectory(remotePath)
|
|
} else {
|
|
return d.removeFile(remotePath)
|
|
}
|
|
}
|
|
|
|
func (d *SFTP) removeDirectory(remotePath string) error {
|
|
remoteFiles, err := d.client.ReadDir(remotePath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
for _, backupDir := range remoteFiles {
|
|
remoteFilePath := path.Join(remotePath, backupDir.Name())
|
|
if backupDir.IsDir() {
|
|
err := d.removeDirectory(remoteFilePath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
} else {
|
|
err := d.removeFile(remoteFilePath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
return d.client.RemoveDirectory(remotePath)
|
|
}
|
|
|
|
func (d *SFTP) removeFile(remotePath string) error {
|
|
return d.client.Remove(path.Join(remotePath))
|
|
}
|