#[cfg(any(feature = "services-tokio", feature = "signal-client-tokio"))]
mod tokio {
#[cfg(any(feature = "services-tokio", feature = "signal-client-tokio"))]
pub use reqwest::Client;
#[cfg(feature = "signal-client-tokio")]
pub async fn get_with_token(url: &str, token: &str) -> reqwest::Result<reqwest::Response> {
reqwest::Client::new().get(url).bearer_auth(token).send().await
}
}
#[cfg(any(feature = "services-tokio", feature = "signal-client-tokio"))]
pub use tokio::*;
#[cfg(any(feature = "__signal-client-async-compatible", feature = "services-async"))]
mod async_std {
#[cfg(any(
feature = "native-tls-vendored",
feature = "rustls-tls-native-roots",
feature = "rustls-tls-webpki-roots",
feature = "__rustls-tls"
))]
compile_error!("the async std compatible libraries do not support these features");
use std::io;
use isahc::AsyncReadResponseExt;
pub struct Response(isahc::http::Response<isahc::AsyncBody>);
impl Response {
pub fn status(&self) -> http::StatusCode {
http::StatusCode::from_u16(self.0.status().as_u16()).expect("valid status code")
}
pub async fn json<T: serde::de::DeserializeOwned + Unpin>(mut self) -> io::Result<T> {
self.0.json().await.map_err(|e| io::Error::new(io::ErrorKind::Other, e))
}
#[cfg(feature = "services-async")]
pub async fn bytes(mut self) -> io::Result<prost::bytes::Bytes> {
Ok(self.0.bytes().await?.into())
}
#[cfg(feature = "__signal-client-async-compatible")]
pub async fn text(mut self) -> io::Result<String> {
self.0.text().await
}
#[cfg(feature = "__signal-client-async-compatible")]
pub fn headers(&self) -> http::HeaderMap {
let mut out = http::HeaderMap::with_capacity(self.0.headers().len());
for (name, value) in self.0.headers() {
let name = http::HeaderName::from_bytes(name.as_str().as_bytes())
.expect("valid header name");
let value =
http::HeaderValue::from_bytes(value.as_bytes()).expect("valid header value");
out.append(name, value);
}
out
}
}
#[cfg(feature = "__signal-client-async-compatible")]
pub async fn get_with_token(url: &str, token: &str) -> io::Result<Response> {
let request = isahc::Request::get(url)
.header("Authorization", format!("Bearer {}", token))
.body(())
.map_err(|e| io::Error::new(io::ErrorKind::Other, e))?;
let response = isahc::send_async(request).await?;
Ok(Response(response))
}
#[derive(Debug, Clone)]
pub struct Client(isahc::HttpClient);
impl Client {
pub fn new() -> Self {
Self(isahc::HttpClient::new().unwrap())
}
#[cfg(feature = "services-async")]
pub fn post(&self, url: url::Url) -> RequestBuilder {
RequestBuilder {
body: Vec::new(),
builder: isahc::http::Request::post(url.as_str()),
client: self.0.clone(),
}
}
#[cfg(feature = "__signal-client-async-compatible")]
pub fn get(&self, url: &str) -> RequestBuilder {
RequestBuilder {
body: Vec::new(),
builder: isahc::http::Request::get(url),
client: self.0.clone(),
}
}
}
pub struct RequestBuilder {
builder: isahc::http::request::Builder,
body: Vec<u8>,
client: isahc::HttpClient,
}
impl RequestBuilder {
pub fn headers(mut self, headers: http::HeaderMap) -> Self {
let dst = self.builder.headers_mut().unwrap();
let mut last_name: Option<isahc::http::HeaderName> = None;
for (key, value) in headers {
let name = match key {
Some(key) => {
let name = isahc::http::HeaderName::from_bytes(key.as_str().as_bytes())
.expect("valid header name");
last_name = Some(name.clone());
name
}
None => last_name.clone().expect("HeaderMap yielded a value before any key"),
};
let value = isahc::http::HeaderValue::from_bytes(value.as_bytes())
.expect("valid header value");
dst.append(name, value);
}
self
}
#[cfg(feature = "services-async")]
pub fn body(mut self, body: Vec<u8>) -> Self {
self.body = body;
self
}
#[cfg(feature = "services-async")]
pub fn timeout(mut self, timeout: std::time::Duration) -> Self {
use isahc::config::Configurable;
self.builder = self.builder.timeout(timeout);
self
}
pub async fn send(self) -> io::Result<Response> {
let request = self.builder.body(self.body).unwrap();
let response = self.client.send_async(request).await?;
Ok(Response(response))
}
}
}
#[cfg(any(feature = "__signal-client-async-compatible", feature = "services-async"))]
pub use async_std::*;