Merge pull request #1875 from TheOneWithTheBraid/braid/well-known-cache
feat: cache .well-known data
This commit is contained in:
commit
5f85acb7f0
|
|
@ -25,7 +25,6 @@ import 'dart:typed_data';
|
|||
import 'package:async/async.dart';
|
||||
import 'package:collection/collection.dart' show IterableExtension;
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:http/http.dart';
|
||||
import 'package:mime/mime.dart';
|
||||
import 'package:olm/olm.dart' as olm;
|
||||
import 'package:random_string/random_string.dart';
|
||||
|
|
@ -124,6 +123,24 @@ class Client extends MatrixApi {
|
|||
/// The timeout until a typing indicator gets removed automatically.
|
||||
final Duration typingIndicatorTimeout;
|
||||
|
||||
DiscoveryInformation? _wellKnown;
|
||||
|
||||
/// the cached .well-known file updated using [getWellknown]
|
||||
DiscoveryInformation? get wellKnown => _wellKnown;
|
||||
|
||||
/// The homeserver this client is communicating with.
|
||||
///
|
||||
/// In case the [homeserver]'s host differs from the previous value, the
|
||||
/// [wellKnown] cache will be invalidated.
|
||||
@override
|
||||
set homeserver(Uri? homeserver) {
|
||||
if (homeserver?.host != this.homeserver?.host) {
|
||||
_wellKnown = null;
|
||||
unawaited(database?.storeWellKnown(null));
|
||||
}
|
||||
super.homeserver = homeserver;
|
||||
}
|
||||
|
||||
Future<MatrixImageFileResizedResponse?> Function(
|
||||
MatrixImageFileResizeArguments)? customImageResizer;
|
||||
|
||||
|
|
@ -531,6 +548,27 @@ class Client extends MatrixApi {
|
|||
}
|
||||
}
|
||||
|
||||
/// Gets discovery information about the domain. The file may include
|
||||
/// additional keys, which MUST follow the Java package naming convention,
|
||||
/// e.g. `com.example.myapp.property`. This ensures property names are
|
||||
/// suitably namespaced for each application and reduces the risk of
|
||||
/// clashes.
|
||||
///
|
||||
/// Note that this endpoint is not necessarily handled by the homeserver,
|
||||
/// but by another webserver, to be used for discovering the homeserver URL.
|
||||
///
|
||||
/// The result of this call is stored in [wellKnown] for later use at runtime.
|
||||
@override
|
||||
Future<DiscoveryInformation> getWellknown() async {
|
||||
final wellKnown = await super.getWellknown();
|
||||
|
||||
// do not reset the well known here, so super call
|
||||
super.homeserver = wellKnown.mHomeserver.baseUrl.stripTrailingSlash();
|
||||
_wellKnown = wellKnown;
|
||||
await database?.storeWellKnown(wellKnown);
|
||||
return wellKnown;
|
||||
}
|
||||
|
||||
/// Checks to see if a username is available, and valid, for the server.
|
||||
/// Returns the fully-qualified Matrix user ID (MXID) that has been registered.
|
||||
/// You have to call [checkHomeserver] first to set a homeserver.
|
||||
|
|
@ -1196,7 +1234,7 @@ class Client extends MatrixApi {
|
|||
path = '_matrix/media/v3/config';
|
||||
}
|
||||
final requestUri = Uri(path: path);
|
||||
final request = Request('GET', baseUri!.resolveUri(requestUri));
|
||||
final request = http.Request('GET', baseUri!.resolveUri(requestUri));
|
||||
request.headers['authorization'] = 'Bearer ${bearerToken!}';
|
||||
final response = await httpClient.send(request);
|
||||
final responseBody = await response.stream.toBytes();
|
||||
|
|
@ -1236,7 +1274,7 @@ class Client extends MatrixApi {
|
|||
// removed with msc3916, so just to be explicit
|
||||
'allow_remote': allowRemote.toString(),
|
||||
});
|
||||
final request = Request('GET', baseUri!.resolveUri(requestUri));
|
||||
final request = http.Request('GET', baseUri!.resolveUri(requestUri));
|
||||
request.headers['authorization'] = 'Bearer ${bearerToken!}';
|
||||
final response = await httpClient.send(request);
|
||||
final responseBody = await response.stream.toBytes();
|
||||
|
|
@ -1279,7 +1317,7 @@ class Client extends MatrixApi {
|
|||
// removed with msc3916, so just to be explicit
|
||||
'allow_remote': allowRemote.toString(),
|
||||
});
|
||||
final request = Request('GET', baseUri!.resolveUri(requestUri));
|
||||
final request = http.Request('GET', baseUri!.resolveUri(requestUri));
|
||||
request.headers['authorization'] = 'Bearer ${bearerToken!}';
|
||||
final response = await httpClient.send(request);
|
||||
final responseBody = await response.stream.toBytes();
|
||||
|
|
@ -1315,7 +1353,7 @@ class Client extends MatrixApi {
|
|||
'url': url.toString(),
|
||||
if (ts != null) 'ts': ts.toString(),
|
||||
});
|
||||
final request = Request('GET', baseUri!.resolveUri(requestUri));
|
||||
final request = http.Request('GET', baseUri!.resolveUri(requestUri));
|
||||
request.headers['authorization'] = 'Bearer ${bearerToken!}';
|
||||
final response = await httpClient.send(request);
|
||||
final responseBody = await response.stream.toBytes();
|
||||
|
|
@ -1369,7 +1407,7 @@ class Client extends MatrixApi {
|
|||
'allow_remote': allowRemote.toString(),
|
||||
});
|
||||
|
||||
final request = Request('GET', baseUri!.resolveUri(requestUri));
|
||||
final request = http.Request('GET', baseUri!.resolveUri(requestUri));
|
||||
request.headers['authorization'] = 'Bearer ${bearerToken!}';
|
||||
final response = await httpClient.send(request);
|
||||
final responseBody = await response.stream.toBytes();
|
||||
|
|
@ -1956,12 +1994,16 @@ class Client extends MatrixApi {
|
|||
_accountData = data;
|
||||
_updatePushrules();
|
||||
});
|
||||
_discoveryDataLoading = database.getWellKnown().then((data) {
|
||||
_wellKnown = data;
|
||||
});
|
||||
// ignore: deprecated_member_use_from_same_package
|
||||
presences.clear();
|
||||
if (waitUntilLoadCompletedLoaded) {
|
||||
await userDeviceKeysLoading;
|
||||
await roomsLoading;
|
||||
await _accountDataLoading;
|
||||
await _discoveryDataLoading;
|
||||
}
|
||||
}
|
||||
_initLock = false;
|
||||
|
|
@ -2784,10 +2826,13 @@ class Client extends MatrixApi {
|
|||
Future? userDeviceKeysLoading;
|
||||
Future? roomsLoading;
|
||||
Future? _accountDataLoading;
|
||||
Future? _discoveryDataLoading;
|
||||
Future? firstSyncReceived;
|
||||
|
||||
Future? get accountDataLoading => _accountDataLoading;
|
||||
|
||||
Future? get wellKnownLoading => _discoveryDataLoading;
|
||||
|
||||
/// A map of known device keys per user.
|
||||
Map<String, DeviceKeysList> get userDeviceKeys => _userDeviceKeys;
|
||||
Map<String, DeviceKeysList> _userDeviceKeys = {};
|
||||
|
|
@ -3593,6 +3638,7 @@ class SdkError {
|
|||
|
||||
class SyncConnectionException implements Exception {
|
||||
final Object originalException;
|
||||
|
||||
SyncConnectionException(this.originalException);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,9 @@ import 'package:matrix/src/utils/queued_to_device_event.dart';
|
|||
|
||||
abstract class DatabaseApi {
|
||||
int get maxFileSize => 1 * 1024 * 1024;
|
||||
|
||||
bool get supportsFileStoring => false;
|
||||
|
||||
Future<Map<String, dynamic>?> getClient(String name);
|
||||
|
||||
Future updateClient(
|
||||
|
|
@ -334,6 +336,10 @@ abstract class DatabaseApi {
|
|||
|
||||
Future<CachedPresence?> getPresence(String userId);
|
||||
|
||||
Future<void> storeWellKnown(DiscoveryInformation? discoveryInformation);
|
||||
|
||||
Future<DiscoveryInformation?> getWellKnown();
|
||||
|
||||
/// Deletes the whole database. The database needs to be created again after
|
||||
/// this.
|
||||
Future<void> delete();
|
||||
|
|
|
|||
|
|
@ -1595,6 +1595,25 @@ class HiveCollectionsDatabase extends DatabaseApi {
|
|||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> storeWellKnown(DiscoveryInformation? discoveryInformation) {
|
||||
if (discoveryInformation == null) {
|
||||
return _clientBox.delete('discovery_information');
|
||||
}
|
||||
return _clientBox.put(
|
||||
'discovery_information',
|
||||
jsonEncode(discoveryInformation.toJson()),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<DiscoveryInformation?> getWellKnown() async {
|
||||
final rawDiscoveryInformation =
|
||||
await _clientBox.get('discovery_information');
|
||||
if (rawDiscoveryInformation == null) return null;
|
||||
return DiscoveryInformation.fromJson(jsonDecode(rawDiscoveryInformation));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> delete() => _collection.deleteFromDisk();
|
||||
|
||||
|
|
|
|||
|
|
@ -1401,6 +1401,25 @@ class FamedlySdkHiveDatabase extends DatabaseApi with ZoneTransactionMixin {
|
|||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> storeWellKnown(DiscoveryInformation? discoveryInformation) {
|
||||
if (discoveryInformation == null) {
|
||||
return _clientBox.delete('discovery_information');
|
||||
}
|
||||
return _clientBox.put(
|
||||
'discovery_information',
|
||||
jsonEncode(discoveryInformation.toJson()),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<DiscoveryInformation?> getWellKnown() async {
|
||||
final rawDiscoveryInformation =
|
||||
await _clientBox.get('discovery_information');
|
||||
if (rawDiscoveryInformation == null) return null;
|
||||
return DiscoveryInformation.fromJson(jsonDecode(rawDiscoveryInformation));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> delete() => Hive.deleteFromDisk();
|
||||
|
||||
|
|
|
|||
|
|
@ -1623,6 +1623,25 @@ class MatrixSdkDatabase extends DatabaseApi with DatabaseFileStorage {
|
|||
return CachedPresence.fromJson(copyMap(rawPresence));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> storeWellKnown(DiscoveryInformation? discoveryInformation) {
|
||||
if (discoveryInformation == null) {
|
||||
return _clientBox.delete('discovery_information');
|
||||
}
|
||||
return _clientBox.put(
|
||||
'discovery_information',
|
||||
jsonEncode(discoveryInformation.toJson()),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<DiscoveryInformation?> getWellKnown() async {
|
||||
final rawDiscoveryInformation =
|
||||
await _clientBox.get('discovery_information');
|
||||
if (rawDiscoveryInformation == null) return null;
|
||||
return DiscoveryInformation.fromJson(jsonDecode(rawDiscoveryInformation));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> delete() async {
|
||||
// database?.path is null on web
|
||||
|
|
|
|||
|
|
@ -175,6 +175,7 @@ void main() {
|
|||
matrix.userDeviceKeys['@alice:example.com']?.deviceKeys['JLAFKJWSCS']
|
||||
?.verified,
|
||||
false);
|
||||
expect(matrix.wellKnown, isNull);
|
||||
|
||||
await matrix.handleSync(SyncUpdate.fromJson({
|
||||
'next_batch': 'fakesync',
|
||||
|
|
@ -1168,6 +1169,13 @@ void main() {
|
|||
await client.dispose(closeDatabase: true);
|
||||
});
|
||||
|
||||
test('wellKnown cache', () async {
|
||||
final client = await getClient();
|
||||
expect(client.wellKnown, null);
|
||||
await client.getWellknown();
|
||||
expect(client.wellKnown?.mHomeserver.baseUrl.host, 'matrix.example.com');
|
||||
});
|
||||
|
||||
test('refreshAccessToken', () async {
|
||||
final client = await getClient();
|
||||
expect(client.accessToken, 'abcd');
|
||||
|
|
|
|||
Loading…
Reference in New Issue