2021-08-21 04:11:33 +00:00
|
|
|
use crate::{errors::NetworkError, future::ResultFuture};
|
2021-08-20 13:09:21 +00:00
|
|
|
use bytes::Bytes;
|
2021-08-21 04:11:33 +00:00
|
|
|
use protobuf::{Message, ProtobufError};
|
|
|
|
use reqwest::{Client, Error, Response};
|
|
|
|
use std::{
|
|
|
|
convert::{TryFrom, TryInto},
|
|
|
|
time::Duration,
|
|
|
|
};
|
|
|
|
use tokio::sync::{oneshot, oneshot::error::RecvError};
|
2021-08-20 13:09:21 +00:00
|
|
|
|
2021-08-21 04:34:11 +00:00
|
|
|
// pub async fn http_post<T1, T2>(url: &str, data: T1) -> ResultFuture<T2,
|
|
|
|
// NetworkError> where
|
|
|
|
// T1: TryInto<Bytes, Error = ProtobufError> + Send + Sync + 'static,
|
|
|
|
// T2: TryFrom<Bytes, Error = ProtobufError> + Send + Sync + 'static,
|
|
|
|
// {
|
|
|
|
// let url = url.to_owned();
|
|
|
|
// ResultFuture::new(async move { post(url, data).await })
|
|
|
|
// }
|
2021-08-20 13:09:21 +00:00
|
|
|
|
2021-08-21 04:34:11 +00:00
|
|
|
pub async fn http_post<T1, T2>(url: &str, data: T1) -> Result<T2, NetworkError>
|
2021-08-21 04:11:33 +00:00
|
|
|
where
|
|
|
|
T1: TryInto<Bytes, Error = ProtobufError>,
|
|
|
|
T2: TryFrom<Bytes, Error = ProtobufError>,
|
|
|
|
{
|
|
|
|
let request_bytes: Bytes = data.try_into()?;
|
2021-08-21 04:34:11 +00:00
|
|
|
let url = url.to_owned();
|
2021-08-21 04:11:33 +00:00
|
|
|
let (tx, rx) = oneshot::channel::<Result<Response, _>>();
|
2021-08-20 13:09:21 +00:00
|
|
|
|
2021-08-21 04:11:33 +00:00
|
|
|
tokio::spawn(async move {
|
|
|
|
let client = default_client();
|
|
|
|
let response = client.post(&url).body(request_bytes).send().await;
|
|
|
|
tx.send(response);
|
|
|
|
});
|
2021-08-20 13:09:21 +00:00
|
|
|
|
2021-08-21 04:11:33 +00:00
|
|
|
match rx.await {
|
|
|
|
Ok(response) => {
|
|
|
|
let response = response?;
|
|
|
|
let response_bytes = response.bytes().await?;
|
|
|
|
let data = T2::try_from(response_bytes)?;
|
|
|
|
Ok(data)
|
|
|
|
},
|
|
|
|
Err(e) => {
|
|
|
|
unimplemented!()
|
|
|
|
},
|
2021-08-20 13:09:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
async fn parse_response<T>(response: Response) -> Result<T, NetworkError>
|
|
|
|
where
|
|
|
|
T: Message,
|
|
|
|
{
|
|
|
|
let bytes = response.bytes().await?;
|
|
|
|
parse_bytes(bytes)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn parse_bytes<T>(bytes: Bytes) -> Result<T, NetworkError>
|
|
|
|
where
|
|
|
|
T: Message,
|
|
|
|
{
|
|
|
|
match Message::parse_from_bytes(&bytes) {
|
|
|
|
Ok(data) => Ok(data),
|
|
|
|
Err(e) => {
|
|
|
|
log::error!(
|
|
|
|
"Parse bytes for {:?} failed: {}",
|
|
|
|
std::any::type_name::<T>(),
|
|
|
|
e
|
|
|
|
);
|
|
|
|
Err(e.into())
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn default_client() -> Client {
|
|
|
|
let result = reqwest::Client::builder()
|
|
|
|
.connect_timeout(Duration::from_millis(500))
|
|
|
|
.timeout(Duration::from_secs(5))
|
|
|
|
.build();
|
|
|
|
|
|
|
|
match result {
|
|
|
|
Ok(client) => client,
|
|
|
|
Err(e) => {
|
|
|
|
log::error!("Create reqwest client failed: {}", e);
|
|
|
|
reqwest::Client::new()
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|