diff --git a/packages/axum-rest-tracker-api-server/tests/server/v1/contract/authentication.rs b/packages/axum-rest-tracker-api-server/tests/server/v1/contract/authentication.rs index eac30d93a..3b6419187 100644 --- a/packages/axum-rest-tracker-api-server/tests/server/v1/contract/authentication.rs +++ b/packages/axum-rest-tracker-api-server/tests/server/v1/contract/authentication.rs @@ -16,6 +16,7 @@ async fn should_authenticate_requests_by_using_a_token_query_param() { let token = env.get_connection_info().api_token.unwrap(); let response = Client::new(env.get_connection_info()) + .unwrap() .get_request_with_query("stats", Query::params([QueryParam::new("token", &token)].to_vec()), None) .await; @@ -33,6 +34,7 @@ async fn should_not_authenticate_requests_when_the_token_is_missing() { let request_id = Uuid::new_v4(); let response = Client::new(env.get_connection_info()) + .unwrap() .get_request_with_query("stats", Query::default(), Some(headers_with_request_id(request_id))) .await; @@ -55,6 +57,7 @@ async fn should_not_authenticate_requests_when_the_token_is_empty() { let request_id = Uuid::new_v4(); let response = Client::new(env.get_connection_info()) + .unwrap() .get_request_with_query( "stats", Query::params([QueryParam::new("token", "")].to_vec()), @@ -81,6 +84,7 @@ async fn should_not_authenticate_requests_when_the_token_is_invalid() { let request_id = Uuid::new_v4(); let response = Client::new(env.get_connection_info()) + .unwrap() .get_request_with_query( "stats", Query::params([QueryParam::new("token", "INVALID TOKEN")].to_vec()), @@ -108,6 +112,7 @@ async fn should_allow_the_token_query_param_to_be_at_any_position_in_the_url_que // At the beginning of the query component let response = Client::new(env.get_connection_info()) + .unwrap() .get_request(&format!("torrents?token={token}&limit=1")) .await; @@ -115,6 +120,7 @@ async fn should_allow_the_token_query_param_to_be_at_any_position_in_the_url_que // At the end of the query component let response = Client::new(env.get_connection_info()) + .unwrap() .get_request(&format!("torrents?limit=1&token={token}")) .await; diff --git a/packages/axum-rest-tracker-api-server/tests/server/v1/contract/context/auth_key.rs b/packages/axum-rest-tracker-api-server/tests/server/v1/contract/context/auth_key.rs index f6355fc6e..3781f4f60 100644 --- a/packages/axum-rest-tracker-api-server/tests/server/v1/contract/context/auth_key.rs +++ b/packages/axum-rest-tracker-api-server/tests/server/v1/contract/context/auth_key.rs @@ -25,6 +25,7 @@ async fn should_allow_generating_a_new_random_auth_key() { let request_id = Uuid::new_v4(); let response = Client::new(env.get_connection_info()) + .unwrap() .add_auth_key( AddKeyForm { opt_key: None, @@ -56,6 +57,7 @@ async fn should_allow_uploading_a_preexisting_auth_key() { let request_id = Uuid::new_v4(); let response = Client::new(env.get_connection_info()) + .unwrap() .add_auth_key( AddKeyForm { opt_key: Some("Xc1L4PbQJSFGlrgSRZl8wxSFAuMa21z5".to_string()), @@ -87,6 +89,7 @@ async fn should_not_allow_generating_a_new_auth_key_for_unauthenticated_users() let request_id = Uuid::new_v4(); let response = Client::new(connection_with_invalid_token(env.get_connection_info().origin)) + .unwrap() .add_auth_key( AddKeyForm { opt_key: None, @@ -106,6 +109,7 @@ async fn should_not_allow_generating_a_new_auth_key_for_unauthenticated_users() let request_id = Uuid::new_v4(); let response = Client::new(connection_with_no_token(env.get_connection_info().origin)) + .unwrap() .add_auth_key( AddKeyForm { opt_key: None, @@ -136,6 +140,7 @@ async fn should_fail_when_the_auth_key_cannot_be_generated() { let request_id = Uuid::new_v4(); let response = Client::new(env.get_connection_info()) + .unwrap() .add_auth_key( AddKeyForm { opt_key: None, @@ -173,6 +178,7 @@ async fn should_allow_deleting_an_auth_key() { let request_id = Uuid::new_v4(); let response = Client::new(env.get_connection_info()) + .unwrap() .delete_auth_key(&auth_key.key.to_string(), Some(headers_with_request_id(request_id))) .await; @@ -207,6 +213,7 @@ async fn should_fail_generating_a_new_auth_key_when_the_provided_key_is_invalid( let request_id = Uuid::new_v4(); let response = Client::new(env.get_connection_info()) + .unwrap() .post_form( "keys", &InvalidAddKeyForm { @@ -246,6 +253,7 @@ async fn should_fail_generating_a_new_auth_key_when_the_key_duration_is_invalid( let request_id = Uuid::new_v4(); let response = Client::new(env.get_connection_info()) + .unwrap() .post_form( "keys", &InvalidAddKeyForm { @@ -282,6 +290,7 @@ async fn should_fail_deleting_an_auth_key_when_the_key_id_is_invalid() { let request_id = Uuid::new_v4(); let response = Client::new(env.get_connection_info()) + .unwrap() .delete_auth_key(invalid_auth_key, Some(headers_with_request_id(request_id))) .await; @@ -311,6 +320,7 @@ async fn should_fail_when_the_auth_key_cannot_be_deleted() { let request_id = Uuid::new_v4(); let response = Client::new(env.get_connection_info()) + .unwrap() .delete_auth_key(&auth_key.key.to_string(), Some(headers_with_request_id(request_id))) .await; @@ -344,6 +354,7 @@ async fn should_not_allow_deleting_an_auth_key_for_unauthenticated_users() { let request_id = Uuid::new_v4(); let response = Client::new(connection_with_invalid_token(env.get_connection_info().origin)) + .unwrap() .delete_auth_key(&auth_key.key.to_string(), Some(headers_with_request_id(request_id))) .await; @@ -366,6 +377,7 @@ async fn should_not_allow_deleting_an_auth_key_for_unauthenticated_users() { let request_id = Uuid::new_v4(); let response = Client::new(connection_with_no_token(env.get_connection_info().origin)) + .unwrap() .delete_auth_key(&auth_key.key.to_string(), Some(headers_with_request_id(request_id))) .await; @@ -396,6 +408,7 @@ async fn should_allow_reloading_keys() { let request_id = Uuid::new_v4(); let response = Client::new(env.get_connection_info()) + .unwrap() .reload_keys(Some(headers_with_request_id(request_id))) .await; @@ -423,6 +436,7 @@ async fn should_fail_when_keys_cannot_be_reloaded() { force_database_error(&env.container.tracker_core_container.database); let response = Client::new(env.get_connection_info()) + .unwrap() .reload_keys(Some(headers_with_request_id(request_id))) .await; @@ -453,6 +467,7 @@ async fn should_not_allow_reloading_keys_for_unauthenticated_users() { let request_id = Uuid::new_v4(); let response = Client::new(connection_with_invalid_token(env.get_connection_info().origin)) + .unwrap() .reload_keys(Some(headers_with_request_id(request_id))) .await; @@ -466,6 +481,7 @@ async fn should_not_allow_reloading_keys_for_unauthenticated_users() { let request_id = Uuid::new_v4(); let response = Client::new(connection_with_no_token(env.get_connection_info().origin)) + .unwrap() .reload_keys(Some(headers_with_request_id(request_id))) .await; @@ -504,6 +520,7 @@ mod deprecated_generate_key_endpoint { let seconds_valid = 60; let response = Client::new(env.get_connection_info()) + .unwrap() .generate_auth_key(seconds_valid, None) .await; @@ -530,12 +547,14 @@ mod deprecated_generate_key_endpoint { let seconds_valid = 60; let response = Client::new(connection_with_invalid_token(env.get_connection_info().origin)) + .unwrap() .generate_auth_key(seconds_valid, Some(headers_with_request_id(request_id))) .await; assert_token_not_valid(response).await; let response = Client::new(connection_with_no_token(env.get_connection_info().origin)) + .unwrap() .generate_auth_key(seconds_valid, None) .await; @@ -563,6 +582,7 @@ mod deprecated_generate_key_endpoint { for invalid_key_duration in invalid_key_durations { let response = Client::new(env.get_connection_info()) + .unwrap() .post_empty(&format!("key/{invalid_key_duration}"), None) .await; @@ -583,6 +603,7 @@ mod deprecated_generate_key_endpoint { let request_id = Uuid::new_v4(); let seconds_valid = 60; let response = Client::new(env.get_connection_info()) + .unwrap() .generate_auth_key(seconds_valid, Some(headers_with_request_id(request_id))) .await; diff --git a/packages/axum-rest-tracker-api-server/tests/server/v1/contract/context/stats.rs b/packages/axum-rest-tracker-api-server/tests/server/v1/contract/context/stats.rs index 1e66eb4cc..51a4804e7 100644 --- a/packages/axum-rest-tracker-api-server/tests/server/v1/contract/context/stats.rs +++ b/packages/axum-rest-tracker-api-server/tests/server/v1/contract/context/stats.rs @@ -26,6 +26,7 @@ async fn should_allow_getting_tracker_statistics() { let request_id = Uuid::new_v4(); let response = Client::new(env.get_connection_info()) + .unwrap() .get_tracker_statistics(Some(headers_with_request_id(request_id))) .await; @@ -80,6 +81,7 @@ async fn should_not_allow_getting_tracker_statistics_for_unauthenticated_users() let request_id = Uuid::new_v4(); let response = Client::new(connection_with_invalid_token(env.get_connection_info().origin)) + .unwrap() .get_tracker_statistics(Some(headers_with_request_id(request_id))) .await; @@ -93,6 +95,7 @@ async fn should_not_allow_getting_tracker_statistics_for_unauthenticated_users() let request_id = Uuid::new_v4(); let response = Client::new(connection_with_no_token(env.get_connection_info().origin)) + .unwrap() .get_tracker_statistics(Some(headers_with_request_id(request_id))) .await; diff --git a/packages/axum-rest-tracker-api-server/tests/server/v1/contract/context/torrent.rs b/packages/axum-rest-tracker-api-server/tests/server/v1/contract/context/torrent.rs index b479416e4..42421db99 100644 --- a/packages/axum-rest-tracker-api-server/tests/server/v1/contract/context/torrent.rs +++ b/packages/axum-rest-tracker-api-server/tests/server/v1/contract/context/torrent.rs @@ -31,6 +31,7 @@ async fn should_allow_getting_all_torrents() { let request_id = Uuid::new_v4(); let response = Client::new(env.get_connection_info()) + .unwrap() .get_torrents(Query::empty(), Some(headers_with_request_id(request_id))) .await; @@ -64,6 +65,7 @@ async fn should_allow_limiting_the_torrents_in_the_result() { let request_id = Uuid::new_v4(); let response = Client::new(env.get_connection_info()) + .unwrap() .get_torrents( Query::params([QueryParam::new("limit", "1")].to_vec()), Some(headers_with_request_id(request_id)), @@ -100,6 +102,7 @@ async fn should_allow_the_torrents_result_pagination() { let request_id = Uuid::new_v4(); let response = Client::new(env.get_connection_info()) + .unwrap() .get_torrents( Query::params([QueryParam::new("offset", "1")].to_vec()), Some(headers_with_request_id(request_id)), @@ -135,6 +138,7 @@ async fn should_allow_getting_a_list_of_torrents_providing_infohashes() { let request_id = Uuid::new_v4(); let response = Client::new(env.get_connection_info()) + .unwrap() .get_torrents( Query::params( [ @@ -181,6 +185,7 @@ async fn should_fail_getting_torrents_when_the_offset_query_parameter_cannot_be_ let request_id = Uuid::new_v4(); let response = Client::new(env.get_connection_info()) + .unwrap() .get_torrents( Query::params([QueryParam::new("offset", invalid_offset)].to_vec()), Some(headers_with_request_id(request_id)), @@ -209,6 +214,7 @@ async fn should_fail_getting_torrents_when_the_limit_query_parameter_cannot_be_p let request_id = Uuid::new_v4(); let response = Client::new(env.get_connection_info()) + .unwrap() .get_torrents( Query::params([QueryParam::new("limit", invalid_limit)].to_vec()), Some(headers_with_request_id(request_id)), @@ -237,6 +243,7 @@ async fn should_fail_getting_torrents_when_the_info_hash_parameter_is_invalid() let request_id = Uuid::new_v4(); let response = Client::new(env.get_connection_info()) + .unwrap() .get_torrents( Query::params([QueryParam::new("info_hash", invalid_info_hash)].to_vec()), Some(headers_with_request_id(request_id)), @@ -262,6 +269,7 @@ async fn should_not_allow_getting_torrents_for_unauthenticated_users() { let request_id = Uuid::new_v4(); let response = Client::new(connection_with_invalid_token(env.get_connection_info().origin)) + .unwrap() .get_torrents(Query::empty(), Some(headers_with_request_id(request_id))) .await; @@ -275,6 +283,7 @@ async fn should_not_allow_getting_torrents_for_unauthenticated_users() { let request_id = Uuid::new_v4(); let response = Client::new(connection_with_no_token(env.get_connection_info().origin)) + .unwrap() .get_torrents(Query::default(), Some(headers_with_request_id(request_id))) .await; @@ -303,6 +312,7 @@ async fn should_allow_getting_a_torrent_info() { let request_id = Uuid::new_v4(); let response = Client::new(env.get_connection_info()) + .unwrap() .get_torrent(&info_hash.to_string(), Some(headers_with_request_id(request_id))) .await; @@ -331,6 +341,7 @@ async fn should_fail_while_getting_a_torrent_info_when_the_torrent_does_not_exis let info_hash = InfoHash::from_str("9e0217d0fa71c87332cd8bf9dbeabcb2c2cf3c4d").unwrap(); // DevSkim: ignore DS173237 let response = Client::new(env.get_connection_info()) + .unwrap() .get_torrent(&info_hash.to_string(), Some(headers_with_request_id(request_id))) .await; @@ -349,6 +360,7 @@ async fn should_fail_getting_a_torrent_info_when_the_provided_infohash_is_invali let request_id = Uuid::new_v4(); let response = Client::new(env.get_connection_info()) + .unwrap() .get_torrent(invalid_infohash, Some(headers_with_request_id(request_id))) .await; @@ -359,6 +371,7 @@ async fn should_fail_getting_a_torrent_info_when_the_provided_infohash_is_invali let request_id = Uuid::new_v4(); let response = Client::new(env.get_connection_info()) + .unwrap() .get_torrent(invalid_infohash, Some(headers_with_request_id(request_id))) .await; @@ -381,6 +394,7 @@ async fn should_not_allow_getting_a_torrent_info_for_unauthenticated_users() { let request_id = Uuid::new_v4(); let response = Client::new(connection_with_invalid_token(env.get_connection_info().origin)) + .unwrap() .get_torrent(&info_hash.to_string(), Some(headers_with_request_id(request_id))) .await; @@ -394,6 +408,7 @@ async fn should_not_allow_getting_a_torrent_info_for_unauthenticated_users() { let request_id = Uuid::new_v4(); let response = Client::new(connection_with_no_token(env.get_connection_info().origin)) + .unwrap() .get_torrent(&info_hash.to_string(), Some(headers_with_request_id(request_id))) .await; diff --git a/packages/axum-rest-tracker-api-server/tests/server/v1/contract/context/whitelist.rs b/packages/axum-rest-tracker-api-server/tests/server/v1/contract/context/whitelist.rs index e8f98b8ab..61fc233d0 100644 --- a/packages/axum-rest-tracker-api-server/tests/server/v1/contract/context/whitelist.rs +++ b/packages/axum-rest-tracker-api-server/tests/server/v1/contract/context/whitelist.rs @@ -25,6 +25,7 @@ async fn should_allow_whitelisting_a_torrent() { let info_hash = "9e0217d0fa71c87332cd8bf9dbeabcb2c2cf3c4d".to_owned(); // DevSkim: ignore DS173237 let response = Client::new(env.get_connection_info()) + .unwrap() .whitelist_a_torrent(&info_hash, Some(headers_with_request_id(request_id))) .await; @@ -48,7 +49,7 @@ async fn should_allow_whitelisting_a_torrent_that_has_been_already_whitelisted() let info_hash = "9e0217d0fa71c87332cd8bf9dbeabcb2c2cf3c4d".to_owned(); // DevSkim: ignore DS173237 - let api_client = Client::new(env.get_connection_info()); + let api_client = Client::new(env.get_connection_info()).unwrap(); let request_id = Uuid::new_v4(); @@ -78,6 +79,7 @@ async fn should_not_allow_whitelisting_a_torrent_for_unauthenticated_users() { let request_id = Uuid::new_v4(); let response = Client::new(connection_with_invalid_token(env.get_connection_info().origin)) + .unwrap() .whitelist_a_torrent(&info_hash, Some(headers_with_request_id(request_id))) .await; @@ -91,6 +93,7 @@ async fn should_not_allow_whitelisting_a_torrent_for_unauthenticated_users() { let request_id = Uuid::new_v4(); let response = Client::new(connection_with_no_token(env.get_connection_info().origin)) + .unwrap() .whitelist_a_torrent(&info_hash, Some(headers_with_request_id(request_id))) .await; @@ -117,6 +120,7 @@ async fn should_fail_when_the_torrent_cannot_be_whitelisted() { let request_id = Uuid::new_v4(); let response = Client::new(env.get_connection_info()) + .unwrap() .whitelist_a_torrent(&info_hash, Some(headers_with_request_id(request_id))) .await; @@ -140,6 +144,7 @@ async fn should_fail_whitelisting_a_torrent_when_the_provided_infohash_is_invali for invalid_infohash in &invalid_infohashes_returning_bad_request() { let response = Client::new(env.get_connection_info()) + .unwrap() .whitelist_a_torrent(invalid_infohash, Some(headers_with_request_id(request_id))) .await; @@ -150,6 +155,7 @@ async fn should_fail_whitelisting_a_torrent_when_the_provided_infohash_is_invali for invalid_infohash in &invalid_infohashes_returning_not_found() { let response = Client::new(env.get_connection_info()) + .unwrap() .whitelist_a_torrent(invalid_infohash, Some(headers_with_request_id(request_id))) .await; @@ -178,6 +184,7 @@ async fn should_allow_removing_a_torrent_from_the_whitelist() { let request_id = Uuid::new_v4(); let response = Client::new(env.get_connection_info()) + .unwrap() .remove_torrent_from_whitelist(&hash, Some(headers_with_request_id(request_id))) .await; @@ -204,6 +211,7 @@ async fn should_not_fail_trying_to_remove_a_non_whitelisted_torrent_from_the_whi let request_id = Uuid::new_v4(); let response = Client::new(env.get_connection_info()) + .unwrap() .remove_torrent_from_whitelist(&non_whitelisted_torrent_hash, Some(headers_with_request_id(request_id))) .await; @@ -222,6 +230,7 @@ async fn should_fail_removing_a_torrent_from_the_whitelist_when_the_provided_inf let request_id = Uuid::new_v4(); let response = Client::new(env.get_connection_info()) + .unwrap() .remove_torrent_from_whitelist(invalid_infohash, Some(headers_with_request_id(request_id))) .await; @@ -232,6 +241,7 @@ async fn should_fail_removing_a_torrent_from_the_whitelist_when_the_provided_inf let request_id = Uuid::new_v4(); let response = Client::new(env.get_connection_info()) + .unwrap() .remove_torrent_from_whitelist(invalid_infohash, Some(headers_with_request_id(request_id))) .await; @@ -261,6 +271,7 @@ async fn should_fail_when_the_torrent_cannot_be_removed_from_the_whitelist() { let request_id = Uuid::new_v4(); let response = Client::new(env.get_connection_info()) + .unwrap() .remove_torrent_from_whitelist(&hash, Some(headers_with_request_id(request_id))) .await; @@ -293,6 +304,7 @@ async fn should_not_allow_removing_a_torrent_from_the_whitelist_for_unauthentica let request_id = Uuid::new_v4(); let response = Client::new(connection_with_invalid_token(env.get_connection_info().origin)) + .unwrap() .remove_torrent_from_whitelist(&hash, Some(headers_with_request_id(request_id))) .await; @@ -313,6 +325,7 @@ async fn should_not_allow_removing_a_torrent_from_the_whitelist_for_unauthentica let request_id = Uuid::new_v4(); let response = Client::new(connection_with_no_token(env.get_connection_info().origin)) + .unwrap() .remove_torrent_from_whitelist(&hash, Some(headers_with_request_id(request_id))) .await; @@ -334,6 +347,7 @@ async fn should_allow_reload_the_whitelist_from_the_database() { let hash = "9e0217d0fa71c87332cd8bf9dbeabcb2c2cf3c4d".to_owned(); // DevSkim: ignore DS173237 let info_hash = InfoHash::from_str(&hash).unwrap(); + env.container .tracker_core_container .whitelist_manager @@ -344,6 +358,7 @@ async fn should_allow_reload_the_whitelist_from_the_database() { let request_id = Uuid::new_v4(); let response = Client::new(env.get_connection_info()) + .unwrap() .reload_whitelist(Some(headers_with_request_id(request_id))) .await; @@ -382,6 +397,7 @@ async fn should_fail_when_the_whitelist_cannot_be_reloaded_from_the_database() { let request_id = Uuid::new_v4(); let response = Client::new(env.get_connection_info()) + .unwrap() .reload_whitelist(Some(headers_with_request_id(request_id))) .await; diff --git a/packages/rest-tracker-api-client/src/v1/client.rs b/packages/rest-tracker-api-client/src/v1/client.rs index 54daa3289..65e3fceb8 100644 --- a/packages/rest-tracker-api-client/src/v1/client.rs +++ b/packages/rest-tracker-api-client/src/v1/client.rs @@ -1,5 +1,7 @@ +use std::time::Duration; + use hyper::HeaderMap; -use reqwest::Response; +use reqwest::{Error, Response}; use serde::Serialize; use url::Url; use uuid::Uuid; @@ -7,19 +9,31 @@ use uuid::Uuid; use crate::common::http::{Query, QueryParam, ReqwestQuery}; use crate::connection_info::ConnectionInfo; +const TOKEN_PARAM_NAME: &str = "token"; +const API_PATH: &str = "api/v1/"; +const DEFAULT_REQUEST_TIMEOUT_IN_SECS: u64 = 5; + /// API Client pub struct Client { connection_info: ConnectionInfo, base_path: String, + client: reqwest::Client, } impl Client { - #[must_use] - pub fn new(connection_info: ConnectionInfo) -> Self { - Self { + /// # Errors + /// + /// Will return an error if the HTTP client can't be created. + pub fn new(connection_info: ConnectionInfo) -> Result<Self, Error> { + let client = reqwest::Client::builder() + .timeout(Duration::from_secs(DEFAULT_REQUEST_TIMEOUT_IN_SECS)) + .build()?; + + Ok(Self { connection_info, - base_path: "api/v1/".to_string(), - } + base_path: API_PATH.to_string(), + client, + }) } pub async fn generate_auth_key(&self, seconds_valid: i32, headers: Option<HeaderMap>) -> Response { @@ -66,7 +80,7 @@ impl Client { let mut query: Query = params; if let Some(token) = &self.connection_info.api_token { - query.add_param(QueryParam::new("token", token)); + query.add_param(QueryParam::new(TOKEN_PARAM_NAME, token)); } self.get_request_with_query(path, query, headers).await @@ -76,7 +90,8 @@ impl Client { /// /// Will panic if the request can't be sent pub async fn post_empty(&self, path: &str, headers: Option<HeaderMap>) -> Response { - let builder = reqwest::Client::new() + let builder = self + .client .post(self.base_url(path).clone()) .query(&ReqwestQuery::from(self.query_with_token())); @@ -92,7 +107,8 @@ impl Client { /// /// Will panic if the request can't be sent pub async fn post_form<T: Serialize + ?Sized>(&self, path: &str, form: &T, headers: Option<HeaderMap>) -> Response { - let builder = reqwest::Client::new() + let builder = self + .client .post(self.base_url(path).clone()) .query(&ReqwestQuery::from(self.query_with_token())) .json(&form); @@ -109,7 +125,8 @@ impl Client { /// /// Will panic if the request can't be sent async fn delete(&self, path: &str, headers: Option<HeaderMap>) -> Response { - let builder = reqwest::Client::new() + let builder = self + .client .delete(self.base_url(path).clone()) .query(&ReqwestQuery::from(self.query_with_token())); @@ -145,7 +162,10 @@ impl Client { /// /// Will panic if the request can't be sent pub async fn get(path: Url, query: Option<Query>, headers: Option<HeaderMap>) -> Response { - let builder = reqwest::Client::builder().build().unwrap(); + let builder = reqwest::Client::builder() + .timeout(Duration::from_secs(DEFAULT_REQUEST_TIMEOUT_IN_SECS)) + .build() + .unwrap(); let builder = match query { Some(params) => builder.get(path).query(&ReqwestQuery::from(params)),