From 26422fc5348b4f5d124d6c0b32e3c5a1e01a5af9 Mon Sep 17 00:00:00 2001 From: Jose Celano Date: Fri, 9 Feb 2024 16:25:58 +0000 Subject: [PATCH] feat: [#472] add timeout to API client requests both in testing and production clients. --- src/web/api/client/v1/connection_info.rs | 3 ++- src/web/api/client/v1/http.rs | 17 ++++++++++++++++- tests/common/client.rs | 17 ++++++++++++++++- 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/src/web/api/client/v1/connection_info.rs b/src/web/api/client/v1/connection_info.rs index 4aa3e927..8c186732 100644 --- a/src/web/api/client/v1/connection_info.rs +++ b/src/web/api/client/v1/connection_info.rs @@ -1,4 +1,5 @@ -use std::{fmt, str::FromStr}; +use std::fmt; +use std::str::FromStr; use reqwest::Url; diff --git a/src/web/api/client/v1/http.rs b/src/web/api/client/v1/http.rs index 7ae7823e..1c90890a 100644 --- a/src/web/api/client/v1/http.rs +++ b/src/web/api/client/v1/http.rs @@ -1,3 +1,5 @@ +use std::time::Duration; + use reqwest::multipart; use serde::Serialize; @@ -65,12 +67,18 @@ impl From for ReqwestQueryParam { /// Generic HTTP Client pub struct Http { connection_info: ConnectionInfo, + /// The timeout is applied from when the request starts connecting until the + /// response body has finished. + timeout: Duration, } impl Http { #[must_use] pub fn new(connection_info: ConnectionInfo) -> Self { - Self { connection_info } + Self { + connection_info, + timeout: Duration::from_secs(5), + } } /// # Panics @@ -80,6 +88,7 @@ impl Http { pub async fn get(&self, path: &str, params: Query) -> TextResponse { let response = match &self.connection_info.token { Some(token) => reqwest::Client::builder() + .timeout(self.timeout) .build() .unwrap() .get(self.base_url(path).clone()) @@ -89,6 +98,7 @@ impl Http { .await .unwrap(), None => reqwest::Client::builder() + .timeout(self.timeout) .build() .unwrap() .get(self.base_url(path).clone()) @@ -107,6 +117,7 @@ impl Http { pub async fn get_binary(&self, path: &str, params: Query) -> BinaryResponse { let response = match &self.connection_info.token { Some(token) => reqwest::Client::builder() + .timeout(self.timeout) .build() .unwrap() .get(self.base_url(path).clone()) @@ -116,6 +127,7 @@ impl Http { .await .unwrap(), None => reqwest::Client::builder() + .timeout(self.timeout) .build() .unwrap() .get(self.base_url(path).clone()) @@ -141,6 +153,7 @@ impl Http { /// This method fails it can't build a `reqwest` client. pub async fn inner_get(&self, path: &str) -> Result { reqwest::Client::builder() + .timeout(self.timeout) .build() .unwrap() .get(self.base_url(path).clone()) @@ -178,6 +191,7 @@ impl Http { pub async fn post_multipart(&self, path: &str, form: multipart::Form) -> TextResponse { let response = match &self.connection_info.token { Some(token) => reqwest::Client::builder() + .timeout(self.timeout) .build() .unwrap() .post(self.base_url(path).clone()) @@ -187,6 +201,7 @@ impl Http { .await .expect("failed to send multipart request with token"), None => reqwest::Client::builder() + .timeout(self.timeout) .build() .unwrap() .post(self.base_url(path).clone()) diff --git a/tests/common/client.rs b/tests/common/client.rs index 97216bfa..1e938d1d 100644 --- a/tests/common/client.rs +++ b/tests/common/client.rs @@ -1,3 +1,5 @@ +use std::time::Duration; + use reqwest::multipart; use serde::Serialize; @@ -158,16 +160,23 @@ impl Client { /// Generic HTTP Client struct Http { connection_info: ConnectionInfo, + /// The timeout is applied from when the request starts connecting until the + /// response body has finished. + timeout: Duration, } impl Http { pub fn new(connection_info: ConnectionInfo) -> Self { - Self { connection_info } + Self { + connection_info, + timeout: Duration::from_secs(5), + } } pub async fn get(&self, path: &str, params: Query) -> TextResponse { let response = match &self.connection_info.token { Some(token) => reqwest::Client::builder() + .timeout(self.timeout) .build() .unwrap() .get(self.base_url(path).clone()) @@ -177,6 +186,7 @@ impl Http { .await .unwrap(), None => reqwest::Client::builder() + .timeout(self.timeout) .build() .unwrap() .get(self.base_url(path).clone()) @@ -191,6 +201,7 @@ impl Http { pub async fn get_binary(&self, path: &str, params: Query) -> BinaryResponse { let response = match &self.connection_info.token { Some(token) => reqwest::Client::builder() + .timeout(self.timeout) .build() .unwrap() .get(self.base_url(path).clone()) @@ -200,6 +211,7 @@ impl Http { .await .unwrap(), None => reqwest::Client::builder() + .timeout(self.timeout) .build() .unwrap() .get(self.base_url(path).clone()) @@ -217,6 +229,7 @@ impl Http { pub async fn inner_get(&self, path: &str) -> Result { reqwest::Client::builder() + .timeout(self.timeout) .build() .unwrap() .get(self.base_url(path).clone()) @@ -246,6 +259,7 @@ impl Http { pub async fn post_multipart(&self, path: &str, form: multipart::Form) -> TextResponse { let response = match &self.connection_info.token { Some(token) => reqwest::Client::builder() + .timeout(self.timeout) .build() .unwrap() .post(self.base_url(path).clone()) @@ -255,6 +269,7 @@ impl Http { .await .expect("failed to send multipart request with token"), None => reqwest::Client::builder() + .timeout(self.timeout) .build() .unwrap() .post(self.base_url(path).clone())