[import] Support larger files when connecting to an HTTP endpoint (#2557)

This commit is contained in:
Salvador Girones Gil 2023-09-01 10:09:41 +02:00 committed by GitHub
parent efa7a14964
commit 129757a28d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -47,8 +47,6 @@ use tokio::fs::OpenOptions;
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
use tokio::io; use tokio::io;
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
use tokio::io::AsyncReadExt;
#[cfg(not(target_arch = "wasm32"))]
use tokio_util::compat::FuturesAsyncReadCompatExt; use tokio_util::compat::FuturesAsyncReadCompatExt;
use url::Url; use url::Url;
@ -279,7 +277,7 @@ async fn export(
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
async fn import(request: RequestBuilder, path: PathBuf) -> Result<Value> { async fn import(request: RequestBuilder, path: PathBuf) -> Result<Value> {
let mut file = match OpenOptions::new().read(true).open(&path).await { let file = match OpenOptions::new().read(true).open(&path).await {
Ok(path) => path, Ok(path) => path,
Err(error) => { Err(error) => {
return Err(Error::FileOpen { return Err(Error::FileOpen {
@ -289,30 +287,25 @@ async fn import(request: RequestBuilder, path: PathBuf) -> Result<Value> {
.into()); .into());
} }
}; };
let mut contents = vec![];
if let Err(error) = file.read_to_end(&mut contents).await { let res = request.header(ACCEPT, "application/octet-stream").body(file).send().await?;
return Err(Error::FileRead {
path,
error,
}
.into());
}
let res = request
.header(ACCEPT, "application/octet-stream")
// ideally we should pass `file` directly into the body
// but currently that results in
// "HTTP status client error (405 Method Not Allowed) for url"
.body(contents)
.send()
.await?;
if res.error_for_status_ref().is_err() { if res.error_for_status_ref().is_err() {
let body: serde_json::Value = res.json().await?; let res = res.text().await?;
let error_msg =
format!("\n{}", serde_json::to_string_pretty(&body).unwrap_or_else(|_| "{}".into()));
match res.parse::<serde_json::Value>() {
Ok(body) => {
let error_msg = format!(
"\n{}",
serde_json::to_string_pretty(&body).unwrap_or_else(|_| "{}".into())
);
return Err(Error::Http(error_msg).into()); return Err(Error::Http(error_msg).into());
} }
Err(_) => {
return Err(Error::Http(res).into());
}
}
}
Ok(Value::None) Ok(Value::None)
} }