xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/depstool/deps/fetch.go (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1package deps
2
3import (
4	"crypto/sha256"
5	"encoding/hex"
6	"fmt"
7	"io"
8	"net/http"
9	"os"
10	"path"
11)
12
13func fetchIntoFile(url string, file *os.File) error {
14	resp, err := http.Get(url)
15	if err != nil {
16		return err
17	}
18	defer resp.Body.Close()
19	_, err = io.Copy(file, resp.Body)
20	return err
21}
22
23func fileSHA256(file *os.File) (string, error) {
24	file.Seek(0, 0)
25	hasher := sha256.New()
26	if _, err := io.Copy(hasher, file); err != nil {
27		return "", nil
28	}
29	return hex.EncodeToString(hasher.Sum(nil)), nil
30}
31
32// FetchURL fetches the specified URL into the specified file path, and returns
33// the SHA-256 hash of the file fetched.
34func FetchURL(url string, path string) (string, error) {
35	file, err := os.Create(path)
36	if err != nil {
37		return "", err
38	}
39	defer file.Close()
40
41	if err = fetchIntoFile(url, file); err != nil {
42		os.Remove(path)
43		return "", err
44	}
45
46	checksum, err := fileSHA256(file)
47	if err != nil {
48		os.Remove(path)
49		return "", err
50	}
51
52	return checksum, nil
53}
54
55// FetchEntry retrieves an existing WORKSPACE file entry into a specified directory,
56// verifies its checksum, and then returns the full path to the resulting file.
57func FetchEntry(entry *Entry, dir string) (string, error) {
58	filename := path.Join(dir, entry.SHA256+".tar.gz")
59	checksum, err := FetchURL(entry.URL, filename)
60	if err != nil {
61		return "", err
62	}
63
64	if checksum != entry.SHA256 {
65		os.Remove(filename)
66		return "", fmt.Errorf("SHA-256 mismatch: expected %s, got %s", entry.SHA256, checksum)
67	}
68
69	return filename, nil
70}
71