Files
OpenList/drivers/sftp/util.go
j2rong4cn cc01b410a4 perf(link): optimize concurrent response (#641)
* 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>
2025-07-12 17:57:54 +08:00

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))
}