Skip to content

Commit

Permalink
add: remotefs/download support file download
Browse files Browse the repository at this point in the history
  • Loading branch information
kaplan-michael committed Apr 29, 2024
1 parent 443adb9 commit de78d31
Showing 1 changed file with 53 additions and 0 deletions.
53 changes: 53 additions & 0 deletions remotefs/download.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package remotefs

import (
"crypto/sha256"
"encoding/hex"
"fmt"
"io"
"os"
)

// ErrChecksumMismatch is returned when the checksum of the uploaded file does not match the local checksum.
//var ErrChecksumMismatch = errors.New("checksum mismatch")

// Download a file from the remote host.
func Download(fs FS, src, dst string) error {
remote, err := fs.Open(src)
if err != nil {
return fmt.Errorf("open remote file for download: %w", err)
}
defer remote.Close()

remoteStat, err := remote.Stat()
if err != nil {
return fmt.Errorf("stat remote file for download: %w", err)
}

remoteSum := sha256.New()
localSum := sha256.New()

local, err := os.OpenFile(dst, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, remoteStat.Mode())
if err != nil {
return fmt.Errorf("open local file for download: %w", err)
}
defer local.Close()

remoteReader := io.TeeReader(remote, remoteSum)
if _, err := io.Copy(io.MultiWriter(local, localSum), remoteReader); err != nil {
_ = local.Close()
return fmt.Errorf("copy file from remote host: %w", err)
}
if err := local.Close(); err != nil {
return fmt.Errorf("close local file after download: %w", err)
}

ls := hex.EncodeToString(localSum.Sum(nil))
rs := hex.EncodeToString(remoteSum.Sum(nil))
fmt.Printf("local %s remote %s", ls, rs)
if ls != rs {
return ErrChecksumMismatch
}

return nil
}

0 comments on commit de78d31

Please sign in to comment.