mirror of
https://github.com/facebook/sapling.git
synced 2024-10-09 08:18:15 +03:00
Add download endpoint to EdenApi trait
Summary: This adds the plumbing to access download a file using the endpoint from the previous diff via the EdenApi trait, which does the actual http request. It concats the stream into a Bytes object and returns it. Reviewed By: StanislavGlebik Differential Revision: D30582422 fbshipit-source-id: ed0fe5e34e3fecc6c1b26d2dceb322dfcf5f8e37
This commit is contained in:
parent
b5184cbb2d
commit
56d4129e8c
@ -564,6 +564,14 @@ impl EdenApi for EagerRepo {
|
||||
.map_err(|e| EdenApiError::Other(e.into()))?;
|
||||
Ok(convert_to_response(hashes))
|
||||
}
|
||||
|
||||
async fn download_file(
|
||||
&self,
|
||||
_repo: String,
|
||||
_token: UploadToken,
|
||||
) -> Result<Bytes, EdenApiError> {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
impl EagerRepo {
|
||||
|
@ -15,6 +15,7 @@ async-trait = "0.1.51"
|
||||
atty = "0.2"
|
||||
auth = { path = "../auth" }
|
||||
blake2 = "0.8"
|
||||
bytes = { version = "1.0", features = ["serde"] }
|
||||
chrono = { version = "0.4", features = ["clock", "serde", "std"], default-features = false }
|
||||
configmodel = { path = "../configmodel" }
|
||||
configparser = { path = "../configparser" }
|
||||
|
@ -5,7 +5,9 @@
|
||||
* GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
use bytes::Bytes as RawBytes;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::convert::TryInto;
|
||||
use std::fmt::Debug;
|
||||
use std::fs::{create_dir_all, File};
|
||||
use std::iter::FromIterator;
|
||||
@ -45,8 +47,8 @@ use edenapi_types::{
|
||||
HgMutationEntryContent, HistoryEntry, HistoryRequest, LookupRequest, LookupResponse,
|
||||
ServerError, ToApi, ToWire, TreeAttributes, TreeEntry, TreeRequest,
|
||||
UploadBonsaiChangesetRequest, UploadHgChangeset, UploadHgChangesetsRequest,
|
||||
UploadHgFilenodeRequest, UploadToken, UploadTokensResponse, UploadTreeEntry, UploadTreeRequest,
|
||||
UploadTreeResponse,
|
||||
UploadHgFilenodeRequest, UploadToken, UploadTokenMetadata, UploadTokensResponse,
|
||||
UploadTreeEntry, UploadTreeRequest, UploadTreeResponse,
|
||||
};
|
||||
use hg_http::http_client;
|
||||
use http_client::{AsyncResponse, HttpClient, HttpClientError, Progress, Request};
|
||||
@ -97,6 +99,7 @@ mod paths {
|
||||
pub const UPLOAD_BONSAI_CHANGESET: &str = "upload/changeset/bonsai";
|
||||
pub const EPHEMERAL_PREPARE: &str = "ephemeral/prepare";
|
||||
pub const FETCH_SNAPSHOT: &str = "snapshot";
|
||||
pub const DOWNLOAD_FILE: &str = "download/file";
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
@ -1241,6 +1244,39 @@ impl EdenApi for Client {
|
||||
|
||||
Ok(self.fetch::<WireFetchSnapshotResponse>(vec![request], None)?)
|
||||
}
|
||||
|
||||
async fn download_file(&self, repo: String, token: UploadToken) -> Result<Bytes, EdenApiError> {
|
||||
let download_file = "Downloading file";
|
||||
tracing::info!("{}", download_file);
|
||||
if self.config().debug {
|
||||
eprintln!("{}", download_file);
|
||||
}
|
||||
let url = self.build_url(paths::DOWNLOAD_FILE, Some(&repo))?;
|
||||
let metadata = token.data.metadata.clone();
|
||||
let req = token.to_wire();
|
||||
let request = self
|
||||
.configure_request(Request::post(url.clone()))?
|
||||
.cbor(&req)
|
||||
.map_err(EdenApiError::RequestSerializationFailed)?;
|
||||
|
||||
use bytes::BytesMut;
|
||||
let buf = if let Some(UploadTokenMetadata::FileContentTokenMetadata(m)) = metadata {
|
||||
BytesMut::with_capacity(m.content_size.try_into().unwrap_or_default())
|
||||
} else {
|
||||
BytesMut::new()
|
||||
};
|
||||
|
||||
Ok(self
|
||||
.fetch::<RawBytes>(vec![request], None)?
|
||||
.entries
|
||||
.try_fold(buf, |mut buf, chunk| async move {
|
||||
buf.extend_from_slice(&chunk);
|
||||
Ok(buf)
|
||||
})
|
||||
.await?
|
||||
.freeze()
|
||||
.into())
|
||||
}
|
||||
}
|
||||
|
||||
/// Split up a collection of keys into batches of at most `batch_size`.
|
||||
|
@ -203,4 +203,7 @@ pub trait EdenApi: Send + Sync + 'static {
|
||||
repo: String,
|
||||
request: FetchSnapshotRequest,
|
||||
) -> Result<Response<FetchSnapshotResponse>, EdenApiError>;
|
||||
|
||||
/// Download single file from upload token
|
||||
async fn download_file(&self, repo: String, token: UploadToken) -> Result<Bytes, EdenApiError>;
|
||||
}
|
||||
|
@ -523,6 +523,14 @@ impl EdenApi for FakeEdenApi {
|
||||
) -> Result<Response<CommitHashLookupResponse>, EdenApiError> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
async fn download_file(
|
||||
&self,
|
||||
_repo: String,
|
||||
_token: UploadToken,
|
||||
) -> Result<Bytes, EdenApiError> {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn make_config(dir: impl AsRef<Path>) -> ConfigSet {
|
||||
|
Loading…
Reference in New Issue
Block a user