Skip to content

Commit

Permalink
switch to hyper while staying 100% compatible
Browse files Browse the repository at this point in the history
  • Loading branch information
Stephan Dilly committed May 19, 2021
1 parent a01fee7 commit 5c149b2
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 29 deletions.
16 changes: 9 additions & 7 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
47 changes: 27 additions & 20 deletions src/client/mod.rs
Original file line number Diff line number Diff line change
@@ -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<HttpsConnector<HttpConnector>>,
}

impl Default for Client {
Expand All @@ -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<FcmResponse, FcmError> {
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::<RetryAfter>().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)),
Expand Down
16 changes: 14 additions & 2 deletions src/client/response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,8 +158,20 @@ impl fmt::Display for FcmError {
}
}

impl From<reqwest::Error> for FcmError {
fn from(_: reqwest::Error) -> Self {
impl From<serde_json::Error> for FcmError {
fn from(_: serde_json::Error) -> Self {
Self::ServerError(None)
}
}

impl From<hyper::Error> for FcmError {
fn from(_: hyper::Error) -> Self {
Self::ServerError(None)
}
}

impl From<hyper::http::Error> for FcmError {
fn from(_: hyper::http::Error) -> Self {
Self::ServerError(None)
}
}
Expand Down

0 comments on commit 5c149b2

Please sign in to comment.