Skip to content

Commit

Permalink
General fixups (#18)
Browse files Browse the repository at this point in the history
This changes the `SparseIndex` API slightly to allow for zero disk I/O
when making requests to the remote HTTP index.

Resolves: #16
  • Loading branch information
Jake-Shadle authored Aug 23, 2023
1 parent 48265de commit 5d23f67
Show file tree
Hide file tree
Showing 10 changed files with 41 additions and 14 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

<!-- next-header -->
## [Unreleased] - ReleaseDate
### Fixed
- [PR#18](https://github.com/EmbarkStudios/tame-index/pull/18) resolved [#16](https://github.com/EmbarkStudios/tame-index/issues/16) by marking `ComboIndexCache` and `ComboIndex` as `#[non_exhaustive]`. This avoids build breaks if the `local` feature is enabled in one transitive dependency and not in another, as much as I hate `non_exhaustive`.

### Changed
- [PR#18](https://github.com/EmbarkStudios/tame-index/pull/18) changed `SparseIndex::make_remote_request` to take an optional [ETag](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag), completely avoiding disk I/O, which allows `SparseIndex` to be used for making and parsing requests without worrying about cargo's global package lock.

## [0.4.1] - 2023-08-21
### Added
- [PR#15](https://github.com/EmbarkStudios/tame-index/pull/15) added the `native-certs` feature to be able to use the OS certificate store instead of `webpki-roots`. Thanks [@Shnatsel](https://github.com/Shnatsel)!
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ twox-hash = { version = "1.6", default-features = false }

[dependencies.gix]
optional = true
version = "0.51"
version = "0.52"
default-features = false
features = [
"max-performance-safe",
Expand Down
6 changes: 0 additions & 6 deletions deny.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,20 +46,14 @@ deny = [{ name = "openssl" }, { name = "curl" }]
skip = [
# several users of this old version
{ name = "bitflags", version = "=1.3.2" },
# tempfile uses an old version
{ name = "fastrand", version = "=1.9.0" },
# imara-diff uses an old version
{ name = "hashbrown", version = "=0.12.3" },
# trust-dns-proto uses an old version
{ name = "idna", version = "=0.2.3" },
# toml-edit is user a newer version :p
{ name = "indexmap", version = "=1.9.3" },
# trust-dns-resolver pulls in a new version than the rest of them use (including itself)
{ name = "socket2", version = "=0.4.9" },
# A bunch of users still of syn 1.0 :p
{ name = "syn", version = "=1.0.109" },
# Reqwest depends on 2 versions :p
{ name = "winreg", version = "=0.10.1" },
]
skip-tree = []

Expand Down
3 changes: 3 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,9 @@ pub enum HttpError {
/// A [`http::Error`]
#[error(transparent)]
Http(#[from] http::Error),
/// A string could not be parsed as a valid header value
#[error(transparent)]
InvalidHeaderValue(#[from] http::header::InvalidHeaderValue),
/// Unable to complete an async request for an `AsyncRemoteSparseIndex` within
/// the user allotted time
#[error("request could not be completed in the allotted timeframe")]
Expand Down
1 change: 1 addition & 0 deletions src/index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ impl IndexConfig {
use crate::Error;

/// Provides simpler access to the cache for an index, regardless of the registry kind
#[non_exhaustive]
pub enum ComboIndexCache {
/// A git index
Git(GitIndex),
Expand Down
1 change: 1 addition & 0 deletions src/index/combo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use crate::{
};

/// A wrapper around either a [`RemoteGitIndex`] or [`RemoteSparseIndex`]
#[non_exhaustive]
pub enum ComboIndex {
/// A standard git based registry index. No longer the default for crates.io
/// as of 1.70.0
Expand Down
15 changes: 14 additions & 1 deletion src/index/sparse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@ impl SparseIndex {
/// Creates an HTTP request that can be sent via your HTTP client of choice
/// to retrieve the current metadata for the specified crate
///
/// If specified, the etag is used instead of the possible etag stored in
/// a local cache entry, resulting in no disk I/O being performed by this
/// method
///
/// See [`Self::parse_remote_response`] processing the response from the remote
/// index
///
Expand All @@ -87,6 +91,7 @@ impl SparseIndex {
pub fn make_remote_request(
&self,
name: KrateName<'_>,
etag: Option<&str>,
) -> Result<http::Request<&'static [u8]>, Error> {
use http::header;

Expand Down Expand Up @@ -145,7 +150,15 @@ impl SparseIndex {
None
};

let _ = set_cache_version(headers);
if let Some(etag) = etag {
let hv =
header::HeaderValue::from_str(etag.trim()).map_err(crate::HttpError::from)?;
headers.insert(header::IF_NONE_MATCH, hv);
} else {
// Use the etag (or last modified, though crates.io does not use this AFAICT)
// from the cache entry if it exists
let _ = set_cache_version(headers);
}
}

const EMPTY: &[u8] = &[];
Expand Down
6 changes: 3 additions & 3 deletions src/index/sparse_remote.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ impl RemoteSparseIndex {
name: KrateName<'_>,
write_cache_entry: bool,
) -> Result<Option<IndexKrate>, Error> {
let req = self.index.make_remote_request(name)?;
let req = self.index.make_remote_request(name, None)?;
let req = req.try_into()?;

let res = self.client.execute(req)?;
Expand Down Expand Up @@ -109,7 +109,7 @@ impl AsyncRemoteSparseIndex {
name: KrateName<'_>,
write_cache_entry: bool,
) -> Result<Option<IndexKrate>, Error> {
let req = self.index.make_remote_request(name)?.try_into()?;
let req = self.index.make_remote_request(name, None)?.try_into()?;
let res = Self::exec_request(&self.client, req).await?;

self.index
Expand Down Expand Up @@ -181,7 +181,7 @@ impl AsyncRemoteSparseIndex {
match kname
.as_str()
.try_into()
.and_then(|name| Ok(self.index.make_remote_request(name)?.try_into()?))
.and_then(|name| Ok(self.index.make_remote_request(name, None)?.try_into()?))
{
Ok(req) => {
let client = self.client.clone();
Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
#![doc = include_str!("../README.md")]

pub mod error;
Expand Down
14 changes: 11 additions & 3 deletions tests/sparse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ fn make_request_without_cache() {
let index = crates_io(env!("CARGO_MANIFEST_DIR"));

let req = index
.make_remote_request("serde".try_into().unwrap())
.make_remote_request("serde".try_into().unwrap(), None)
.unwrap();

let hdrs = req.headers();
Expand Down Expand Up @@ -61,7 +61,15 @@ fn make_request_with_cache() {
.unwrap();

let req = index
.make_remote_request("etag-krate".try_into().unwrap())
.make_remote_request("etag-krate".try_into().unwrap(), None)
.unwrap();

assert_eq!(req.headers().get(header::IF_NONE_MATCH).unwrap(), ETAG);
}

{
let req = index
.make_remote_request("etag-specified-krate".try_into().unwrap(), Some(ETAG))
.unwrap();

assert_eq!(req.headers().get(header::IF_NONE_MATCH).unwrap(), ETAG);
Expand All @@ -78,7 +86,7 @@ fn make_request_with_cache() {
.unwrap();

let req = index
.make_remote_request("modified-krate".try_into().unwrap())
.make_remote_request("modified-krate".try_into().unwrap(), None)
.unwrap();

assert_eq!(req.headers().get(header::IF_MODIFIED_SINCE).unwrap(), DATE);
Expand Down

0 comments on commit 5d23f67

Please sign in to comment.