diff --git a/matrix_sdk/src/client.rs b/matrix_sdk/src/client.rs index b040ae4c..aa131d71 100644 --- a/matrix_sdk/src/client.rs +++ b/matrix_sdk/src/client.rs @@ -31,6 +31,7 @@ use matrix_sdk_common::{ locks::RwLock, presence::PresenceState, uuid::Uuid, + FromHttpRequestError, FromHttpResponseError, Outgoing, }; use futures_timer::Delay as sleep; @@ -290,7 +291,6 @@ use api::r0::{ session::login, sync::sync_events, typing::create_typing_event, - uiaa::UiaaResponse, }; impl Client { @@ -540,7 +540,7 @@ impl Client { info!("Registering to {}", self.homeserver); let request = registration.into(); - self.send_uiaa(request).await + self.send(request).await } /// Join a room by `RoomId`. @@ -1093,57 +1093,25 @@ impl Client { /// // returned /// # }) /// ``` - pub async fn send + Debug>( + pub async fn send( &self, request: Request, - ) -> Result { + ) -> Result<::Incoming> + where + Request: Endpoint + Debug, + ::Incoming: + TryFrom>, Error = FromHttpRequestError>, + ::Incoming: TryFrom< + http::Response>, + Error = FromHttpResponseError<::ResponseError>, + >, + crate::Error: From::ResponseError>>, + { self.http_client .send(request, self.base_client.session().clone()) .await } - /// Send an arbitrary request to the server, without updating client state. - /// - /// This version allows the client to make registration requests. - /// - /// **Warning:** Because this method *does not* update the client state, it is - /// important to make sure than you account for this yourself, and use wrapper methods - /// where available. This method should *only* be used if a wrapper method for the - /// endpoint you'd like to use is not available. - /// - /// # Arguments - /// - /// * `request` - This version of send is for dealing with types that return - /// a `UiaaResponse` as the `Endpoint` associated type. - /// - /// # Examples - /// ``` - /// # use std::convert::TryFrom; - /// # use matrix_sdk::{Client, RegistrationBuilder}; - /// # use matrix_sdk::api::r0::account::register::{RegistrationKind, Request}; - /// # use matrix_sdk::identifiers::DeviceId; - /// # use url::Url; - /// # let homeserver = Url::parse("http://example.com").unwrap(); - /// # let mut rt = tokio::runtime::Runtime::new().unwrap(); - /// # rt.block_on(async { - /// let mut builder = RegistrationBuilder::default(); - /// builder.password("pass") - /// .username("user") - /// .kind(RegistrationKind::User); - /// let mut client = Client::new(homeserver).unwrap(); - /// let req: Request = builder.into(); - /// client.send_uiaa(req).await; - /// # }) - /// ``` - pub async fn send_uiaa + Debug>( - &self, - request: Request, - ) -> Result { - self.http_client - .send_uiaa(request, self.base_client.session().clone()) - .await - } - /// Synchronize the client's state with the latest state on the server. /// /// If a `StateStore` is provided and this is the initial sync state will diff --git a/matrix_sdk/src/http_client.rs b/matrix_sdk/src/http_client.rs index 36875114..ee187522 100644 --- a/matrix_sdk/src/http_client.rs +++ b/matrix_sdk/src/http_client.rs @@ -15,13 +15,13 @@ use std::{convert::TryFrom, sync::Arc}; use http::{Method as HttpMethod, Response as HttpResponse}; -use reqwest::{header::AUTHORIZATION, Client, Response}; +use reqwest::{Client, Response}; use tracing::trace; use url::Url; -use matrix_sdk_common::locks::RwLock; +use matrix_sdk_common::{locks::RwLock, FromHttpRequestError, FromHttpResponseError, Outgoing}; -use crate::{api::r0::uiaa::UiaaResponse, Endpoint, Error, Result, Session}; +use crate::{Endpoint, Error, Result, Session}; #[derive(Clone, Debug)] pub(crate) struct HttpClient { @@ -30,19 +30,40 @@ pub(crate) struct HttpClient { } impl HttpClient { - async fn send_request( + async fn send_request( &self, requires_auth: bool, method: HttpMethod, - request: http::Request>, + request: Request, session: Arc>>, - ) -> Result { - let url = request.uri(); - let path_and_query = url.path_and_query().unwrap(); - let mut url = (&*self.homeserver).clone(); + ) -> Result + where + Request: Endpoint, + ::Incoming: + TryFrom>, Error = FromHttpRequestError>, + ::Incoming: TryFrom< + http::Response>, + Error = FromHttpResponseError<::ResponseError>, + >, + { + let request = { + let read_guard; + let access_token = if requires_auth { + read_guard = session.read().await; - url.set_path(path_and_query.path()); - url.set_query(path_and_query.query()); + if let Some(session) = read_guard.as_ref() { + Some(session.access_token.as_str()) + } else { + return Err(Error::AuthenticationRequired); + } + } else { + None + }; + + request.try_into_http_request(&self.homeserver.to_string(), access_token)? + }; + + let url = &request.uri().to_string(); let request_builder = match method { HttpMethod::GET => self.inner.get(url), @@ -70,17 +91,6 @@ impl HttpClient { method => panic!("Unsupported method {}", method), }; - let request_builder = if requires_auth { - if let Some(session) = session.read().await.as_ref() { - let header_value = format!("Bearer {}", &session.access_token); - request_builder.header(AUTHORIZATION, header_value) - } else { - return Err(Error::AuthenticationRequired); - } - } else { - request_builder - }; - Ok(request_builder.send().await?) } @@ -101,12 +111,21 @@ impl HttpClient { Ok(http_builder.body(body).unwrap()) } - pub async fn send + std::fmt::Debug>( + pub async fn send( &self, request: Request, session: Arc>>, - ) -> Result { - let request: http::Request> = request.try_into()?; + ) -> Result<::Incoming> + where + Request: Endpoint, + ::Incoming: + TryFrom>, Error = FromHttpRequestError>, + ::Incoming: TryFrom< + http::Response>, + Error = FromHttpResponseError<::ResponseError>, + >, + Error: From::ResponseError>>, + { let response = self .send_request( Request::METADATA.requires_authentication, @@ -120,30 +139,8 @@ impl HttpClient { let response = self.response_to_http_response(response).await?; - Ok(::try_from(response)?) - } - - pub async fn send_uiaa + std::fmt::Debug>( - &self, - request: Request, - session: Arc>>, - ) -> Result { - let request: http::Request> = request.try_into()?; - let response = self - .send_request( - Request::METADATA.requires_authentication, - Request::METADATA.method, - request, - session, - ) - .await?; - - trace!("Got response: {:?}", response); - - let response = self.response_to_http_response(response).await?; - - let uiaa: Result<_> = ::try_from(response).map_err(Into::into); - - Ok(uiaa?) + Ok(::Incoming::try_from( + response, + )?) } } diff --git a/matrix_sdk_common/Cargo.toml b/matrix_sdk_common/Cargo.toml index 067b20e9..e4cc1714 100644 --- a/matrix_sdk_common/Cargo.toml +++ b/matrix_sdk_common/Cargo.toml @@ -15,9 +15,10 @@ instant = { version = "0.1.6", features = ["wasm-bindgen", "now"] } js_int = "0.1.8" [dependencies.ruma] -git = "https://github.com/matrix-org/ruma" +version = "0.0.1" +git = "https://github.com/ruma/ruma" +rev = "a589e92144e1af635ec3fd224265193e45dcdc95" features = ["client-api"] -branch = "verification-event-improvements2" [target.'cfg(not(target_arch = "wasm32"))'.dependencies] uuid = { version = "0.8.1", features = ["v4"] } diff --git a/matrix_sdk_common/src/lib.rs b/matrix_sdk_common/src/lib.rs index bb478f9b..2e4898c7 100644 --- a/matrix_sdk_common/src/lib.rs +++ b/matrix_sdk_common/src/lib.rs @@ -4,7 +4,7 @@ pub use ruma::{ api::{ client as api, error::{FromHttpRequestError, FromHttpResponseError, IntoHttpError, ServerError}, - Endpoint, EndpointError, + Endpoint, EndpointError, Outgoing, }, events, identifiers, presence, push, Raw, };