Fetch wheel metadata by async range requests on the remote wheel (#301)

Use range requests and async zip to extract the METADATA file from a
remote wheel.

We currently only cache when the remote says the remote declares the
resource as immutable, see
https://github.com/06chaynes/http-cache/issues/57 and
https://github.com/baszalmstra/async_http_range_reader/pull/1 . The
cache is stored as json with the description omitted, this improve cache
deserialization performance.
This commit is contained in:
konsti 2023-11-06 15:06:49 +01:00 committed by GitHub
parent 6f83a44fea
commit b2439b24a1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 558 additions and 68 deletions

View file

@ -2,6 +2,7 @@
use std::io;
use distribution_filename::WheelFilename;
use platform_info::PlatformInfoError;
use thiserror::Error;
use zip::result::ZipError;
@ -69,3 +70,45 @@ impl Error {
}
}
}
/// The metadata name may be uppercase, while the wheel and dist info names are lowercase, or
/// the metadata name and the dist info name are lowercase, while the wheel name is uppercase.
/// Either way, we just search the wheel for the name
pub fn find_dist_info_metadata<'a, T: Copy>(
filename: &WheelFilename,
files: impl Iterator<Item = (T, &'a str)>,
) -> Result<(T, &'a str), String> {
let dist_info_matcher = format!(
"{}-{}",
filename.distribution.as_dist_info_name(),
filename.version
);
let metadatas: Vec<_> = files
.filter_map(|(payload, path)| {
let (dir, file) = path.split_once('/')?;
let dir = dir.strip_suffix(".dist-info")?;
if dir.to_lowercase() == dist_info_matcher && file == "METADATA" {
Some((payload, path))
} else {
None
}
})
.collect();
let (payload, path) = match metadatas[..] {
[] => {
return Err("no .dist-info directory".to_string());
}
[(payload, path)] => (payload, path),
_ => {
return Err(format!(
"multiple .dist-info directories: {}",
metadatas
.into_iter()
.map(|(_, path)| path.to_string())
.collect::<Vec<_>>()
.join(", ")
));
}
};
Ok((payload, path))
}