forked from TrueCloudLab/rclone
serve sftp: extract function refactoring for handling hashsum commands
This commit is contained in:
parent
53a29fadf5
commit
0eecebfdb5
1 changed files with 56 additions and 50 deletions
|
@ -100,56 +100,7 @@ func (c *conn) execCommand(ctx context.Context, out io.Writer, command string) (
|
||||||
if binary == "sha1sum" {
|
if binary == "sha1sum" {
|
||||||
ht = hash.SHA1
|
ht = hash.SHA1
|
||||||
}
|
}
|
||||||
if !c.vfs.Fs().Hashes().Contains(ht) {
|
return c.handleHashsumCommand(ctx, out, ht, args)
|
||||||
return fmt.Errorf("%v hash not supported", ht)
|
|
||||||
}
|
|
||||||
var hashSum string
|
|
||||||
if args == "" {
|
|
||||||
// empty hash for no input
|
|
||||||
if ht == hash.MD5 {
|
|
||||||
hashSum = "d41d8cd98f00b204e9800998ecf8427e"
|
|
||||||
} else {
|
|
||||||
hashSum = "da39a3ee5e6b4b0d3255bfef95601890afd80709"
|
|
||||||
}
|
|
||||||
args = "-"
|
|
||||||
} else {
|
|
||||||
node, err := c.vfs.Stat(args)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("hash failed finding file %q: %w", args, err)
|
|
||||||
}
|
|
||||||
if node.IsDir() {
|
|
||||||
return errors.New("can't hash directory")
|
|
||||||
}
|
|
||||||
o, ok := node.DirEntry().(fs.ObjectInfo)
|
|
||||||
if !ok {
|
|
||||||
fs.Debugf(args, "File uploading - reading hash from VFS cache")
|
|
||||||
in, err := node.Open(os.O_RDONLY)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("hash vfs open failed: %w", err)
|
|
||||||
}
|
|
||||||
defer func() {
|
|
||||||
_ = in.Close()
|
|
||||||
}()
|
|
||||||
h, err := hash.NewMultiHasherTypes(hash.NewHashSet(ht))
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("hash vfs create multi-hasher failed: %w", err)
|
|
||||||
}
|
|
||||||
_, err = io.Copy(h, in)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("hash vfs copy failed: %w", err)
|
|
||||||
}
|
|
||||||
hashSum = h.Sums()[ht]
|
|
||||||
} else {
|
|
||||||
hashSum, err = o.Hash(ctx, ht)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("hash failed: %w", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_, err = fmt.Fprintf(out, "%s %s\n", hashSum, args)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("send output failed: %w", err)
|
|
||||||
}
|
|
||||||
case "echo":
|
case "echo":
|
||||||
// Special cases for legacy rclone command detection.
|
// Special cases for legacy rclone command detection.
|
||||||
// Before rclone v1.49.0 the sftp backend used "echo 'abc' | md5sum" when
|
// Before rclone v1.49.0 the sftp backend used "echo 'abc' | md5sum" when
|
||||||
|
@ -189,6 +140,61 @@ func (c *conn) execCommand(ctx context.Context, out io.Writer, command string) (
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// handleHashsumCommand is a helper to execCommand for common functionality of hashsum related commands
|
||||||
|
func (c *conn) handleHashsumCommand(ctx context.Context, out io.Writer, ht hash.Type, args string) (err error) {
|
||||||
|
if !c.vfs.Fs().Hashes().Contains(ht) {
|
||||||
|
return fmt.Errorf("%v hash not supported", ht)
|
||||||
|
}
|
||||||
|
var hashSum string
|
||||||
|
if args == "" {
|
||||||
|
// empty hash for no input
|
||||||
|
if ht == hash.MD5 {
|
||||||
|
hashSum = "d41d8cd98f00b204e9800998ecf8427e"
|
||||||
|
} else {
|
||||||
|
hashSum = "da39a3ee5e6b4b0d3255bfef95601890afd80709"
|
||||||
|
}
|
||||||
|
args = "-"
|
||||||
|
} else {
|
||||||
|
node, err := c.vfs.Stat(args)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("hash failed finding file %q: %w", args, err)
|
||||||
|
}
|
||||||
|
if node.IsDir() {
|
||||||
|
return errors.New("can't hash directory")
|
||||||
|
}
|
||||||
|
o, ok := node.DirEntry().(fs.ObjectInfo)
|
||||||
|
if !ok {
|
||||||
|
fs.Debugf(args, "File uploading - reading hash from VFS cache")
|
||||||
|
in, err := node.Open(os.O_RDONLY)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("hash vfs open failed: %w", err)
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
_ = in.Close()
|
||||||
|
}()
|
||||||
|
h, err := hash.NewMultiHasherTypes(hash.NewHashSet(ht))
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("hash vfs create multi-hasher failed: %w", err)
|
||||||
|
}
|
||||||
|
_, err = io.Copy(h, in)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("hash vfs copy failed: %w", err)
|
||||||
|
}
|
||||||
|
hashSum = h.Sums()[ht]
|
||||||
|
} else {
|
||||||
|
hashSum, err = o.Hash(ctx, ht)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("hash failed: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_, err = fmt.Fprintf(out, "%s %s\n", hashSum, args)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("send output failed: %w", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// handle a new incoming channel request
|
// handle a new incoming channel request
|
||||||
func (c *conn) handleChannel(newChannel ssh.NewChannel) {
|
func (c *conn) handleChannel(newChannel ssh.NewChannel) {
|
||||||
fs.Debugf(c.what, "Incoming channel: %s\n", newChannel.ChannelType())
|
fs.Debugf(c.what, "Incoming channel: %s\n", newChannel.ChannelType())
|
||||||
|
|
Loading…
Add table
Reference in a new issue