Merge branch 'famous'
commit
7a5daf6ac7
|
@ -75,8 +75,19 @@ pub enum LoopCtrl {
|
||||||
Break,
|
Break,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "encryption")]
|
||||||
use matrix_sdk_common::{
|
use matrix_sdk_common::{
|
||||||
api::r0::{
|
api::r0::{
|
||||||
|
keys::{get_keys, upload_keys, upload_signing_keys::Request as UploadSigningKeysRequest},
|
||||||
|
to_device::send_event_to_device::{
|
||||||
|
Request as RumaToDeviceRequest, Response as ToDeviceResponse,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
identifiers::EventId,
|
||||||
|
};
|
||||||
|
use matrix_sdk_common::{
|
||||||
|
api::{
|
||||||
|
r0::{
|
||||||
account::register,
|
account::register,
|
||||||
device::{delete_devices, get_devices},
|
device::{delete_devices, get_devices},
|
||||||
directory::{get_public_rooms, get_public_rooms_filtered},
|
directory::{get_public_rooms, get_public_rooms_filtered},
|
||||||
|
@ -90,6 +101,8 @@ use matrix_sdk_common::{
|
||||||
sync::sync_events,
|
sync::sync_events,
|
||||||
uiaa::AuthData,
|
uiaa::AuthData,
|
||||||
},
|
},
|
||||||
|
unversioned::{discover_homeserver, get_supported_versions},
|
||||||
|
},
|
||||||
assign,
|
assign,
|
||||||
identifiers::{DeviceIdBox, RoomId, RoomIdOrAliasId, ServerName, UserId},
|
identifiers::{DeviceIdBox, RoomId, RoomIdOrAliasId, ServerName, UserId},
|
||||||
instant::{Duration, Instant},
|
instant::{Duration, Instant},
|
||||||
|
@ -98,16 +111,6 @@ use matrix_sdk_common::{
|
||||||
uuid::Uuid,
|
uuid::Uuid,
|
||||||
FromHttpResponseError, UInt,
|
FromHttpResponseError, UInt,
|
||||||
};
|
};
|
||||||
#[cfg(feature = "encryption")]
|
|
||||||
use matrix_sdk_common::{
|
|
||||||
api::r0::{
|
|
||||||
keys::{get_keys, upload_keys, upload_signing_keys::Request as UploadSigningKeysRequest},
|
|
||||||
to_device::send_event_to_device::{
|
|
||||||
Request as RumaToDeviceRequest, Response as ToDeviceResponse,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
identifiers::EventId,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[cfg(feature = "encryption")]
|
#[cfg(feature = "encryption")]
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -142,7 +145,7 @@ const SSO_SERVER_BIND_TRIES: u8 = 10;
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Client {
|
pub struct Client {
|
||||||
/// The URL of the homeserver to connect to.
|
/// The URL of the homeserver to connect to.
|
||||||
homeserver: Arc<Url>,
|
homeserver: Arc<RwLock<Url>>,
|
||||||
/// The underlying HTTP client.
|
/// The underlying HTTP client.
|
||||||
http_client: HttpClient,
|
http_client: HttpClient,
|
||||||
/// User session data.
|
/// User session data.
|
||||||
|
@ -164,7 +167,7 @@ pub struct Client {
|
||||||
#[cfg(not(tarpaulin_include))]
|
#[cfg(not(tarpaulin_include))]
|
||||||
impl Debug for Client {
|
impl Debug for Client {
|
||||||
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> StdResult<(), fmt::Error> {
|
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> StdResult<(), fmt::Error> {
|
||||||
write!(fmt, "Client {{ homeserver: {} }}", self.homeserver)
|
write!(fmt, "Client")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -502,7 +505,7 @@ impl Client {
|
||||||
///
|
///
|
||||||
/// * `config` - Configuration for the client.
|
/// * `config` - Configuration for the client.
|
||||||
pub fn new_with_config(homeserver_url: Url, config: ClientConfig) -> Result<Self> {
|
pub fn new_with_config(homeserver_url: Url, config: ClientConfig) -> Result<Self> {
|
||||||
let homeserver = Arc::new(homeserver_url);
|
let homeserver = Arc::new(RwLock::new(homeserver_url));
|
||||||
|
|
||||||
let client = if let Some(client) = config.client {
|
let client = if let Some(client) = config.client {
|
||||||
client
|
client
|
||||||
|
@ -513,12 +516,8 @@ impl Client {
|
||||||
let base_client = BaseClient::new_with_config(config.base_config)?;
|
let base_client = BaseClient::new_with_config(config.base_config)?;
|
||||||
let session = base_client.session().clone();
|
let session = base_client.session().clone();
|
||||||
|
|
||||||
let http_client = HttpClient {
|
let http_client =
|
||||||
homeserver: homeserver.clone(),
|
HttpClient::new(client, homeserver.clone(), session, config.request_config);
|
||||||
inner: client,
|
|
||||||
session,
|
|
||||||
request_config: config.request_config,
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
homeserver,
|
homeserver,
|
||||||
|
@ -534,6 +533,89 @@ impl Client {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Creates a new client for making HTTP requests to the homeserver of the
|
||||||
|
/// given user. Follows homeserver discovery directions described
|
||||||
|
/// [here](https://spec.matrix.org/unstable/client-server-api/#well-known-uri).
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
///
|
||||||
|
/// * `user_id` - The id of the user whose homeserver the client should
|
||||||
|
/// connect to.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
/// ```no_run
|
||||||
|
/// # use std::convert::TryFrom;
|
||||||
|
/// # use matrix_sdk::{Client, identifiers::UserId};
|
||||||
|
/// # use futures::executor::block_on;
|
||||||
|
/// let alice = UserId::try_from("@alice:example.org").unwrap();
|
||||||
|
/// # block_on(async {
|
||||||
|
/// let client = Client::new_from_user_id(alice.clone()).await.unwrap();
|
||||||
|
/// client.login(alice.localpart(), "password", None, None).await.unwrap();
|
||||||
|
/// # });
|
||||||
|
/// ```
|
||||||
|
pub async fn new_from_user_id(user_id: UserId) -> Result<Self> {
|
||||||
|
let config = ClientConfig::new();
|
||||||
|
Client::new_from_user_id_with_config(user_id, config).await
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates a new client for making HTTP requests to the homeserver of the
|
||||||
|
/// given user and configuration. Follows homeserver discovery directions
|
||||||
|
/// described [here](https://spec.matrix.org/unstable/client-server-api/#well-known-uri).
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
///
|
||||||
|
/// * `user_id` - The id of the user whose homeserver the client should
|
||||||
|
/// connect to.
|
||||||
|
///
|
||||||
|
/// * `config` - Configuration for the client.
|
||||||
|
pub async fn new_from_user_id_with_config(
|
||||||
|
user_id: UserId,
|
||||||
|
config: ClientConfig,
|
||||||
|
) -> Result<Self> {
|
||||||
|
let homeserver = Client::homeserver_from_user_id(user_id)?;
|
||||||
|
let mut client = Client::new_with_config(homeserver, config)?;
|
||||||
|
|
||||||
|
let well_known = client.discover_homeserver().await?;
|
||||||
|
let well_known = Url::parse(well_known.homeserver.base_url.as_ref())?;
|
||||||
|
client.set_homeserver(well_known).await;
|
||||||
|
client.get_supported_versions().await?;
|
||||||
|
Ok(client)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn homeserver_from_user_id(user_id: UserId) -> Result<Url> {
|
||||||
|
let homeserver = format!("https://{}", user_id.server_name());
|
||||||
|
#[allow(unused_mut)]
|
||||||
|
let mut result = Url::parse(homeserver.as_str())?;
|
||||||
|
// Mockito only knows how to test http endpoints:
|
||||||
|
// https://github.com/lipanski/mockito/issues/127
|
||||||
|
#[cfg(test)]
|
||||||
|
let _ = result.set_scheme("http");
|
||||||
|
Ok(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn discover_homeserver(&self) -> Result<discover_homeserver::Response> {
|
||||||
|
self.send(discover_homeserver::Request::new(), Some(RequestConfig::new().disable_retry()))
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Change the homeserver URL used by this client.
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
///
|
||||||
|
/// * `homeserver_url` - The new URL to use.
|
||||||
|
pub async fn set_homeserver(&mut self, homeserver_url: Url) {
|
||||||
|
let mut homeserver = self.homeserver.write().await;
|
||||||
|
*homeserver = homeserver_url;
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_supported_versions(&self) -> Result<get_supported_versions::Response> {
|
||||||
|
self.send(
|
||||||
|
get_supported_versions::Request::new(),
|
||||||
|
Some(RequestConfig::new().disable_retry()),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
|
||||||
/// Process a [transaction] received from the homeserver
|
/// Process a [transaction] received from the homeserver
|
||||||
///
|
///
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
|
@ -566,8 +648,8 @@ impl Client {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The Homeserver of the client.
|
/// The Homeserver of the client.
|
||||||
pub fn homeserver(&self) -> &Url {
|
pub async fn homeserver(&self) -> Url {
|
||||||
&self.homeserver
|
self.homeserver.read().await.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the user id of the current owner of the client.
|
/// Get the user id of the current owner of the client.
|
||||||
|
@ -866,8 +948,8 @@ impl Client {
|
||||||
/// successful SSO login.
|
/// successful SSO login.
|
||||||
///
|
///
|
||||||
/// [`login_with_token`]: #method.login_with_token
|
/// [`login_with_token`]: #method.login_with_token
|
||||||
pub fn get_sso_login_url(&self, redirect_url: &str) -> Result<String> {
|
pub async fn get_sso_login_url(&self, redirect_url: &str) -> Result<String> {
|
||||||
let homeserver = self.homeserver();
|
let homeserver = self.homeserver().await;
|
||||||
let request = sso_login::Request::new(redirect_url)
|
let request = sso_login::Request::new(redirect_url)
|
||||||
.try_into_http_request::<Vec<u8>>(homeserver.as_str(), SendAccessToken::None);
|
.try_into_http_request::<Vec<u8>>(homeserver.as_str(), SendAccessToken::None);
|
||||||
match request {
|
match request {
|
||||||
|
@ -928,7 +1010,7 @@ impl Client {
|
||||||
device_id: Option<&str>,
|
device_id: Option<&str>,
|
||||||
initial_device_display_name: Option<&str>,
|
initial_device_display_name: Option<&str>,
|
||||||
) -> Result<login::Response> {
|
) -> Result<login::Response> {
|
||||||
info!("Logging in to {} as {:?}", self.homeserver, user);
|
info!("Logging in to {} as {:?}", self.homeserver().await, user);
|
||||||
|
|
||||||
let request = assign!(
|
let request = assign!(
|
||||||
login::Request::new(
|
login::Request::new(
|
||||||
|
@ -1037,7 +1119,7 @@ impl Client {
|
||||||
where
|
where
|
||||||
C: Future<Output = Result<()>>,
|
C: Future<Output = Result<()>>,
|
||||||
{
|
{
|
||||||
info!("Logging in to {}", self.homeserver);
|
info!("Logging in to {}", self.homeserver().await);
|
||||||
let (signal_tx, signal_rx) = oneshot::channel();
|
let (signal_tx, signal_rx) = oneshot::channel();
|
||||||
let (data_tx, data_rx) = oneshot::channel();
|
let (data_tx, data_rx) = oneshot::channel();
|
||||||
let data_tx_mutex = Arc::new(std::sync::Mutex::new(Some(data_tx)));
|
let data_tx_mutex = Arc::new(std::sync::Mutex::new(Some(data_tx)));
|
||||||
|
@ -1109,7 +1191,7 @@ impl Client {
|
||||||
|
|
||||||
tokio::spawn(server);
|
tokio::spawn(server);
|
||||||
|
|
||||||
let sso_url = self.get_sso_login_url(redirect_url.as_str()).unwrap();
|
let sso_url = self.get_sso_login_url(redirect_url.as_str()).await.unwrap();
|
||||||
|
|
||||||
match use_sso_login_url(sso_url).await {
|
match use_sso_login_url(sso_url).await {
|
||||||
Ok(t) => t,
|
Ok(t) => t,
|
||||||
|
@ -1193,7 +1275,7 @@ impl Client {
|
||||||
device_id: Option<&str>,
|
device_id: Option<&str>,
|
||||||
initial_device_display_name: Option<&str>,
|
initial_device_display_name: Option<&str>,
|
||||||
) -> Result<login::Response> {
|
) -> Result<login::Response> {
|
||||||
info!("Logging in to {}", self.homeserver);
|
info!("Logging in to {}", self.homeserver().await);
|
||||||
|
|
||||||
let request = assign!(
|
let request = assign!(
|
||||||
login::Request::new(
|
login::Request::new(
|
||||||
|
@ -1264,7 +1346,7 @@ impl Client {
|
||||||
&self,
|
&self,
|
||||||
registration: impl Into<register::Request<'_>>,
|
registration: impl Into<register::Request<'_>>,
|
||||||
) -> Result<register::Response> {
|
) -> Result<register::Response> {
|
||||||
info!("Registering to {}", self.homeserver);
|
info!("Registering to {}", self.homeserver().await);
|
||||||
|
|
||||||
let request = registration.into();
|
let request = registration.into();
|
||||||
self.send(request, None).await
|
self.send(request, None).await
|
||||||
|
@ -2387,7 +2469,13 @@ impl Client {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use std::{collections::BTreeMap, convert::TryInto, io::Cursor, str::FromStr, time::Duration};
|
use std::{
|
||||||
|
collections::BTreeMap,
|
||||||
|
convert::{TryFrom, TryInto},
|
||||||
|
io::Cursor,
|
||||||
|
str::FromStr,
|
||||||
|
time::Duration,
|
||||||
|
};
|
||||||
|
|
||||||
use matrix_sdk_base::identifiers::mxc_uri;
|
use matrix_sdk_base::identifiers::mxc_uri;
|
||||||
use matrix_sdk_common::{
|
use matrix_sdk_common::{
|
||||||
|
@ -2399,7 +2487,7 @@ mod test {
|
||||||
assign,
|
assign,
|
||||||
directory::Filter,
|
directory::Filter,
|
||||||
events::{room::message::MessageEventContent, AnyMessageEventContent},
|
events::{room::message::MessageEventContent, AnyMessageEventContent},
|
||||||
identifiers::{event_id, room_id, user_id},
|
identifiers::{event_id, room_id, user_id, UserId},
|
||||||
thirdparty,
|
thirdparty,
|
||||||
};
|
};
|
||||||
use matrix_sdk_test::{test_json, EventBuilder, EventsJson};
|
use matrix_sdk_test::{test_json, EventBuilder, EventsJson};
|
||||||
|
@ -2425,6 +2513,59 @@ mod test {
|
||||||
client
|
client
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn set_homeserver() {
|
||||||
|
let homeserver = Url::from_str("http://example.com/").unwrap();
|
||||||
|
|
||||||
|
let mut client = Client::new(homeserver).unwrap();
|
||||||
|
|
||||||
|
let homeserver = Url::from_str(&mockito::server_url()).unwrap();
|
||||||
|
|
||||||
|
client.set_homeserver(homeserver.clone()).await;
|
||||||
|
|
||||||
|
assert_eq!(client.homeserver().await, homeserver);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn successful_discovery() {
|
||||||
|
let server_url = mockito::server_url();
|
||||||
|
let domain = server_url.strip_prefix("http://").unwrap();
|
||||||
|
let alice = UserId::try_from("@alice:".to_string() + domain).unwrap();
|
||||||
|
|
||||||
|
let _m_well_known = mock("GET", "/.well-known/matrix/client")
|
||||||
|
.with_status(200)
|
||||||
|
.with_body(
|
||||||
|
test_json::WELL_KNOWN.to_string().replace("HOMESERVER_URL", server_url.as_ref()),
|
||||||
|
)
|
||||||
|
.create();
|
||||||
|
|
||||||
|
let _m_versions = mock("GET", "/_matrix/client/versions")
|
||||||
|
.with_status(200)
|
||||||
|
.with_body(test_json::VERSIONS.to_string())
|
||||||
|
.create();
|
||||||
|
let client = Client::new_from_user_id(alice).await.unwrap();
|
||||||
|
|
||||||
|
assert_eq!(client.homeserver().await, Url::parse(server_url.as_ref()).unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn discovery_broken_server() {
|
||||||
|
let server_url = mockito::server_url();
|
||||||
|
let domain = server_url.strip_prefix("http://").unwrap();
|
||||||
|
let alice = UserId::try_from("@alice:".to_string() + domain).unwrap();
|
||||||
|
|
||||||
|
let _m = mock("GET", "/.well-known/matrix/client")
|
||||||
|
.with_status(200)
|
||||||
|
.with_body(
|
||||||
|
test_json::WELL_KNOWN.to_string().replace("HOMESERVER_URL", server_url.as_ref()),
|
||||||
|
)
|
||||||
|
.create();
|
||||||
|
|
||||||
|
if Client::new_from_user_id(alice).await.is_ok() {
|
||||||
|
panic!("Creating a client from a user ID should fail when the .well-known server returns no version infromation.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn login() {
|
async fn login() {
|
||||||
let homeserver = Url::from_str(&mockito::server_url()).unwrap();
|
let homeserver = Url::from_str(&mockito::server_url()).unwrap();
|
||||||
|
@ -2514,7 +2655,7 @@ mod test {
|
||||||
.any(|flow| matches!(flow, LoginType::Sso(_)));
|
.any(|flow| matches!(flow, LoginType::Sso(_)));
|
||||||
assert!(can_sso);
|
assert!(can_sso);
|
||||||
|
|
||||||
let sso_url = client.get_sso_login_url("http://127.0.0.1:3030");
|
let sso_url = client.get_sso_login_url("http://127.0.0.1:3030").await;
|
||||||
assert!(sso_url.is_ok());
|
assert!(sso_url.is_ok());
|
||||||
|
|
||||||
let _m = mock("POST", "/_matrix/client/r0/login")
|
let _m = mock("POST", "/_matrix/client/r0/login")
|
||||||
|
@ -2626,7 +2767,7 @@ mod test {
|
||||||
client.base_client.receive_sync_response(response).await.unwrap();
|
client.base_client.receive_sync_response(response).await.unwrap();
|
||||||
let room_id = room_id!("!SVkFJHzfwvuaIEawgC:localhost");
|
let room_id = room_id!("!SVkFJHzfwvuaIEawgC:localhost");
|
||||||
|
|
||||||
assert_eq!(client.homeserver(), &Url::parse(&mockito::server_url()).unwrap());
|
assert_eq!(client.homeserver().await, Url::parse(&mockito::server_url()).unwrap());
|
||||||
|
|
||||||
let room = client.get_joined_room(&room_id);
|
let room = client.get_joined_room(&room_id);
|
||||||
assert!(room.is_some());
|
assert!(room.is_some());
|
||||||
|
|
|
@ -31,6 +31,7 @@ use matrix_sdk_common::{
|
||||||
use reqwest::Error as ReqwestError;
|
use reqwest::Error as ReqwestError;
|
||||||
use serde_json::Error as JsonError;
|
use serde_json::Error as JsonError;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
use url::ParseError as UrlParseError;
|
||||||
|
|
||||||
/// Result type of the rust-sdk.
|
/// Result type of the rust-sdk.
|
||||||
pub type Result<T> = std::result::Result<T, Error>;
|
pub type Result<T> = std::result::Result<T, Error>;
|
||||||
|
@ -128,6 +129,10 @@ pub enum Error {
|
||||||
/// An error encountered when trying to parse an identifier.
|
/// An error encountered when trying to parse an identifier.
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
Identifier(#[from] IdentifierError),
|
Identifier(#[from] IdentifierError),
|
||||||
|
|
||||||
|
/// An error encountered when trying to parse a url.
|
||||||
|
#[error(transparent)]
|
||||||
|
Url(#[from] UrlParseError),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Error {
|
impl Error {
|
||||||
|
|
|
@ -97,7 +97,7 @@ pub trait HttpSend: AsyncTraitDeps {
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub(crate) struct HttpClient {
|
pub(crate) struct HttpClient {
|
||||||
pub(crate) inner: Arc<dyn HttpSend>,
|
pub(crate) inner: Arc<dyn HttpSend>,
|
||||||
pub(crate) homeserver: Arc<Url>,
|
pub(crate) homeserver: Arc<RwLock<Url>>,
|
||||||
pub(crate) session: Arc<RwLock<Option<Session>>>,
|
pub(crate) session: Arc<RwLock<Option<Session>>>,
|
||||||
pub(crate) request_config: RequestConfig,
|
pub(crate) request_config: RequestConfig,
|
||||||
}
|
}
|
||||||
|
@ -106,6 +106,15 @@ pub(crate) struct HttpClient {
|
||||||
use crate::OutgoingRequestAppserviceExt;
|
use crate::OutgoingRequestAppserviceExt;
|
||||||
|
|
||||||
impl HttpClient {
|
impl HttpClient {
|
||||||
|
pub(crate) fn new(
|
||||||
|
inner: Arc<dyn HttpSend>,
|
||||||
|
homeserver: Arc<RwLock<Url>>,
|
||||||
|
session: Arc<RwLock<Option<Session>>>,
|
||||||
|
request_config: RequestConfig,
|
||||||
|
) -> Self {
|
||||||
|
HttpClient { inner, homeserver, session, request_config }
|
||||||
|
}
|
||||||
|
|
||||||
async fn send_request<Request: OutgoingRequest>(
|
async fn send_request<Request: OutgoingRequest>(
|
||||||
&self,
|
&self,
|
||||||
request: Request,
|
request: Request,
|
||||||
|
@ -161,7 +170,10 @@ impl HttpClient {
|
||||||
};
|
};
|
||||||
|
|
||||||
let http_request = request
|
let http_request = request
|
||||||
.try_into_http_request::<BytesMut>(&self.homeserver.to_string(), access_token)?
|
.try_into_http_request::<BytesMut>(
|
||||||
|
&self.homeserver.read().await.to_string(),
|
||||||
|
access_token,
|
||||||
|
)?
|
||||||
.map(|body| body.freeze());
|
.map(|body| body.freeze());
|
||||||
|
|
||||||
Ok(http_request)
|
Ok(http_request)
|
||||||
|
@ -189,7 +201,7 @@ impl HttpClient {
|
||||||
|
|
||||||
let http_request = request
|
let http_request = request
|
||||||
.try_into_http_request_with_user_id::<BytesMut>(
|
.try_into_http_request_with_user_id::<BytesMut>(
|
||||||
&self.homeserver.to_string(),
|
&self.homeserver.read().await.to_string(),
|
||||||
access_token,
|
access_token,
|
||||||
user_id,
|
user_id,
|
||||||
)?
|
)?
|
||||||
|
|
|
@ -42,3 +42,29 @@ lazy_static! {
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
pub static ref WELL_KNOWN: JsonValue = json!({
|
||||||
|
"m.homeserver": {
|
||||||
|
"base_url": "HOMESERVER_URL"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
pub static ref VERSIONS: JsonValue = json!({
|
||||||
|
"versions": [
|
||||||
|
"r0.0.1",
|
||||||
|
"r0.1.0",
|
||||||
|
"r0.2.0",
|
||||||
|
"r0.3.0",
|
||||||
|
"r0.4.0",
|
||||||
|
"r0.5.0",
|
||||||
|
"r0.6.0"
|
||||||
|
],
|
||||||
|
"unstable_features": {
|
||||||
|
"org.matrix.label_based_filtering":true,
|
||||||
|
"org.matrix.e2e_cross_signing":true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue