Skip to content

Commit

Permalink
Auto merge of rust-lang#1452 - alexcrichton:issue-1355, r=huonw
Browse files Browse the repository at this point in the history
The hashes would occasionally disappear when the main package registry overwrote
a previous registry source, so this just adds logic to load hashes if they're
missing.

Closes rust-lang#1355
  • Loading branch information
bors committed Apr 3, 2015
2 parents a6eb3f4 + f162aed commit d7b6671
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 9 deletions.
12 changes: 10 additions & 2 deletions src/cargo/core/registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,11 +109,15 @@ impl<'a, 'b> PackageRegistry<'a, 'b> {
// We've previously loaded this source, and we've already locked it,
// so we're not allowed to change it even if `namespace` has a
// slightly different precise version listed.
Some(&(_, Kind::Locked)) => return Ok(()),
Some(&(_, Kind::Locked)) => {
debug!("load/locked {}", namespace);
return Ok(())
}

// If the previous source was not a precise source, then we can be
// sure that it's already been updated if we've already loaded it.
Some(&(ref previous, _)) if previous.precise().is_none() => {
debug!("load/precise {}", namespace);
return Ok(())
}

Expand All @@ -122,10 +126,14 @@ impl<'a, 'b> PackageRegistry<'a, 'b> {
// updating this source.
Some(&(ref previous, _)) => {
if previous.precise() == namespace.precise() {
debug!("load/match {}", namespace);
return Ok(())
}
debug!("load/mismatch {}", namespace);
}
None => {
debug!("load/missing {}", namespace);
}
None => {}
}

try!(self.load(namespace, Kind::Normal));
Expand Down
23 changes: 16 additions & 7 deletions src/cargo/sources/registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -298,13 +298,14 @@ impl<'a, 'b> RegistrySource<'a, 'b> {
/// No action is taken if the package is already downloaded.
fn download_package(&mut self, pkg: &PackageId, url: &Url)
-> CargoResult<PathBuf> {
// TODO: should discover from the S3 redirect
// TODO: should discover filename from the S3 redirect
let filename = format!("{}-{}.crate", pkg.name(), pkg.version());
let dst = self.cache_path.join(&filename);
if fs::metadata(&dst).is_ok() { return Ok(dst) }
try!(self.config.shell().status("Downloading", pkg));

try!(fs::create_dir_all(dst.parent().unwrap()));
let expected_hash = try!(self.hash(pkg));
let handle = match self.handle {
Some(ref mut handle) => handle,
None => {
Expand All @@ -320,17 +321,12 @@ impl<'a, 'b> RegistrySource<'a, 'b> {
}

// Verify what we just downloaded
let expected = self.hashes.get(&(pkg.name().to_string(),
pkg.version().to_string()));
let expected = try!(expected.chain_error(|| {
internal(format!("no hash listed for {}", pkg))
}));
let actual = {
let mut state = Sha256::new();
state.update(resp.get_body());
state.finish()
};
if actual.to_hex() != *expected {
if actual.to_hex() != expected_hash {
return Err(human(format!("Failed to verify the checksum of `{}`",
pkg)))
}
Expand All @@ -339,6 +335,19 @@ impl<'a, 'b> RegistrySource<'a, 'b> {
Ok(dst)
}

/// Return the hash listed for a specified PackageId.
fn hash(&mut self, pkg: &PackageId) -> CargoResult<String> {
let key = (pkg.name().to_string(), pkg.version().to_string());
if let Some(s) = self.hashes.get(&key) {
return Ok(s.clone())
}
// Ok, we're missing the key, so parse the index file to load it.
try!(self.summaries(pkg.name()));
self.hashes.get(&key).chain_error(|| {
internal(format!("no hash listed for {}", pkg))
}).map(|s| s.clone())
}

/// Unpacks a downloaded package into a location where it's ready to be
/// compiled.
///
Expand Down

0 comments on commit d7b6671

Please sign in to comment.