2019-12-04 14:32:28 +00:00
|
|
|
use super::{PathInfo, Store, StorePath};
|
2019-09-12 15:39:25 +00:00
|
|
|
use crate::Error;
|
2019-12-04 20:01:16 +00:00
|
|
|
use hyper::client::Client;
|
2019-09-12 15:39:25 +00:00
|
|
|
|
|
|
|
pub struct BinaryCacheStore {
|
|
|
|
base_uri: String,
|
2019-12-04 20:01:16 +00:00
|
|
|
client: Client<hyper::client::HttpConnector, hyper::Body>,
|
2019-09-12 15:39:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl BinaryCacheStore {
|
|
|
|
pub fn new(base_uri: String) -> Self {
|
|
|
|
Self {
|
|
|
|
base_uri,
|
2019-12-04 20:01:16 +00:00
|
|
|
client: Client::new(),
|
2019-09-12 15:39:25 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Store for BinaryCacheStore {
|
|
|
|
fn query_path_info(
|
|
|
|
&self,
|
|
|
|
path: &StorePath,
|
|
|
|
) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<PathInfo, Error>> + Send>> {
|
|
|
|
let uri = format!("{}/{}.narinfo", self.base_uri.clone(), path.hash);
|
|
|
|
let path = path.clone();
|
|
|
|
let client = self.client.clone();
|
|
|
|
let store_dir = self.store_dir().to_string();
|
|
|
|
|
|
|
|
Box::pin(async move {
|
2019-12-04 20:01:16 +00:00
|
|
|
let response = client.get(uri.parse::<hyper::Uri>().unwrap()).await?;
|
2019-09-12 15:39:25 +00:00
|
|
|
|
2019-12-04 20:01:16 +00:00
|
|
|
if response.status() == hyper::StatusCode::NOT_FOUND
|
|
|
|
|| response.status() == hyper::StatusCode::FORBIDDEN
|
2019-12-04 14:32:28 +00:00
|
|
|
{
|
2019-09-12 15:39:25 +00:00
|
|
|
return Err(Error::InvalidPath(path));
|
|
|
|
}
|
|
|
|
|
2019-12-04 20:01:16 +00:00
|
|
|
let mut body = response.into_body();
|
2019-09-12 15:39:25 +00:00
|
|
|
|
2019-12-04 20:01:16 +00:00
|
|
|
let mut bytes = Vec::new();
|
|
|
|
while let Some(next) = body.next().await {
|
|
|
|
bytes.extend(next?);
|
|
|
|
}
|
2019-09-12 15:39:25 +00:00
|
|
|
|
2019-12-04 20:01:16 +00:00
|
|
|
PathInfo::parse_nar_info(std::str::from_utf8(&bytes).unwrap(), &store_dir)
|
2019-09-12 15:39:25 +00:00
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|