From 0eecebfdb5d8bedf18daf3faddfcc2937c75233d Mon Sep 17 00:00:00 2001 From: albertony <12441419+albertony@users.noreply.github.com> Date: Mon, 2 Dec 2024 18:51:48 +0100 Subject: [PATCH] serve sftp: extract function refactoring for handling hashsum commands --- cmd/serve/sftp/connection.go | 106 ++++++++++++++++++----------------- 1 file changed, 56 insertions(+), 50 deletions(-) diff --git a/cmd/serve/sftp/connection.go b/cmd/serve/sftp/connection.go index fb6d524cb..812ae1aa6 100644 --- a/cmd/serve/sftp/connection.go +++ b/cmd/serve/sftp/connection.go @@ -100,56 +100,7 @@ func (c *conn) execCommand(ctx context.Context, out io.Writer, command string) ( if binary == "sha1sum" { ht = hash.SHA1 } - 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 c.handleHashsumCommand(ctx, out, ht, args) case "echo": // Special cases for legacy rclone command detection. // 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 } +// 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 func (c *conn) handleChannel(newChannel ssh.NewChannel) { fs.Debugf(c.what, "Incoming channel: %s\n", newChannel.ChannelType())