| 305 | } |
| 306 | |
| 307 | func downloadFile( |
| 308 | ctx context.Context, |
| 309 | client HttpClient, |
| 310 | url string, |
| 311 | destPath string, |
| 312 | ) error { |
| 313 | req, err := http.NewRequestWithContext(ctx, "GET", url, nil) |
| 314 | if err != nil { |
| 315 | return err |
| 316 | } |
| 317 | |
| 318 | res, err := client.Do(req) |
| 319 | if err != nil { |
| 320 | return err |
| 321 | } |
| 322 | defer res.Body.Close() |
| 323 | |
| 324 | // http.Client doesn't treat non 2xx responses as error |
| 325 | if res.StatusCode >= 400 { |
| 326 | return fmt.Errorf("(%d) failed to send download file request", res.StatusCode) |
| 327 | } |
| 328 | |
| 329 | // ensure that the dest parent dir(s) exist |
| 330 | if err := os.MkdirAll(filepath.Dir(destPath), os.ModePerm); err != nil { |
| 331 | return err |
| 332 | } |
| 333 | |
| 334 | dest, err := os.Create(destPath) |
| 335 | if err != nil { |
| 336 | return err |
| 337 | } |
| 338 | defer dest.Close() |
| 339 | |
| 340 | if _, err := io.Copy(dest, res.Body); err != nil { |
| 341 | return err |
| 342 | } |
| 343 | |
| 344 | return nil |
| 345 | } |
| 346 | |
| 347 | func archiveSuffix(goos, goarch string) string { |
| 348 | switch goos { |