How to upload / download using axum and AsyncRead
?
#705
-
After hyper v1 revolution (they removed the native hyper Client moving it in "legacy" crate in another hyper-util crate) I would like to use ureq (instead of reqwest or others). I need to use it in multiple places but one of them is driving me crazy (along with #704). I'm using "axum" and I need to "upload" and "download" some files, but I don't understand how to do it. The actual code is: use tokio::io::AsyncRead;
impl Trait for S3Client {
async fn put_file(
&self,
filename: &str,
size: i64,
reader: Pin<Box<(dyn AsyncRead + Send)>>,
) -> Result<()> {
self.hyper_client
.request(
hyper::Request::builder()
.method(Method::PUT)
.uri(get_uri())
.header(header::CONTENT_LENGTH, size)
.body(hyper::Body::wrap_stream(ReaderStream::new(reader)))
.unwrap(),
)
.await?;
Ok(())
}
async fn get_file(&self, filename: &str) -> Result<Pin<Box<dyn AsyncRead + Send + Sync>>> {
let resp = self
.hyper_client
.uri(get_uri())
.await?
.into_body()
.map_err(|e| futures::io::Error::new(futures::io::ErrorKind::Other, e))
.into_async_read()
.compat();
Ok(Box::pin(resp))
}
} with use axum::body::Body;
pub async fn upload(
//...
request: Request,
) -> Result<Response, StatusCode> {
//...
let stream = request
.into_body()
.into_data_stream()
.map_err(|err| io::Error::new(io::ErrorKind::Other, err));
//...
}
pub async fn download(
State(app_state): State<Arc<AppState>>,
session: Extension<Session>,
Query(params): Query<Vec<(String, String)>>,
) -> Result<Response, StatusCode> {
let Some(res) = get_file(...);
//...
Ok(
Response::builder()
.body(Body::from_stream(ReaderStream::new(res.1)))
.unwrap()
)
} I think the first problem is with |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
Hi! Yeah, I |
Beta Was this translation helpful? Give feedback.
Hi! Yeah, I
AsyncRead
is not going to be a great fit with ureq, since ureq is (deliberately) sync. I'm sure it's possible by spawning blocking polls for the AsyncRead, but it kinda goes against the idea of async.