diff --git a/services/tunnelbroker/src/constants.rs b/services/tunnelbroker/src/constants.rs --- a/services/tunnelbroker/src/constants.rs +++ b/services/tunnelbroker/src/constants.rs @@ -20,6 +20,8 @@ tracing_subscriber::filter::EnvFilter::DEFAULT_ENV; pub const FCM_ACCESS_TOKEN_GENERATION_THRESHOLD: u64 = 5 * 60; +pub const PUSH_SERVICE_REQUEST_TIMEOUT: Duration = Duration::from_secs(8); + pub mod dynamodb { // This table holds messages which could not be immediately delivered to // a device. diff --git a/services/tunnelbroker/src/notifs/apns/mod.rs b/services/tunnelbroker/src/notifs/apns/mod.rs --- a/services/tunnelbroker/src/notifs/apns/mod.rs +++ b/services/tunnelbroker/src/notifs/apns/mod.rs @@ -1,3 +1,4 @@ +use crate::constants::PUSH_SERVICE_REQUEST_TIMEOUT; use crate::notifs::apns::config::APNsConfig; use crate::notifs::apns::error::Error::ResponseError; use crate::notifs::apns::headers::{NotificationHeaders, PushType}; @@ -38,6 +39,7 @@ .http2_prior_knowledge() .http2_keep_alive_interval(Some(Duration::from_secs(5))) .http2_keep_alive_while_idle(true) + .timeout(PUSH_SERVICE_REQUEST_TIMEOUT) .build()?; Ok(APNsClient { diff --git a/services/tunnelbroker/src/notifs/fcm/mod.rs b/services/tunnelbroker/src/notifs/fcm/mod.rs --- a/services/tunnelbroker/src/notifs/fcm/mod.rs +++ b/services/tunnelbroker/src/notifs/fcm/mod.rs @@ -1,3 +1,4 @@ +use crate::constants::PUSH_SERVICE_REQUEST_TIMEOUT; use crate::notifs::fcm::config::FCMConfig; use crate::notifs::fcm::error::Error::FCMError; use crate::notifs::fcm::firebase_message::{FCMMessage, FCMMessageWrapper}; @@ -23,7 +24,9 @@ impl FCMClient { pub fn new(config: &FCMConfig) -> Result { - let http_client = reqwest::Client::builder().build()?; + let http_client = reqwest::Client::builder() + .timeout(PUSH_SERVICE_REQUEST_TIMEOUT) + .build()?; // Token must be a short-lived token (60 minutes) and in a reasonable // timeframe. diff --git a/services/tunnelbroker/src/notifs/web_push/mod.rs b/services/tunnelbroker/src/notifs/web_push/mod.rs --- a/services/tunnelbroker/src/notifs/web_push/mod.rs +++ b/services/tunnelbroker/src/notifs/web_push/mod.rs @@ -1,3 +1,4 @@ +use crate::constants::PUSH_SERVICE_REQUEST_TIMEOUT; use serde::{Deserialize, Serialize}; use web_push::{ ContentEncoding, HyperWebPushClient, SubscriptionInfo, VapidSignatureBuilder, @@ -53,7 +54,13 @@ builder.set_vapid_signature(vapid_signature); let message = builder.build()?; - self.inner_client.send(message).await?; + let response_future = self.inner_client.send(message); + + tokio::time::timeout(PUSH_SERVICE_REQUEST_TIMEOUT, response_future) + .await + .map_err(|err| { + error::Error::WebPush(web_push::WebPushError::Other(err.to_string())) + })??; Ok(()) } diff --git a/services/tunnelbroker/src/notifs/wns/mod.rs b/services/tunnelbroker/src/notifs/wns/mod.rs --- a/services/tunnelbroker/src/notifs/wns/mod.rs +++ b/services/tunnelbroker/src/notifs/wns/mod.rs @@ -1,3 +1,4 @@ +use crate::constants::PUSH_SERVICE_REQUEST_TIMEOUT; use crate::notifs::wns::config::WNSConfig; use error::WNSTokenError; use reqwest::StatusCode; @@ -32,7 +33,9 @@ impl WNSClient { pub fn new(config: &WNSConfig) -> Result { - let http_client = reqwest::Client::builder().build()?; + let http_client = reqwest::Client::builder() + .timeout(PUSH_SERVICE_REQUEST_TIMEOUT) + .build()?; Ok(WNSClient { http_client, config: config.clone(),