1 // Copyright 2017 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
24 currentVersionURL = "https://golang.org/VERSION?m=text"
25 downloadURLPrefix = "https://dl.google.com/go"
28 // downloadGoVersion downloads and upacks the specific go version to dest/go.
29 func downloadGoVersion(version, ops, arch, dest string) error {
34 uri := fmt.Sprintf("%s/%s.%s-%s.%s", downloadURLPrefix, version, ops, arch, suffix)
36 verbosef("Downloading %s", uri)
38 req, err := http.NewRequest("GET", uri, nil)
42 req.Header.Add("User-Agent", fmt.Sprintf("golang.org-getgo/%s", version))
44 resp, err := http.DefaultClient.Do(req)
46 return fmt.Errorf("Downloading Go from %s failed: %v", uri, err)
48 if resp.StatusCode > 299 {
49 return fmt.Errorf("Downloading Go from %s failed with HTTP status %s", uri, resp.Status)
51 defer resp.Body.Close()
53 tmpf, err := ioutil.TempFile("", "go")
57 defer os.Remove(tmpf.Name())
61 w := io.MultiWriter(tmpf, h)
62 if _, err := io.Copy(w, resp.Body); err != nil {
66 verbosef("Downloading SHA %s.sha256", uri)
68 sresp, err := http.Get(uri + ".sha256")
70 return fmt.Errorf("Downloading Go sha256 from %s.sha256 failed: %v", uri, err)
72 defer sresp.Body.Close()
73 if sresp.StatusCode > 299 {
74 return fmt.Errorf("Downloading Go sha256 from %s.sha256 failed with HTTP status %s", uri, sresp.Status)
77 shasum, err := ioutil.ReadAll(sresp.Body)
83 sum := fmt.Sprintf("%x", h.Sum(nil))
84 if sum != string(shasum) {
85 return fmt.Errorf("Shasum mismatch %s vs. %s", sum, string(shasum))
88 unpackFunc := unpackTar
90 unpackFunc = unpackZip
92 if err := unpackFunc(tmpf.Name(), dest); err != nil {
93 return fmt.Errorf("Unpacking Go to %s failed: %v", dest, err)
98 func unpack(dest, name string, fi os.FileInfo, r io.Reader) error {
99 if strings.HasPrefix(name, "go/") {
100 name = name[len("go/"):]
103 path := filepath.Join(dest, name)
105 return os.MkdirAll(path, fi.Mode())
108 f, err := os.OpenFile(path, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, fi.Mode())
114 _, err = io.Copy(f, r)
118 func unpackTar(src, dest string) error {
119 r, err := os.Open(src)
125 archive, err := gzip.NewReader(r)
129 defer archive.Close()
131 tarReader := tar.NewReader(archive)
134 header, err := tarReader.Next()
137 } else if err != nil {
141 if err := unpack(dest, header.Name, header.FileInfo(), tarReader); err != nil {
149 func unpackZip(src, dest string) error {
150 zr, err := zip.OpenReader(src)
155 for _, f := range zr.File {
160 if err := unpack(dest, f.Name, f.FileInfo(), fr); err != nil {
169 func getLatestGoVersion() (string, error) {
170 resp, err := http.Get(currentVersionURL)
172 return "", fmt.Errorf("Getting current Go version failed: %v", err)
174 defer resp.Body.Close()
175 if resp.StatusCode > 299 {
176 b, _ := ioutil.ReadAll(io.LimitReader(resp.Body, 1024))
177 return "", fmt.Errorf("Could not get current Go version: HTTP %d: %q", resp.StatusCode, b)
179 version, err := ioutil.ReadAll(resp.Body)
183 return strings.TrimSpace(string(version)), nil