1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
use super::SparseIndex;
use crate::{Error, IndexKrate, KrateName};
pub use reqwest::blocking::Client;
pub use reqwest::Client as AsyncClient;
/// Allows **blocking** access to a remote HTTP sparse registry index
pub struct RemoteSparseIndex {
/// The local index this remote is wrapping
pub index: SparseIndex,
/// The client used to make requests to the remote index
pub client: Client,
}
impl RemoteSparseIndex {
/// Creates a new [`Self`] that can access and write local cache entries,
/// and contact the remote index to retrieve the latest index information
#[inline]
pub fn new(index: SparseIndex, client: Client) -> Self {
Self { index, client }
}
/// Gets the latest index metadata for the crate
///
/// Network I/O is _always_ performed when calling this method, however the
/// response from the remote registry will be empty of contents other than
/// headers if the local cache entry for the crate is up to date with the
/// latest in the index
pub fn krate(
&self,
name: KrateName<'_>,
write_cache_entry: bool,
) -> Result<Option<IndexKrate>, Error> {
let req = self.index.make_remote_request(name)?;
let req = req.try_into()?;
let res = self.client.execute(req)?;
let mut builder = http::Response::builder()
.status(res.status())
.version(res.version());
builder
.headers_mut()
.unwrap()
.extend(res.headers().iter().map(|(k, v)| (k.clone(), v.clone())));
let body = res.bytes()?;
let res = builder.body(body.to_vec())?;
self.index
.parse_remote_response(name, res, write_cache_entry)
}
/// Attempts to read the locally cached crate information
///
/// This method does no network I/O unlike [`Self::krate`], but does not
/// guarantee that the cache information is up to date with the latest in
/// the remote index
#[inline]
pub fn cached_krate(&self, name: KrateName<'_>) -> Result<Option<IndexKrate>, Error> {
self.index.cached_krate(name)
}
}
/// Allows **async** access to a remote HTTP sparse registry index
pub struct AsyncRemoteSparseIndex {
/// The local index this remote is wrapping
pub index: SparseIndex,
/// The client used to make requests to the remote index
pub client: AsyncClient,
}
impl AsyncRemoteSparseIndex {
/// Creates a new [`Self`] that can access and write local cache entries,
/// and contact the remote index to retrieve the latest index information
#[inline]
pub fn new(index: SparseIndex, client: AsyncClient) -> Self {
Self { index, client }
}
/// Async version of [`RemoteSparseIndex::krate`]
pub async fn krate_async(
&self,
name: KrateName<'_>,
write_cache_entry: bool,
) -> Result<Option<IndexKrate>, Error> {
let req = self.index.make_remote_request(name)?;
let req = req.try_into()?;
let res = self.client.execute(req).await?;
let mut builder = http::Response::builder()
.status(res.status())
.version(res.version());
builder
.headers_mut()
.unwrap()
.extend(res.headers().iter().map(|(k, v)| (k.clone(), v.clone())));
let body = res.bytes().await?;
let res = builder.body(body.to_vec())?;
self.index
.parse_remote_response(name, res, write_cache_entry)
}
/// Attempts to read the locally cached crate information
///
/// This method does no network I/O unlike [`Self::krate_async`], but does not
/// guarantee that the cache information is up to date with the latest in
/// the remote index
#[inline]
pub fn cached_krate(&self, name: KrateName<'_>) -> Result<Option<IndexKrate>, Error> {
self.index.cached_krate(name)
}
}
impl From<reqwest::Error> for Error {
#[inline]
fn from(e: reqwest::Error) -> Self {
Self::Http(crate::HttpError::Reqwest(e))
}
}
impl From<http::Error> for Error {
#[inline]
fn from(e: http::Error) -> Self {
Self::Http(crate::HttpError::Http(e))
}
}