func (s *suite) TestDownloadError(c *gc.C) { gitjujutesting.Server.Response(404, nil, nil) d := downloader.New(s.URL("/archive.tgz"), c.MkDir(), utils.VerifySSLHostnames) status := <-d.Done() c.Assert(status.File, gc.IsNil) c.Assert(status.Err, gc.ErrorMatches, `cannot download ".*": bad http response: 404 Not Found`) }
// NewBundlesDir returns a new BundlesDir which uses path for storage. func NewBundlesDir(path string, dlr Downloader) *BundlesDir { if dlr == nil { dlr = downloader.New(downloader.NewArgs{ HostnameVerification: utils.NoVerifySSLHostnames, }) } return &BundlesDir{ path: path, downloader: dlr, } }
func (s *DownloaderSuite) TestDownload(c *gc.C) { tmp := c.MkDir() gitjujutesting.Server.Response(200, nil, []byte("archive")) dlr := downloader.New(downloader.NewArgs{}) filename, err := dlr.Download(downloader.Request{ URL: s.URL(c, "/archive.tgz"), TargetDir: tmp, }) c.Assert(err, jc.ErrorIsNil) dir, _ := filepath.Split(filename) c.Assert(filepath.Clean(dir), gc.Equals, tmp) assertFileContents(c, filename, "archive") }
func (s *suite) TestStopDownload(c *gc.C) { tmp := c.MkDir() d := downloader.New(s.URL("/x.tgz"), tmp, utils.VerifySSLHostnames) d.Stop() select { case status := <-d.Done(): c.Fatalf("received status %#v after stop", status) case <-time.After(testing.ShortWait): } infos, err := ioutil.ReadDir(tmp) c.Assert(err, gc.IsNil) c.Assert(infos, gc.HasLen, 0) }
func (s *DownloaderSuite) TestDownloadError(c *gc.C) { gitjujutesting.Server.Response(404, nil, nil) dlr := downloader.New(downloader.NewArgs{ HostnameVerification: utils.VerifySSLHostnames, }) dl := dlr.Start(downloader.Request{ URL: s.URL(c, "/archive.tgz"), TargetDir: c.MkDir(), }) status := <-dl.Done() c.Assert(status.File, gc.IsNil) c.Assert(status.Err, gc.ErrorMatches, `cannot download ".*": bad http response: 404 Not Found`) }
// download fetches the supplied charm and checks that it has the correct sha256 // hash, then copies it into the directory. If a value is received on abort, the // download will be stopped. func (d *BundlesDir) download(info BundleInfo, abort <-chan struct{}) (err error) { archiveURL, disableSSLHostnameVerification, err := info.ArchiveURL() if err != nil { return err } defer errors.Maskf(&err, "failed to download charm %q from %q", info.URL(), archiveURL) dir := d.downloadsPath() if err := os.MkdirAll(dir, 0755); err != nil { return err } aurl := archiveURL.String() logger.Infof("downloading %s from %s", info.URL(), aurl) if disableSSLHostnameVerification { logger.Infof("SSL hostname verification disabled") } dl := downloader.New(aurl, dir, disableSSLHostnameVerification) defer dl.Stop() for { select { case <-abort: logger.Infof("download aborted") return fmt.Errorf("aborted") case st := <-dl.Done(): if st.Err != nil { return st.Err } logger.Infof("download complete") defer st.File.Close() actualSha256, _, err := utils.ReadSHA256(st.File) if err != nil { return err } archiveSha256, err := info.ArchiveSha256() if err != nil { return err } if actualSha256 != archiveSha256 { return fmt.Errorf( "expected sha256 %q, got %q", archiveSha256, actualSha256, ) } logger.Infof("download verified") if err := os.MkdirAll(d.path, 0755); err != nil { return err } // Renaming an open file is not possible on Windows st.File.Close() return os.Rename(st.File.Name(), d.bundlePath(info)) } } }
func (s *suite) testDownload(c *gc.C, hostnameVerification utils.SSLHostnameVerification) { tmp := c.MkDir() gitjujutesting.Server.Response(200, nil, []byte("archive")) d := downloader.New(s.URL("/archive.tgz"), tmp, hostnameVerification) status := <-d.Done() c.Assert(status.Err, gc.IsNil) c.Assert(status.File, gc.NotNil) defer os.Remove(status.File.Name()) defer status.File.Close() dir, _ := filepath.Split(status.File.Name()) c.Assert(filepath.Clean(dir), gc.Equals, tmp) assertFileContents(c, status.File, "archive") }
func (s *DownloaderSuite) testStart(c *gc.C, hostnameVerification utils.SSLHostnameVerification) { tmp := c.MkDir() gitjujutesting.Server.Response(200, nil, []byte("archive")) dlr := downloader.New(downloader.NewArgs{ HostnameVerification: hostnameVerification, }) dl := dlr.Start(downloader.Request{ URL: s.URL(c, "/archive.tgz"), TargetDir: tmp, }) status := <-dl.Done() c.Assert(status.Err, gc.IsNil) dir, _ := filepath.Split(status.Filename) c.Assert(filepath.Clean(dir), gc.Equals, tmp) assertFileContents(c, status.Filename, "archive") }
func tryDownload(url, dir string, abort <-chan struct{}) (downloader.Status, error) { // Downloads always go through the API server, which at // present cannot be verified due to the certificates // being inadequate. We always verify the SHA-256 hash, // and the data transferred is not sensitive, so this // does not pose a problem. dl := downloader.New(url, dir, utils.NoVerifySSLHostnames) defer dl.Stop() select { case <-abort: logger.Infof("download aborted") return downloader.Status{}, errors.New("aborted") case st := <-dl.Done(): if st.Err != nil { return downloader.Status{}, st.Err } return st, nil } }
func (s *DownloaderSuite) TestStopDownload(c *gc.C) { tmp := c.MkDir() dlr := downloader.New(downloader.NewArgs{ HostnameVerification: utils.VerifySSLHostnames, }) dl := dlr.Start(downloader.Request{ URL: s.URL(c, "/x.tgz"), TargetDir: tmp, }) dl.Stop() select { case status := <-dl.Done(): c.Fatalf("received status %#v after stop", status) case <-time.After(testing.ShortWait): } infos, err := ioutil.ReadDir(tmp) c.Assert(err, jc.ErrorIsNil) c.Assert(infos, gc.HasLen, 0) }