chore(sdk): Move the various config structs into its own module

master
Damir Jelić 2021-09-14 15:02:09 +02:00
parent cf26557cc2
commit 7de782d3a2
19 changed files with 467 additions and 362 deletions

View File

@ -10,7 +10,7 @@ Connecting and logging in to a homeserver is pretty starightforward:
```rust,no_run
use std::convert::TryFrom;
use matrix_sdk::{
Client, SyncSettings, Result,
Client, config::SyncSettings, Result,
ruma::{UserId, events::{SyncMessageEvent, room::message::MessageEventContent}},
};

View File

@ -1,9 +1,10 @@
use std::{env, process::exit};
use matrix_sdk::{
config::{ClientConfig, SyncSettings},
room::Room,
ruma::events::{room::member::MemberEventContent, StrippedStateEvent},
Client, ClientConfig, SyncSettings,
Client,
};
use tokio::time::{sleep, Duration};
use url::Url;

View File

@ -1,12 +1,13 @@
use std::{env, process::exit};
use matrix_sdk::{
config::{ClientConfig, SyncSettings},
room::Room,
ruma::events::{
room::message::{MessageEventContent, MessageType, TextMessageEventContent},
AnyMessageEventContent, SyncMessageEvent,
},
Client, ClientConfig, SyncSettings,
Client,
};
use url::Url;

View File

@ -4,7 +4,7 @@ use std::{
sync::atomic::{AtomicBool, Ordering},
};
use matrix_sdk::{ruma::UserId, Client, LoopCtrl, SyncSettings};
use matrix_sdk::{config::SyncSettings, ruma::UserId, Client, LoopCtrl};
use url::Url;
async fn bootstrap(client: Client, user_id: UserId, password: String) {

View File

@ -9,6 +9,7 @@ use std::{
use matrix_sdk::{
self,
config::SyncSettings,
encryption::verification::{SasVerification, Verification},
ruma::{
events::{
@ -16,7 +17,7 @@ use matrix_sdk::{
},
UserId,
},
Client, LoopCtrl, SyncSettings,
Client, LoopCtrl,
};
use url::Url;

View File

@ -9,12 +9,13 @@ use std::{
use matrix_sdk::{
self,
config::SyncSettings,
room::Room,
ruma::events::{
room::message::{MessageEventContent, MessageType, TextMessageEventContent},
SyncMessageEvent,
},
Client, SyncSettings,
Client,
};
use tokio::sync::Mutex;
use url::Url;

View File

@ -2,12 +2,13 @@ use std::{env, process::exit};
use matrix_sdk::{
self,
config::SyncSettings,
room::Room,
ruma::events::{
room::message::{MessageEventContent, MessageType, TextMessageEventContent},
SyncMessageEvent,
},
Client, SyncSettings,
Client,
};
use url::Url;

View File

@ -1,4 +1,5 @@
use matrix_sdk::{
config::SyncSettings,
deserialized_responses::SyncResponse,
ruma::{
events::{
@ -7,7 +8,7 @@ use matrix_sdk::{
},
RoomId,
},
Client, LoopCtrl, SyncSettings,
Client, LoopCtrl,
};
use url::Url;
use wasm_bindgen::prelude::*;

View File

@ -18,7 +18,6 @@ use std::{
fmt::{self, Debug},
future::Future,
io::Read,
path::Path,
pin::Pin,
result::Result as StdResult,
sync::Arc,
@ -27,11 +26,10 @@ use std::{
use dashmap::DashMap;
use futures::FutureExt;
use futures_timer::Delay as sleep;
use http::HeaderValue;
use matrix_sdk_base::{
deserialized_responses::{JoinedRoom, LeftRoom, SyncResponse},
media::{MediaEventContent, MediaFormat, MediaRequest, MediaThumbnailSize, MediaType},
BaseClient, BaseClientConfig, Session, Store,
BaseClient, Session, Store,
};
use matrix_sdk_common::{
instant::{Duration, Instant},
@ -39,7 +37,6 @@ use matrix_sdk_common::{
uuid::Uuid,
};
use mime::{self, Mime};
use reqwest::header::InvalidHeaderValue;
use ruma::{
api::{
client::{
@ -73,14 +70,13 @@ use tracing::{error, info, instrument, warn};
use url::Url;
use crate::{
config::{ClientConfig, RequestConfig},
error::{HttpError, HttpResult},
event_handler::{EventHandler, EventHandlerData, EventHandlerResult, EventKind, SyncEvent},
http_client::{client_with_config, HttpClient, HttpSend},
http_client::{client_with_config, HttpClient},
room, Error, Result,
};
const DEFAULT_REQUEST_TIMEOUT: Duration = Duration::from_secs(10);
const DEFAULT_SYNC_TIMEOUT: Duration = Duration::from_secs(30);
/// A conservative upload speed of 1Mbps
const DEFAULT_UPLOAD_SPEED: u64 = 125_000;
/// 5 min minimal upload request timeout, used to clamp the request timeout.
@ -151,333 +147,6 @@ impl Debug for Client {
}
}
/// Configuration for the creation of the `Client`.
///
/// When setting the `StateStore` it is up to the user to open/connect
/// the storage backend before client creation.
///
/// # Example
///
/// ```
/// # use matrix_sdk::ClientConfig;
/// // To pass all the request through mitmproxy set the proxy and disable SSL
/// // verification
/// let client_config = ClientConfig::new()
/// .proxy("http://localhost:8080")
/// .unwrap()
/// .disable_ssl_verification();
/// ```
#[derive(Default)]
pub struct ClientConfig {
#[cfg(not(target_arch = "wasm32"))]
pub(crate) proxy: Option<reqwest::Proxy>,
pub(crate) user_agent: Option<HeaderValue>,
pub(crate) disable_ssl_verification: bool,
pub(crate) base_config: BaseClientConfig,
pub(crate) request_config: RequestConfig,
pub(crate) client: Option<Arc<dyn HttpSend>>,
pub(crate) appservice_mode: bool,
}
#[cfg(not(tarpaulin_include))]
impl Debug for ClientConfig {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut res = fmt.debug_struct("ClientConfig");
#[cfg(not(target_arch = "wasm32"))]
let res = res.field("proxy", &self.proxy);
res.field("user_agent", &self.user_agent)
.field("disable_ssl_verification", &self.disable_ssl_verification)
.field("request_config", &self.request_config)
.finish()
}
}
impl ClientConfig {
/// Create a new default `ClientConfig`.
pub fn new() -> Self {
Default::default()
}
/// Set the proxy through which all the HTTP requests should go.
///
/// Note, only HTTP proxies are supported.
///
/// # Arguments
///
/// * `proxy` - The HTTP URL of the proxy.
///
/// # Example
///
/// ```
/// use matrix_sdk::ClientConfig;
///
/// let client_config = ClientConfig::new()
/// .proxy("http://localhost:8080")
/// .unwrap();
/// ```
#[cfg(not(target_arch = "wasm32"))]
pub fn proxy(mut self, proxy: &str) -> Result<Self> {
self.proxy = Some(reqwest::Proxy::all(proxy)?);
Ok(self)
}
/// Disable SSL verification for the HTTP requests.
pub fn disable_ssl_verification(mut self) -> Self {
self.disable_ssl_verification = true;
self
}
/// Set a custom HTTP user agent for the client.
pub fn user_agent(mut self, user_agent: &str) -> StdResult<Self, InvalidHeaderValue> {
self.user_agent = Some(HeaderValue::from_str(user_agent)?);
Ok(self)
}
///// Set a custom implementation of a `StateStore`.
/////
///// The state store should be opened before being set.
//pub fn state_store(mut self, store: Box<dyn StateStore>) -> Self {
// self.base_config = self.base_config.state_store(store);
// self
//}
/// Set the path for storage.
///
/// # Arguments
///
/// * `path` - The path where the stores should save data in. It is the
/// callers responsibility to make sure that the path exists.
///
/// In the default configuration the client will open default
/// implementations for the crypto store and the state store. It will use
/// the given path to open the stores. If no path is provided no store will
/// be opened
pub fn store_path(mut self, path: impl AsRef<Path>) -> Self {
self.base_config = self.base_config.store_path(path);
self
}
/// Set the passphrase to encrypt the crypto store.
///
/// # Argument
///
/// * `passphrase` - The passphrase that will be used to encrypt the data in
/// the cryptostore.
///
/// This is only used if no custom cryptostore is set.
pub fn passphrase(mut self, passphrase: String) -> Self {
self.base_config = self.base_config.passphrase(passphrase);
self
}
/// Set the default timeout, fail and retry behavior for all HTTP requests.
pub fn request_config(mut self, request_config: RequestConfig) -> Self {
self.request_config = request_config;
self
}
/// Get the [`RequestConfig`]
pub fn get_request_config(&self) -> &RequestConfig {
&self.request_config
}
/// Specify a client to handle sending requests and receiving responses.
///
/// Any type that implements the `HttpSend` trait can be used to
/// send/receive `http` types.
pub fn client(mut self, client: Arc<dyn HttpSend>) -> Self {
self.client = Some(client);
self
}
/// Puts the client into application service mode
///
/// This is low-level functionality. For an high-level API check the
/// `matrix_sdk_appservice` crate.
#[cfg(feature = "appservice")]
pub fn appservice_mode(mut self) -> Self {
self.appservice_mode = true;
self
}
}
#[derive(Debug, Clone)]
/// Settings for a sync call.
pub struct SyncSettings<'a> {
pub(crate) filter: Option<sync_events::Filter<'a>>,
pub(crate) timeout: Option<Duration>,
pub(crate) token: Option<String>,
pub(crate) full_state: bool,
}
impl<'a> Default for SyncSettings<'a> {
fn default() -> Self {
Self {
filter: Default::default(),
timeout: Some(DEFAULT_SYNC_TIMEOUT),
token: Default::default(),
full_state: Default::default(),
}
}
}
impl<'a> SyncSettings<'a> {
/// Create new default sync settings.
pub fn new() -> Self {
Default::default()
}
/// Set the sync token.
///
/// # Arguments
///
/// * `token` - The sync token that should be used for the sync call.
pub fn token(mut self, token: impl Into<String>) -> Self {
self.token = Some(token.into());
self
}
/// Set the maximum time the server can wait, in milliseconds, before
/// responding to the sync request.
///
/// # Arguments
///
/// * `timeout` - The time the server is allowed to wait.
pub fn timeout(mut self, timeout: Duration) -> Self {
self.timeout = Some(timeout);
self
}
/// Set the sync filter.
/// It can be either the filter ID, or the definition for the filter.
///
/// # Arguments
///
/// * `filter` - The filter configuration that should be used for the sync
/// call.
pub fn filter(mut self, filter: sync_events::Filter<'a>) -> Self {
self.filter = Some(filter);
self
}
/// Should the server return the full state from the start of the timeline.
///
/// This does nothing if no sync token is set.
///
/// # Arguments
/// * `full_state` - A boolean deciding if the server should return the full
/// state or not.
pub fn full_state(mut self, full_state: bool) -> Self {
self.full_state = full_state;
self
}
}
/// Configuration for requests the `Client` makes.
///
/// This sets how often and for how long a request should be repeated. As well
/// as how long a successful request is allowed to take.
///
/// By default requests are retried indefinitely and use no timeout.
///
/// # Example
///
/// ```
/// # use matrix_sdk::RequestConfig;
/// # use std::time::Duration;
/// // This sets makes requests fail after a single send request and sets the timeout to 30s
/// let request_config = RequestConfig::new()
/// .disable_retry()
/// .timeout(Duration::from_secs(30));
/// ```
#[derive(Copy, Clone)]
pub struct RequestConfig {
pub(crate) timeout: Duration,
pub(crate) retry_limit: Option<u64>,
pub(crate) retry_timeout: Option<Duration>,
pub(crate) force_auth: bool,
pub(crate) assert_identity: bool,
}
#[cfg(not(tarpaulin_include))]
impl Debug for RequestConfig {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut res = fmt.debug_struct("RequestConfig");
res.field("timeout", &self.timeout)
.field("retry_limit", &self.retry_limit)
.field("retry_timeout", &self.retry_timeout)
.finish()
}
}
impl Default for RequestConfig {
fn default() -> Self {
Self {
timeout: DEFAULT_REQUEST_TIMEOUT,
retry_limit: Default::default(),
retry_timeout: Default::default(),
force_auth: false,
assert_identity: false,
}
}
}
impl RequestConfig {
/// Create a new default `RequestConfig`.
pub fn new() -> Self {
Default::default()
}
/// This is a convince method to disable the retries of a request. Setting
/// the `retry_limit` to `0` has the same effect.
pub fn disable_retry(mut self) -> Self {
self.retry_limit = Some(0);
self
}
/// The number of times a request should be retried. The default is no limit
pub fn retry_limit(mut self, retry_limit: u64) -> Self {
self.retry_limit = Some(retry_limit);
self
}
/// Set the timeout duration for all HTTP requests.
pub fn timeout(mut self, timeout: Duration) -> Self {
self.timeout = timeout;
self
}
/// Set a timeout for how long a request should be retried. The default is
/// no timeout, meaning requests are retried forever.
pub fn retry_timeout(mut self, retry_timeout: Duration) -> Self {
self.retry_timeout = Some(retry_timeout);
self
}
/// Force sending authorization even if the endpoint does not require it.
/// Default is only sending authorization if it is required.
pub(crate) fn force_auth(mut self) -> Self {
self.force_auth = true;
self
}
/// All outgoing http requests will have a GET query key-value appended with
/// `user_id` being the key and the `user_id` from the `Session` being
/// the value. Will error if there's no `Session`. This is called
/// [identity assertion] in the Matrix Application Service Spec
///
/// [identity assertion]: https://spec.matrix.org/unstable/application-service-api/#identity-assertion
#[cfg(feature = "appservice")]
#[cfg_attr(feature = "docs", doc(cfg(appservice)))]
pub fn assert_identity(mut self) -> Self {
self.assert_identity = true;
self
}
}
impl Client {
/// Creates a new client for making HTTP requests to the given homeserver.
///
@ -1504,7 +1173,7 @@ impl Client {
///
/// ```no_run
/// # use matrix_sdk::{
/// # Client, SyncSettings,
/// # Client, config::SyncSettings,
/// # ruma::api::client::r0::{
/// # filter::{
/// # FilterDefinition, LazyLoadOptions, RoomEventFilter, RoomFilter,
@ -1789,7 +1458,7 @@ impl Client {
/// # Example
/// ```no_run
/// # use std::sync::{Arc, RwLock};
/// # use matrix_sdk::{Client, SyncSettings};
/// # use matrix_sdk::{Client, config::SyncSettings};
/// # use url::Url;
/// # use futures::executor::block_on;
/// # use matrix_sdk::ruma::room_id;
@ -1847,7 +1516,7 @@ impl Client {
/// # Example
///
/// ```no_run
/// # use matrix_sdk::{Client, SyncSettings};
/// # use matrix_sdk::{Client, config::SyncSettings};
/// # use futures::executor::block_on;
/// # use url::Url;
/// # use std::convert::TryFrom;
@ -1886,7 +1555,7 @@ impl Client {
/// # Examples
///
/// ```no_run
/// # use matrix_sdk::{Client, SyncSettings};
/// # use matrix_sdk::{Client, config::SyncSettings};
/// # use futures::executor::block_on;
/// # use url::Url;
/// # use std::convert::TryFrom;
@ -1932,7 +1601,7 @@ impl Client {
/// # },
/// # assign,
/// # },
/// # Client, Error, SyncSettings,
/// # Client, Error, config::SyncSettings,
/// # };
/// # use futures::executor::block_on;
/// # use serde_json::json;
@ -1981,7 +1650,10 @@ impl Client {
///
/// [`sync`]: #method.sync
#[instrument]
pub async fn sync_once(&self, sync_settings: SyncSettings<'_>) -> Result<SyncResponse> {
pub async fn sync_once(
&self,
sync_settings: crate::config::SyncSettings<'_>,
) -> Result<SyncResponse> {
let request = assign!(sync_events::Request::new(), {
filter: sync_settings.filter.as_ref(),
since: sync_settings.token.as_deref(),
@ -2102,7 +1774,7 @@ impl Client {
/// will be only used for the first sync call.
///
/// [`sync_with_callback`]: #method.sync_with_callback
pub async fn sync(&self, sync_settings: SyncSettings<'_>) {
pub async fn sync(&self, sync_settings: crate::config::SyncSettings<'_>) {
self.sync_with_callback(sync_settings, |_| async { LoopCtrl::Continue }).await
}
@ -2131,7 +1803,7 @@ impl Client {
/// # };
/// # use std::sync::{Arc, RwLock};
/// # use std::time::Duration;
/// # use matrix_sdk::{Client, SyncSettings, LoopCtrl};
/// # use matrix_sdk::{Client, config::SyncSettings, LoopCtrl};
/// # use url::Url;
/// # use futures::executor::block_on;
/// # block_on(async {
@ -2164,7 +1836,7 @@ impl Client {
#[instrument(skip(callback))]
pub async fn sync_with_callback<C>(
&self,
mut sync_settings: SyncSettings<'_>,
mut sync_settings: crate::config::SyncSettings<'_>,
callback: impl Fn(SyncResponse) -> C,
) where
C: Future<Output = LoopCtrl>,
@ -2540,8 +2212,11 @@ pub(crate) mod test {
};
use serde_json::json;
use super::{Client, Session, SyncSettings, Url};
use crate::{ClientConfig, HttpError, RequestConfig, RoomMember};
use super::{Client, Session, Url};
use crate::{
config::{ClientConfig, RequestConfig, SyncSettings},
HttpError, RoomMember,
};
pub(crate) async fn logged_in_client() -> Client {
let session = Session {

View File

@ -0,0 +1,177 @@
// Copyright 2021 The Matrix.org Foundation C.I.C.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use std::{
fmt::{self, Debug},
path::Path,
sync::Arc,
};
use http::{header::InvalidHeaderValue, HeaderValue};
use matrix_sdk_base::BaseClientConfig;
use crate::{config::RequestConfig, HttpSend, Result};
/// Configuration for the creation of the `Client`.
///
/// When setting the `StateStore` it is up to the user to open/connect
/// the storage backend before client creation.
///
/// # Example
///
/// ```
/// use matrix_sdk::config::ClientConfig;
/// // To pass all the request through mitmproxy set the proxy and disable SSL
/// // verification
/// let client_config = ClientConfig::new()
/// .proxy("http://localhost:8080")?
/// .disable_ssl_verification();
/// # matrix_sdk::Result::<()>::Ok(())
/// ```
#[derive(Default)]
pub struct ClientConfig {
#[cfg(not(target_arch = "wasm32"))]
pub(crate) proxy: Option<reqwest::Proxy>,
pub(crate) user_agent: Option<HeaderValue>,
pub(crate) disable_ssl_verification: bool,
pub(crate) base_config: BaseClientConfig,
pub(crate) request_config: RequestConfig,
pub(crate) client: Option<Arc<dyn HttpSend>>,
pub(crate) appservice_mode: bool,
}
#[cfg(not(tarpaulin_include))]
impl Debug for ClientConfig {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut res = fmt.debug_struct("ClientConfig");
#[cfg(not(target_arch = "wasm32"))]
let res = res.field("proxy", &self.proxy);
res.field("user_agent", &self.user_agent)
.field("disable_ssl_verification", &self.disable_ssl_verification)
.field("request_config", &self.request_config)
.finish()
}
}
impl ClientConfig {
/// Create a new default `ClientConfig`.
pub fn new() -> Self {
Default::default()
}
/// Set the proxy through which all the HTTP requests should go.
///
/// Note, only HTTP proxies are supported.
///
/// # Arguments
///
/// * `proxy` - The HTTP URL of the proxy.
///
/// # Example
///
/// ```
/// use matrix_sdk::{Client, config::ClientConfig};
///
/// let client_config = ClientConfig::new()
/// .proxy("http://localhost:8080")?;
///
/// # matrix_sdk::Result::Ok(())
/// ```
#[cfg(not(target_arch = "wasm32"))]
pub fn proxy(mut self, proxy: &str) -> Result<Self> {
self.proxy = Some(reqwest::Proxy::all(proxy)?);
Ok(self)
}
/// Disable SSL verification for the HTTP requests.
pub fn disable_ssl_verification(mut self) -> Self {
self.disable_ssl_verification = true;
self
}
/// Set a custom HTTP user agent for the client.
pub fn user_agent(mut self, user_agent: &str) -> std::result::Result<Self, InvalidHeaderValue> {
self.user_agent = Some(HeaderValue::from_str(user_agent)?);
Ok(self)
}
///// Set a custom implementation of a `StateStore`.
/////
///// The state store should be opened before being set.
//pub fn state_store(mut self, store: Box<dyn StateStore>) -> Self {
// self.base_config = self.base_config.state_store(store);
// self
//}
/// Set the path for storage.
///
/// # Arguments
///
/// * `path` - The path where the stores should save data in. It is the
/// callers responsibility to make sure that the path exists.
///
/// In the default configuration the client will open default
/// implementations for the crypto store and the state store. It will use
/// the given path to open the stores. If no path is provided no store will
/// be opened
pub fn store_path(mut self, path: impl AsRef<Path>) -> Self {
self.base_config = self.base_config.store_path(path);
self
}
/// Set the passphrase to encrypt the crypto store.
///
/// # Argument
///
/// * `passphrase` - The passphrase that will be used to encrypt the data in
/// the cryptostore.
///
/// This is only used if no custom cryptostore is set.
pub fn passphrase(mut self, passphrase: String) -> Self {
self.base_config = self.base_config.passphrase(passphrase);
self
}
/// Set the default timeout, fail and retry behavior for all HTTP requests.
pub fn request_config(mut self, request_config: RequestConfig) -> Self {
self.request_config = request_config;
self
}
/// Get the [`RequestConfig`]
pub fn get_request_config(&self) -> &RequestConfig {
&self.request_config
}
/// Specify a client to handle sending requests and receiving responses.
///
/// Any type that implements the `HttpSend` trait can be used to
/// send/receive `http` types.
pub fn client(mut self, client: Arc<dyn HttpSend>) -> Self {
self.client = Some(client);
self
}
/// Puts the client into application service mode
///
/// This is low-level functionality. For an high-level API check the
/// `matrix_sdk_appservice` crate.
#[cfg(feature = "appservice")]
pub fn appservice_mode(mut self) -> Self {
self.appservice_mode = true;
self
}
}

View File

@ -0,0 +1,25 @@
// Copyright 2021 The Matrix.org Foundation C.I.C.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//! Configuration to change the behaviour of the [`Client`].
//!
//! [`Client`]: #crate.Client
mod client;
mod request;
mod sync;
pub use client::ClientConfig;
pub use request::RequestConfig;
pub use sync::SyncSettings;

View File

@ -0,0 +1,124 @@
// Copyright 2021 The Matrix.org Foundation C.I.C.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use std::{
fmt::{self, Debug},
time::Duration,
};
const DEFAULT_REQUEST_TIMEOUT: Duration = Duration::from_secs(10);
/// Configuration for requests the `Client` makes.
///
/// This sets how often and for how long a request should be repeated. As well
/// as how long a successful request is allowed to take.
///
/// By default requests are retried indefinitely and use no timeout.
///
/// # Example
///
/// ```
/// use matrix_sdk::config::RequestConfig;
/// use std::time::Duration;
///
/// // This sets makes requests fail after a single send request and sets the timeout to 30s
/// let request_config = RequestConfig::new()
/// .disable_retry()
/// .timeout(Duration::from_secs(30));
/// ```
#[derive(Copy, Clone)]
pub struct RequestConfig {
pub(crate) timeout: Duration,
pub(crate) retry_limit: Option<u64>,
pub(crate) retry_timeout: Option<Duration>,
pub(crate) force_auth: bool,
pub(crate) assert_identity: bool,
}
#[cfg(not(tarpaulin_include))]
impl Debug for RequestConfig {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut res = fmt.debug_struct("RequestConfig");
res.field("timeout", &self.timeout)
.field("retry_limit", &self.retry_limit)
.field("retry_timeout", &self.retry_timeout)
.finish()
}
}
impl Default for RequestConfig {
fn default() -> Self {
Self {
timeout: DEFAULT_REQUEST_TIMEOUT,
retry_limit: Default::default(),
retry_timeout: Default::default(),
force_auth: false,
assert_identity: false,
}
}
}
impl RequestConfig {
/// Create a new default `RequestConfig`.
pub fn new() -> Self {
Default::default()
}
/// This is a convince method to disable the retries of a request. Setting
/// the `retry_limit` to `0` has the same effect.
pub fn disable_retry(mut self) -> Self {
self.retry_limit = Some(0);
self
}
/// The number of times a request should be retried. The default is no limit
pub fn retry_limit(mut self, retry_limit: u64) -> Self {
self.retry_limit = Some(retry_limit);
self
}
/// Set the timeout duration for all HTTP requests.
pub fn timeout(mut self, timeout: Duration) -> Self {
self.timeout = timeout;
self
}
/// Set a timeout for how long a request should be retried. The default is
/// no timeout, meaning requests are retried forever.
pub fn retry_timeout(mut self, retry_timeout: Duration) -> Self {
self.retry_timeout = Some(retry_timeout);
self
}
/// Force sending authorization even if the endpoint does not require it.
/// Default is only sending authorization if it is required.
pub(crate) fn force_auth(mut self) -> Self {
self.force_auth = true;
self
}
/// All outgoing http requests will have a GET query key-value appended with
/// `user_id` being the key and the `user_id` from the `Session` being
/// the value. Will error if there's no `Session`. This is called
/// [identity assertion] in the Matrix Application Service Spec
///
/// [identity assertion]: https://spec.matrix.org/unstable/application-service-api/#identity-assertion
#[cfg(feature = "appservice")]
#[cfg_attr(feature = "docs", doc(cfg(appservice)))]
pub fn assert_identity(mut self) -> Self {
self.assert_identity = true;
self
}
}

View File

@ -0,0 +1,91 @@
// Copyright 2021 The Matrix.org Foundation C.I.C.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use std::time::Duration;
use ruma::api::client::r0::sync::sync_events;
const DEFAULT_SYNC_TIMEOUT: Duration = Duration::from_secs(30);
#[derive(Debug, Clone)]
/// Settings for a sync call.
pub struct SyncSettings<'a> {
pub(crate) filter: Option<sync_events::Filter<'a>>,
pub(crate) timeout: Option<Duration>,
pub(crate) token: Option<String>,
pub(crate) full_state: bool,
}
impl<'a> Default for SyncSettings<'a> {
fn default() -> Self {
Self {
filter: Default::default(),
timeout: Some(DEFAULT_SYNC_TIMEOUT),
token: Default::default(),
full_state: Default::default(),
}
}
}
impl<'a> SyncSettings<'a> {
/// Create new default sync settings.
pub fn new() -> Self {
Default::default()
}
/// Set the sync token.
///
/// # Arguments
///
/// * `token` - The sync token that should be used for the sync call.
pub fn token(mut self, token: impl Into<String>) -> Self {
self.token = Some(token.into());
self
}
/// Set the maximum time the server can wait, in milliseconds, before
/// responding to the sync request.
///
/// # Arguments
///
/// * `timeout` - The time the server is allowed to wait.
pub fn timeout(mut self, timeout: Duration) -> Self {
self.timeout = Some(timeout);
self
}
/// Set the sync filter.
/// It can be either the filter ID, or the definition for the filter.
///
/// # Arguments
///
/// * `filter` - The filter configuration that should be used for the sync
/// call.
pub fn filter(mut self, filter: sync_events::Filter<'a>) -> Self {
self.filter = Some(filter);
self
}
/// Should the server return the full state from the start of the timeline.
///
/// This does nothing if no sync token is set.
///
/// # Arguments
/// * `full_state` - A boolean deciding if the server should return the full
/// state or not.
pub fn full_state(mut self, full_state: bool) -> Self {
self.full_state = full_state;
self
}
}

View File

@ -344,7 +344,7 @@ impl Client {
/// ```no_run
/// # use std::{path::PathBuf, time::Duration};
/// # use matrix_sdk::{
/// # Client, SyncSettings,
/// # Client, config::SyncSettings,
/// # ruma::room_id,
/// # };
/// # use futures::executor::block_on;
@ -414,7 +414,7 @@ impl Client {
/// ```no_run
/// # use std::{path::PathBuf, time::Duration};
/// # use matrix_sdk::{
/// # Client, SyncSettings,
/// # Client, config::SyncSettings,
/// # ruma::room_id,
/// # };
/// # use futures::executor::block_on;

View File

@ -25,7 +25,11 @@ use ruma::api::{
use tracing::trace;
use url::Url;
use crate::{error::HttpError, ClientConfig, RequestConfig, Session};
use crate::{
config::{ClientConfig, RequestConfig},
error::HttpError,
Session,
};
/// Abstraction around the http layer. The allows implementors to use different
/// http libraries.
@ -49,7 +53,7 @@ pub trait HttpSend: AsyncTraitDeps {
///
/// ```
/// use std::convert::TryFrom;
/// use matrix_sdk::{HttpSend, async_trait, HttpError, RequestConfig, bytes::Bytes};
/// use matrix_sdk::{HttpSend, async_trait, HttpError, config::RequestConfig, bytes::Bytes};
///
/// #[derive(Debug)]
/// struct Client(reqwest::Client);

View File

@ -47,6 +47,7 @@ pub use reqwest;
pub use ruma;
mod client;
pub mod config;
mod error;
pub mod event_handler;
mod http_client;
@ -59,7 +60,7 @@ mod room_member;
#[cfg_attr(feature = "docs", doc(cfg(encryption)))]
pub mod encryption;
pub use client::{Client, ClientConfig, LoopCtrl, RequestConfig, SyncSettings};
pub use client::{Client, LoopCtrl};
pub use error::{Error, HttpError, HttpResult, Result};
pub use http_client::HttpSend;
pub use room_member::RoomMember;

View File

@ -162,8 +162,9 @@ impl Joined {
/// ```no_run
/// use std::time::Duration;
/// use matrix_sdk::ruma::api::client::r0::typing::create_typing_event::Typing;
///
/// # use matrix_sdk::{
/// # Client, SyncSettings,
/// # Client, config::SyncSettings,
/// # ruma::room_id,
/// # };
/// # use futures::executor::block_on;
@ -348,7 +349,7 @@ impl Joined {
/// # Example
/// ```no_run
/// # use std::sync::{Arc, RwLock};
/// # use matrix_sdk::{Client, SyncSettings};
/// # use matrix_sdk::{Client, config::SyncSettings};
/// # use url::Url;
/// # use futures::executor::block_on;
/// # use matrix_sdk::ruma::room_id;

View File

@ -92,9 +92,10 @@ pub use matrix_sdk;
pub use matrix_sdk::ruma;
use matrix_sdk::{
bytes::Bytes,
config::ClientConfig,
event_handler::{EventHandler, EventHandlerResult, SyncEvent},
reqwest::Url,
Client, ClientConfig, Session,
Client, Session,
};
use regex::Regex;
use ruma::{

View File

@ -4,11 +4,11 @@ use std::{
};
use matrix_sdk::{
config::{ClientConfig, RequestConfig},
ruma::{
api::appservice::Registration,
events::{room::member::MemberEventContent, SyncStateEvent},
},
ClientConfig, RequestConfig,
};
use matrix_sdk_appservice::*;
use matrix_sdk_test::{appservice::TransactionBuilder, async_test, EventsJson};