[fractal] Make get_client() infallible



commit 0f1512161542754433868d145894c1a1c32576f4
Author: Alejandro Domínguez <adomu net-c com>
Date:   Mon Jul 6 17:55:58 2020 +0200

    Make get_client() infallible
    
    If getting the system proxies fails, the request will fail.
    This will enable us to use only the reqwest error type easily
    in many places.

 fractal-gtk/src/backend/directory.rs |  5 +--
 fractal-gtk/src/backend/media.rs     |  2 +-
 fractal-gtk/src/backend/mod.rs       |  4 +-
 fractal-gtk/src/backend/register.rs  |  6 +--
 fractal-gtk/src/backend/room.rs      | 42 +++++++++---------
 fractal-gtk/src/backend/sync.rs      |  2 +-
 fractal-gtk/src/backend/user.rs      | 30 ++++++-------
 fractal-gtk/src/client.rs            | 85 +++++++++++++++++++-----------------
 8 files changed, 89 insertions(+), 87 deletions(-)
---
diff --git a/fractal-gtk/src/backend/directory.rs b/fractal-gtk/src/backend/directory.rs
index c2902f6e..3fbb8b67 100644
--- a/fractal-gtk/src/backend/directory.rs
+++ b/fractal-gtk/src/backend/directory.rs
@@ -48,8 +48,7 @@ pub fn protocols(
 ) -> Result<Vec<ProtocolInstance>, DirectoryProtocolsError> {
     let params = SupportedProtocolsParameters { access_token };
     let request = get_supported_protocols(base, &params)?;
-    let response: SupportedProtocolsResponse =
-        HTTP_CLIENT.get_client()?.execute(request)?.json()?;
+    let response: SupportedProtocolsResponse = HTTP_CLIENT.get_client().execute(request)?.json()?;
 
     Ok(response
         .into_iter()
@@ -117,7 +116,7 @@ pub fn room_search(
     };
 
     let request = post_public_rooms(base.clone(), &params, &body)?;
-    let response: PublicRoomsResponse = HTTP_CLIENT.get_client()?.execute(request)?.json()?;
+    let response: PublicRoomsResponse = HTTP_CLIENT.get_client().execute(request)?.json()?;
 
     let since = response.next_batch;
     let rooms = response
diff --git a/fractal-gtk/src/backend/media.rs b/fractal-gtk/src/backend/media.rs
index 1ae3cd8e..9b46553a 100644
--- a/fractal-gtk/src/backend/media.rs
+++ b/fractal-gtk/src/backend/media.rs
@@ -93,7 +93,7 @@ fn get_room_media_list(
     };
 
     let request = get_messages_events_req(baseu, &params, room_id)?;
-    let response: GetMessagesEventsResponse = HTTP_CLIENT.get_client()?.execute(request)?.json()?;
+    let response: GetMessagesEventsResponse = HTTP_CLIENT.get_client().execute(request)?.json()?;
 
     let prev_batch = response.end.unwrap_or_default();
     let evs = response.chunk.iter().rev();
diff --git a/fractal-gtk/src/backend/mod.rs b/fractal-gtk/src/backend/mod.rs
index 06c6d173..23d5910c 100644
--- a/fractal-gtk/src/backend/mod.rs
+++ b/fractal-gtk/src/backend/mod.rs
@@ -108,7 +108,7 @@ pub fn get_prev_batch_from(
     };
 
     let request = get_context(base, &params, room_id, event_id)?;
-    let response: GetContextResponse = HTTP_CLIENT.get_client()?.execute(request)?.json()?;
+    let response: GetContextResponse = HTTP_CLIENT.get_client().execute(request)?.json()?;
     let prev_batch = response.start.unwrap_or_default();
 
     Ok(prev_batch)
@@ -172,7 +172,7 @@ pub fn dw_media(
         Ok(fname)
     } else {
         HTTP_CLIENT
-            .get_client()?
+            .get_client()
             .execute(request)?
             .bytes()
             .collect::<Result<Vec<u8>, std::io::Error>>()
diff --git a/fractal-gtk/src/backend/register.rs b/fractal-gtk/src/backend/register.rs
index ec02ff55..c99c45b2 100644
--- a/fractal-gtk/src/backend/register.rs
+++ b/fractal-gtk/src/backend/register.rs
@@ -68,7 +68,7 @@ pub fn login(
     };
 
     let request = login_req(server, &body)?;
-    let response: LoginResponse = HTTP_CLIENT.get_client()?.execute(request)?.json()?;
+    let response: LoginResponse = HTTP_CLIENT.get_client().execute(request)?.json()?;
 
     if let (Some(tk), Some(uid)) = (response.access_token, response.user_id) {
         Ok((uid, tk, response.device_id))
@@ -92,7 +92,7 @@ pub fn logout(server: Url, access_token: AccessToken) -> Result<(), LogoutError>
     let params = LogoutParameters { access_token };
 
     let request = logout_req(server, &params)?;
-    HTTP_CLIENT.get_client()?.execute(request)?;
+    HTTP_CLIENT.get_client().execute(request)?;
 
     Ok(())
 }
@@ -101,7 +101,7 @@ pub fn get_well_known(domain: Url) -> Result<DomainInfoResponse, Error> {
     let request = domain_info(domain)?;
 
     HTTP_CLIENT
-        .get_client()?
+        .get_client()
         .execute(request)?
         .json()
         .map_err(Into::into)
diff --git a/fractal-gtk/src/backend/room.rs b/fractal-gtk/src/backend/room.rs
index fe86ef9a..970f3c9f 100644
--- a/fractal-gtk/src/backend/room.rs
+++ b/fractal-gtk/src/backend/room.rs
@@ -103,7 +103,7 @@ pub fn get_room_detail(
     let params = GetStateEventsForKeyParameters { access_token };
 
     let request = get_state_events_for_key(base, &params, &room_id, &keys)?;
-    let response: JsonValue = HTTP_CLIENT.get_client()?.execute(request)?.json()?;
+    let response: JsonValue = HTTP_CLIENT.get_client().execute(request)?.json()?;
 
     let k = keys.split('.').last().ok_or(Error::BackendError)?;
     let value = response[&k].as_str().map(Into::into).unwrap_or_default();
@@ -133,7 +133,7 @@ pub fn get_room_avatar(
         .map_err(Into::into)
         .and_then(|request| {
             let response = HTTP_CLIENT
-                .get_client()?
+                .get_client()
                 .execute(request)?
                 .json::<JsonValue>()?;
 
@@ -176,7 +176,7 @@ pub fn get_room_members(
     let params = JoinedMembersParameters { access_token };
 
     let request = get_joined_members(base, &room_id, &params)?;
-    let response: JoinedMembersResponse = HTTP_CLIENT.get_client()?.execute(request)?.json()?;
+    let response: JoinedMembersResponse = HTTP_CLIENT.get_client().execute(request)?.json()?;
 
     let ms = response.joined.into_iter().map(Member::from).collect();
 
@@ -216,7 +216,7 @@ pub fn get_room_messages(
     };
 
     let request = get_messages_events(base, &params, &room_id)?;
-    let response: GetMessagesEventsResponse = HTTP_CLIENT.get_client()?.execute(request)?.json()?;
+    let response: GetMessagesEventsResponse = HTTP_CLIENT.get_client().execute(request)?.json()?;
 
     let prev_batch = response.end;
     let evs = response.chunk.iter().rev();
@@ -290,7 +290,7 @@ pub fn send_msg(
         .map_err::<Error, _>(Into::into)
         .and_then(|request| {
             let response = HTTP_CLIENT
-                .get_client()?
+                .get_client()
                 .execute(request)?
                 .json::<CreateMessageEventResponse>()?;
 
@@ -320,7 +320,7 @@ pub fn send_typing(
     let body = TypingNotificationBody::Typing(Duration::from_secs(4));
 
     let request = send_typing_notification(base, &room_id, &user_id, &params, &body)?;
-    HTTP_CLIENT.get_client()?.execute(request)?;
+    HTTP_CLIENT.get_client().execute(request)?;
 
     Ok(())
 }
@@ -354,7 +354,7 @@ pub fn redact_msg(
         .map_err::<Error, _>(Into::into)
         .and_then(|request| {
             let response = HTTP_CLIENT
-                .get_client()?
+                .get_client()
                 .execute(request)?
                 .json::<RedactEventResponse>()?;
 
@@ -399,7 +399,7 @@ pub fn join_room(
     };
 
     let request = join_room_req(base, &room_id_or_alias_id, &params)?;
-    HTTP_CLIENT.get_client()?.execute(request)?;
+    HTTP_CLIENT.get_client().execute(request)?;
 
     Ok(room_id)
 }
@@ -423,7 +423,7 @@ pub fn leave_room(
     let params = LeaveRoomParameters { access_token };
 
     let request = leave_room_req(base, &room_id, &params)?;
-    HTTP_CLIENT.get_client()?.execute(request)?;
+    HTTP_CLIENT.get_client().execute(request)?;
 
     Ok(())
 }
@@ -453,7 +453,7 @@ pub fn mark_as_read(
     };
 
     let request = set_read_marker(base, &params, &body, &room_id)?;
-    HTTP_CLIENT.get_client()?.execute(request)?;
+    HTTP_CLIENT.get_client().execute(request)?;
 
     Ok((room_id, event_id))
 }
@@ -481,7 +481,7 @@ pub fn set_room_name(
     });
 
     let request = create_state_events_for_key(base, &params, &body, &room_id, "m.room.name")?;
-    HTTP_CLIENT.get_client()?.execute(request)?;
+    HTTP_CLIENT.get_client().execute(request)?;
 
     Ok(())
 }
@@ -510,7 +510,7 @@ pub fn set_room_topic(
     });
 
     let request = create_state_events_for_key(base, &params, &body, &room_id, "m.room.topic")?;
-    HTTP_CLIENT.get_client()?.execute(request)?;
+    HTTP_CLIENT.get_client().execute(request)?;
 
     Ok(())
 }
@@ -546,7 +546,7 @@ pub fn set_room_avatar(
 
     let body = json!({ "url": upload_file_response.content_uri.as_str() });
     let request = create_state_events_for_key(base, &params, &body, &room_id, "m.room.avatar")?;
-    HTTP_CLIENT.get_client()?.execute(request)?;
+    HTTP_CLIENT.get_client().execute(request)?;
 
     Ok(())
 }
@@ -585,7 +585,7 @@ pub fn upload_file(
     let request = create_content(base, &params_upload, contents)?;
 
     HTTP_CLIENT
-        .get_client()?
+        .get_client()
         .execute(request)?
         .json()
         .map_err(Into::into)
@@ -642,7 +642,7 @@ pub fn new_room(
     };
 
     let request = create_room(base, &params, &body)?;
-    let response: CreateRoomResponse = HTTP_CLIENT.get_client()?.execute(request)?.json()?;
+    let response: CreateRoomResponse = HTTP_CLIENT.get_client().execute(request)?.json()?;
 
     Ok(Room {
         name: Some(name),
@@ -662,7 +662,7 @@ fn update_direct_chats(
     };
 
     let request = get_global_account_data(base.clone(), &params, &user_id, "m.direct")?;
-    let response: JsonValue = HTTP_CLIENT.get_client()?.execute(request)?.json()?;
+    let response: JsonValue = HTTP_CLIENT.get_client().execute(request)?.json()?;
 
     let mut directs = response
         .as_object()
@@ -688,7 +688,7 @@ fn update_direct_chats(
     let params = SetGlobalAccountDataParameters { access_token };
 
     let request = set_global_account_data(base, &params, &json!(directs), &user_id, "m.direct")?;
-    HTTP_CLIENT.get_client()?.execute(request)?;
+    HTTP_CLIENT.get_client().execute(request)?;
 
     Ok(())
 }
@@ -718,7 +718,7 @@ pub fn direct_chat(
     };
 
     let request = create_room(base.clone(), &params, &body)?;
-    let response: CreateRoomResponse = HTTP_CLIENT.get_client()?.execute(request)?.json()?;
+    let response: CreateRoomResponse = HTTP_CLIENT.get_client().execute(request)?.json()?;
 
     let directs = update_direct_chats(
         base,
@@ -767,7 +767,7 @@ pub fn add_to_fav(
         delete_tag(base, &user_id, &room_id, "m.favourite", &params)
     }?;
 
-    HTTP_CLIENT.get_client()?.execute(request)?;
+    HTTP_CLIENT.get_client().execute(request)?;
 
     Ok((room_id, tofav))
 }
@@ -793,7 +793,7 @@ pub fn invite(
     let body = InviteUserBody { user_id };
 
     let request = invite_user(base, &room_id, &params, &body)?;
-    HTTP_CLIENT.get_client()?.execute(request)?;
+    HTTP_CLIENT.get_client().execute(request)?;
 
     Ok(())
 }
@@ -838,7 +838,7 @@ pub fn set_language(
     )
     .map_err(Into::into)
     .and_then(|request| {
-        let _ = HTTP_CLIENT.get_client()?.execute(request)?;
+        let _ = HTTP_CLIENT.get_client().execute(request)?;
 
         Ok(())
     });
diff --git a/fractal-gtk/src/backend/sync.rs b/fractal-gtk/src/backend/sync.rs
index c6abd4de..5b7db540 100644
--- a/fractal-gtk/src/backend/sync.rs
+++ b/fractal-gtk/src/backend/sync.rs
@@ -181,7 +181,7 @@ pub fn sync(
 
     let query = ProxySettings::current().and_then(|proxy_settings| {
         let client = proxy_settings
-            .apply_to_client_builder(client_builder_timeout)?
+            .apply_to_client_builder(client_builder_timeout)
             .build()?;
         let request = sync_events(base.clone(), &params)?;
         let response = client.execute(request)?;
diff --git a/fractal-gtk/src/backend/user.rs b/fractal-gtk/src/backend/user.rs
index f10c7bbf..004be50e 100644
--- a/fractal-gtk/src/backend/user.rs
+++ b/fractal-gtk/src/backend/user.rs
@@ -97,7 +97,7 @@ pub fn get_username(
 ) -> Result<Option<String>, NameError> {
     let params = GetDisplayNameParameters { access_token };
     let request = get_display_name(base, &params, &uid)?;
-    let response: GetDisplayNameResponse = HTTP_CLIENT.get_client()?.execute(request)?.json()?;
+    let response: GetDisplayNameResponse = HTTP_CLIENT.get_client().execute(request)?.json()?;
 
     Ok(response.displayname)
 }
@@ -111,7 +111,7 @@ pub fn get_username_async(base: Url, access_token: AccessToken, uid: UserId) ->
         .map_err::<Error, _>(Into::into)
         .and_then(|request| {
             HTTP_CLIENT
-                .get_client()?
+                .get_client()
                 .execute(request)?
                 .json::<GetDisplayNameResponse>()
                 .map_err(Into::into)
@@ -144,7 +144,7 @@ pub fn set_username(
     };
 
     let request = set_display_name(base, &params, &body, &uid)?;
-    HTTP_CLIENT.get_client()?.execute(request)?;
+    HTTP_CLIENT.get_client().execute(request)?;
 
     Ok(username)
 }
@@ -176,7 +176,7 @@ pub fn get_threepid(
     let params = ThirdPartyIDParameters { access_token };
 
     let request = get_identifiers(base, &params)?;
-    let response: ThirdPartyIDResponse = HTTP_CLIENT.get_client()?.execute(request)?.json()?;
+    let response: ThirdPartyIDResponse = HTTP_CLIENT.get_client().execute(request)?.json()?;
 
     Ok(response.threepids)
 }
@@ -239,7 +239,7 @@ pub fn get_email_token(
     let request = request_contact_verification_token_email(base, &params, &body)?;
 
     match HTTP_CLIENT
-        .get_client()?
+        .get_client()
         .execute(request)?
         .json::<EmailTokenResponse>()?
     {
@@ -310,7 +310,7 @@ pub fn get_phone_token(
     let request = request_contact_verification_token_msisdn(base, &params, &body)?;
 
     match HTTP_CLIENT
-        .get_client()?
+        .get_client()
         .execute(request)?
         .json::<PhoneTokenResponse>()?
     {
@@ -349,7 +349,7 @@ pub fn add_threepid(
     };
 
     let request = create_contact(base, &params, &body)?;
-    HTTP_CLIENT.get_client()?.execute(request)?;
+    HTTP_CLIENT.get_client().execute(request)?;
 
     Ok(())
 }
@@ -378,7 +378,7 @@ pub fn submit_phone_token(
     };
 
     let request = submit_phone_token_req(base, &body)?;
-    let response: SubmitPhoneTokenResponse = HTTP_CLIENT.get_client()?.execute(request)?.json()?;
+    let response: SubmitPhoneTokenResponse = HTTP_CLIENT.get_client().execute(request)?.json()?;
 
     Ok((Some(sid).filter(|_| response.success), client_secret))
 }
@@ -404,7 +404,7 @@ pub fn delete_three_pid(
     let body = DeleteThreePIDBody { address, medium };
 
     let request = delete_contact(base, &params, &body)?;
-    HTTP_CLIENT.get_client()?.execute(request)?;
+    HTTP_CLIENT.get_client().execute(request)?;
 
     Ok(())
 }
@@ -448,7 +448,7 @@ pub fn change_password(
     };
 
     let request = change_password_req(base, &params, &body)?;
-    HTTP_CLIENT.get_client()?.execute(request)?;
+    HTTP_CLIENT.get_client().execute(request)?;
 
     Ok(())
 }
@@ -490,7 +490,7 @@ pub fn account_destruction(
     };
 
     let request = deactivate(base, &params, &body)?;
-    HTTP_CLIENT.get_client()?.execute(request)?;
+    HTTP_CLIENT.get_client().execute(request)?;
 
     Ok(())
 }
@@ -543,7 +543,7 @@ pub fn set_user_avatar(
     let contents = fs::read(&avatar)?;
     let request = create_content(base.clone(), &params_upload, contents)?;
     let upload_response: CreateContentResponse =
-        HTTP_CLIENT.get_client()?.execute(request)?.json()?;
+        HTTP_CLIENT.get_client().execute(request)?.json()?;
 
     let params_avatar = SetAvatarUrlParameters { access_token };
     let body = SetAvatarUrlBody {
@@ -551,7 +551,7 @@ pub fn set_user_avatar(
     };
 
     let request = set_avatar_url(base, &params_avatar, &body, &uid)?;
-    HTTP_CLIENT.get_client()?.execute(request)?;
+    HTTP_CLIENT.get_client().execute(request)?;
 
     Ok(avatar)
 }
@@ -605,7 +605,7 @@ pub fn search(
     };
 
     let request = user_directory(base, &params, &body)?;
-    let response: UserDirectoryResponse = HTTP_CLIENT.get_client()?.execute(request)?.json()?;
+    let response: UserDirectoryResponse = HTTP_CLIENT.get_client().execute(request)?.json()?;
 
     Ok(response.results.into_iter().map(Into::into).collect())
 }
@@ -632,7 +632,7 @@ pub fn get_user_avatar(
         .map_err::<Error, _>(Into::into)
         .and_then(|request| {
             HTTP_CLIENT
-                .get_client()?
+                .get_client()
                 .execute(request)?
                 .json::<GetProfileResponse>()
                 .map_err(Into::into)
diff --git a/fractal-gtk/src/client.rs b/fractal-gtk/src/client.rs
index 605032dd..0d85be8e 100644
--- a/fractal-gtk/src/client.rs
+++ b/fractal-gtk/src/client.rs
@@ -1,6 +1,7 @@
 use crate::error::Error;
 use crate::globals;
 
+use fractal_api::reqwest;
 use gio::prelude::*;
 
 use std::sync::Mutex;
@@ -9,58 +10,62 @@ use std::time::Duration;
 // Special URI used by gio to indicate no proxy
 const PROXY_DIRECT_URI: &str = "direct://";
 
-#[derive(Debug, Eq, PartialEq)]
+#[derive(Debug, Default, Eq, PartialEq)]
 pub struct ProxySettings {
     http_proxy: Vec<String>,
     https_proxy: Vec<String>,
 }
 
 impl ProxySettings {
-    fn new(http_proxy: Vec<String>, https_proxy: Vec<String>) -> ProxySettings {
-        ProxySettings {
-            http_proxy,
-            https_proxy,
+    fn new<I, T>(http_proxy: T, https_proxy: T) -> Self
+    where
+        I: PartialEq<str> + Into<String>,
+        T: IntoIterator<Item = I>,
+    {
+        Self {
+            http_proxy: http_proxy
+                .into_iter()
+                .filter(|proxy| proxy != PROXY_DIRECT_URI)
+                .map(Into::into)
+                .collect(),
+            https_proxy: https_proxy
+                .into_iter()
+                .filter(|proxy| proxy != PROXY_DIRECT_URI)
+                .map(Into::into)
+                .collect(),
         }
     }
 
-    fn direct() -> ProxySettings {
-        Self::new(
-            vec![PROXY_DIRECT_URI.to_string()],
-            vec![PROXY_DIRECT_URI.to_string()],
-        )
-    }
-
-    pub fn current() -> Result<ProxySettings, Error> {
+    pub fn current() -> Result<Self, Error> {
         Ok(Self::new(
-            PROXY_RESOLVER
-                .with(|resolver| resolver.lookup("http://";, gio::NONE_CANCELLABLE))?
-                .iter()
-                .map(ToString::to_string)
-                .collect(),
-            PROXY_RESOLVER
-                .with(|resolver| resolver.lookup("https://";, gio::NONE_CANCELLABLE))?
-                .iter()
-                .map(ToString::to_string)
-                .collect(),
+            PROXY_RESOLVER.with(|resolver| resolver.lookup("http://";, gio::NONE_CANCELLABLE))?,
+            PROXY_RESOLVER.with(|resolver| resolver.lookup("https://";, gio::NONE_CANCELLABLE))?,
         ))
     }
 
     pub fn apply_to_client_builder(
         &self,
         mut builder: fractal_api::reqwest::blocking::ClientBuilder,
-    ) -> Result<fractal_api::reqwest::blocking::ClientBuilder, fractal_api::reqwest::Error> {
+    ) -> fractal_api::reqwest::blocking::ClientBuilder {
         // Reqwest only supports one proxy for each type
-
-        if !self.http_proxy.is_empty() && self.http_proxy[0] != PROXY_DIRECT_URI {
-            let proxy = fractal_api::reqwest::Proxy::http(&self.http_proxy[0])?;
-            builder = builder.proxy(proxy);
+        if let Some(http_proxy) = self
+            .http_proxy
+            .get(0)
+            .map(reqwest::Proxy::http)
+            .and_then(Result::ok)
+        {
+            builder = builder.proxy(http_proxy);
         }
-        if !self.https_proxy.is_empty() && self.https_proxy[0] != PROXY_DIRECT_URI {
-            let proxy = fractal_api::reqwest::Proxy::https(&self.https_proxy[0])?;
-            builder = builder.proxy(proxy);
+        if let Some(https_proxy) = self
+            .https_proxy
+            .get(0)
+            .map(reqwest::Proxy::http)
+            .and_then(Result::ok)
+        {
+            builder = builder.proxy(https_proxy);
         }
 
-        Ok(builder)
+        builder
     }
 }
 
@@ -86,29 +91,27 @@ impl Client {
         Client {
             inner: Mutex::new(ClientInner {
                 client: Self::build(fractal_api::reqwest::blocking::Client::builder()),
-                proxy_settings: ProxySettings::direct(),
+                proxy_settings: Default::default(),
             }),
         }
     }
 
-    pub fn get_client(&self) -> Result<fractal_api::reqwest::blocking::Client, Error> {
+    pub fn get_client(&self) -> fractal_api::reqwest::blocking::Client {
         // Lock first so we don't overwrite proxy settings with outdated information
         let mut inner = self.inner.lock().unwrap();
 
-        let new_proxy_settings = ProxySettings::current()?;
+        let new_proxy_settings = ProxySettings::current().unwrap_or_default();
 
-        if inner.proxy_settings == new_proxy_settings {
-            Ok(inner.client.clone())
-        } else {
+        if inner.proxy_settings != new_proxy_settings {
             let mut builder = fractal_api::reqwest::blocking::Client::builder();
-            builder = new_proxy_settings.apply_to_client_builder(builder)?;
+            builder = new_proxy_settings.apply_to_client_builder(builder);
             let client = Self::build(builder);
 
             inner.client = client;
             inner.proxy_settings = new_proxy_settings;
-
-            Ok(inner.client.clone())
         }
+
+        inner.client.clone()
     }
 
     fn build(


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]