AppFlowy/rust-lib/flowy-net/src/request/request.rs

80 lines
2.1 KiB
Rust
Raw Normal View History

use crate::response::{FlowyResponse, ServerCode, ServerError};
2021-08-20 13:09:21 +00:00
use bytes::Bytes;
use hyper::http;
use protobuf::{Message, ProtobufError};
use reqwest::{Client, Response};
use std::{
convert::{TryFrom, TryInto},
time::Duration,
};
use tokio::sync::oneshot;
2021-08-20 13:09:21 +00:00
2021-08-21 09:17:54 +00:00
pub async fn http_post<T1, T2>(url: &str, data: T1) -> Result<T2, ServerError>
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();
let (tx, rx) = oneshot::channel::<Result<Response, _>>();
2021-08-20 13:09:21 +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 09:17:54 +00:00
let response = rx.await??;
if response.status() == http::StatusCode::OK {
let response_bytes = response.bytes().await?;
let flowy_resp: FlowyResponse = serde_json::from_slice(&response_bytes).unwrap();
let data = T2::try_from(flowy_resp.data)?;
2021-08-21 09:17:54 +00:00
Ok(data)
} else {
Err(ServerError {
code: ServerCode::InternalError,
msg: format!("{:?}", response),
})
2021-08-20 13:09:21 +00:00
}
}
2021-08-21 09:17:54 +00:00
async fn parse_response<T>(response: Response) -> Result<T, ServerError>
2021-08-20 13:09:21 +00:00
where
T: Message,
{
let bytes = response.bytes().await?;
parse_bytes(bytes)
}
2021-08-21 09:17:54 +00:00
fn parse_bytes<T>(bytes: Bytes) -> Result<T, ServerError>
2021-08-20 13:09:21 +00:00
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()
},
}
}