From 5c149b24ec198bbaae359d6aae9ced5dc42793d5 Mon Sep 17 00:00:00 2001 From: Stephan Dilly Date: Wed, 19 May 2021 19:51:08 +0200 Subject: [PATCH] switch to hyper while staying 100% compatible --- Cargo.toml | 16 +++++++------- src/client/mod.rs | 47 ++++++++++++++++++++++++------------------ src/client/response.rs | 16 ++++++++++++-- 3 files changed, 50 insertions(+), 29 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index c0ebb2c8f..d3c7ebf2e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,19 +15,21 @@ edition = "2018" [features] default = ["native-tls"] -native-tls = ["reqwest/native-tls"] -rustls = ["reqwest/rustls-tls"] -vendored-tls = ["reqwest/native-tls-vendored"] +native-tls = ["hyper-tls"] +rustls = ["hyper-rustls"] +vendored-tls = ["hyper-tls/vendored"] [dependencies] serde = { version = "1", features = ["derive"] } serde_json = "1" erased-serde = "0.3" -reqwest = {version = "0.11.0", features = ["json"], default-features=false} chrono = "0.4" log = "0.4" +hyper = { version = "0.14", features = ["client", "http1"] } +hyper-tls = { version = "0.5", optional = true } +hyper-rustls = { version = "0.22", optional = true } [dev-dependencies] -argparse = "0.2.1" -tokio = { version = "1.0", features = ["rt-multi-thread", "macros"] } -pretty_env_logger = "0.3" +argparse = "0.2" +tokio = { version = "1.6", features = ["rt-multi-thread", "macros"] } +pretty_env_logger = "0.4" diff --git a/src/client/mod.rs b/src/client/mod.rs index debdb5ebe..347ba531d 100644 --- a/src/client/mod.rs +++ b/src/client/mod.rs @@ -1,14 +1,18 @@ pub mod response; +use hyper::{client::HttpConnector, Body, Request, StatusCode}; +#[cfg(feature = "hyper-rustls")] +use hyper_rustls::HttpsConnector; +#[cfg(feature = "hyper-tls")] +use hyper_tls::HttpsConnector; + pub use crate::client::response::*; use crate::message::Message; -use reqwest::header::{AUTHORIZATION, CONTENT_LENGTH, CONTENT_TYPE, RETRY_AFTER}; -use reqwest::{Body, StatusCode}; /// An async client for sending the notification payload. pub struct Client { - http_client: reqwest::Client, + http_client: hyper::Client>, } impl Default for Client { @@ -19,40 +23,43 @@ impl Default for Client { impl Client { /// Get a new instance of Client. - pub fn new() -> Client { - let http_client = reqwest::ClientBuilder::new() - .pool_max_idle_per_host(std::usize::MAX) - .build() - .unwrap(); + pub fn new() -> Self { + #[cfg(feature = "hyper-tls")] + let connector = HttpsConnector::new(); + + #[cfg(feature = "hyper-rustls")] + let connector = HttpsConnector::with_native_roots(); - Client { http_client } + Self { + http_client: hyper::Client::builder().build::<_, Body>(connector), + } } /// Try sending a `Message` to FCM. pub async fn send(&self, message: Message<'_>) -> Result { let payload = serde_json::to_vec(&message.body).unwrap(); - let request = self - .http_client - .post("https://fcm.googleapis.com/fcm/send") - .header(CONTENT_TYPE, "application/json") - .header(CONTENT_LENGTH, format!("{}", payload.len() as u64).as_bytes()) - .header(AUTHORIZATION, format!("key={}", message.api_key).as_bytes()) - .body(Body::from(payload)) - .build()?; - let response = self.http_client.execute(request).await?; + let request = Request::builder() + .method("POST") + .uri("https://fcm.googleapis.com/fcm/send") + .header("Content-Type", "application/json") + .header("Content-Length", format!("{}", payload.len() as u64)) + .header("Athorization", format!("key={}", message.api_key)) + .body(Body::from(payload))?; + let response = self.http_client.request(request).await?; let response_status = response.status(); let retry_after = response .headers() - .get(RETRY_AFTER) + .get("Retry-After") .and_then(|ra| ra.to_str().ok()) .and_then(|ra| ra.parse::().ok()); match response_status { StatusCode::OK => { - let fcm_response: FcmResponse = response.json().await.unwrap(); + let buf = hyper::body::to_bytes(response).await?; + let fcm_response: FcmResponse = serde_json::from_slice(&buf)?; match fcm_response.error { Some(ErrorReason::Unavailable) => Err(response::FcmError::ServerError(retry_after)), diff --git a/src/client/response.rs b/src/client/response.rs index 6da22f3b7..bd879596a 100644 --- a/src/client/response.rs +++ b/src/client/response.rs @@ -158,8 +158,20 @@ impl fmt::Display for FcmError { } } -impl From for FcmError { - fn from(_: reqwest::Error) -> Self { +impl From for FcmError { + fn from(_: serde_json::Error) -> Self { + Self::ServerError(None) + } +} + +impl From for FcmError { + fn from(_: hyper::Error) -> Self { + Self::ServerError(None) + } +} + +impl From for FcmError { + fn from(_: hyper::http::Error) -> Self { Self::ServerError(None) } }