blob: 39fc0ee8e832f72f409480a8b37e08b58d58be3d [file] [log] [blame] [edit]
package deps
import (
"crypto/sha256"
"encoding/hex"
"fmt"
"io"
"net/http"
"os"
"path"
)
func fetchIntoFile(url string, file *os.File) error {
resp, err := http.Get(url)
if err != nil {
return err
}
defer resp.Body.Close()
_, err = io.Copy(file, resp.Body)
return err
}
func fileSHA256(file *os.File) (string, error) {
file.Seek(0, 0)
hasher := sha256.New()
if _, err := io.Copy(hasher, file); err != nil {
return "", nil
}
return hex.EncodeToString(hasher.Sum(nil)), nil
}
// FetchURL fetches the specified URL into the specified file path, and returns
// the SHA-256 hash of the file fetched.
func FetchURL(url string, path string) (string, error) {
file, err := os.Create(path)
if err != nil {
return "", err
}
defer file.Close()
if err = fetchIntoFile(url, file); err != nil {
os.Remove(path)
return "", err
}
checksum, err := fileSHA256(file)
if err != nil {
os.Remove(path)
return "", err
}
return checksum, nil
}
// FetchEntry retrieves an existing WORKSPACE file entry into a specified directory,
// verifies its checksum, and then returns the full path to the resulting file.
func FetchEntry(entry *Entry, dir string) (string, error) {
filename := path.Join(dir, entry.SHA256+".tar.gz")
checksum, err := FetchURL(entry.URL, filename)
if err != nil {
return "", err
}
if checksum != entry.SHA256 {
os.Remove(filename)
return "", fmt.Errorf("SHA-256 mismatch: expected %s, got %s", entry.SHA256, checksum)
}
return filename, nil
}