discoInfoQuery method
Send a disco#info query to entity
. If node
is specified, then the disco#info
request will be directed against that one node of entity
.
shouldEncrypt
indicates to possible end-to-end encryption implementations whether
the request should be encrypted (true) or not (false).
shouldCache
indicates whether the successful result of the disco#info query
should be cached (true) or not(false).
Implementation
Future<Result<StanzaError, DiscoInfo>> discoInfoQuery(
JID entity, {
String? node,
bool shouldEncrypt = false,
bool shouldCache = true,
}) async {
DiscoInfo? info;
final cacheKey = DiscoCacheKey(entity, node);
final ecm = getAttributes()
.getManagerById<EntityCapabilitiesManager>(entityCapabilitiesManager);
final ffuture = await _cacheLock
.synchronized<Future<Future<Result<StanzaError, DiscoInfo>>?>?>(
() async {
// Check if we already know what the JID supports
if (_discoInfoCache.containsKey(cacheKey)) {
info = _discoInfoCache[cacheKey];
return null;
} else {
// Check if we know entity capabilities
if (ecm != null && node == null) {
info = await ecm.getCachedDiscoInfoFromJid(entity);
if (info != null) {
return null;
}
}
return _discoInfoTracker.waitFor(cacheKey);
}
});
if (info != null) {
return Result<DiscoError, DiscoInfo>(info);
} else {
final future = await ffuture;
if (future != null) {
return future;
}
}
final stanza = (await getAttributes().sendStanza(
StanzaDetails(
buildDiscoInfoQueryStanza(entity, node),
shouldEncrypt: shouldEncrypt,
),
))!;
// Error handling
if (stanza.attributes['type'] == 'error') {
final result =
Result<StanzaError, DiscoInfo>(StanzaError.fromXMLNode(stanza));
await _exitDiscoInfoCriticalSection(cacheKey, result, shouldCache);
return result;
}
final query = stanza.firstTag('query');
if (query == null) {
final result = Result<DiscoError, DiscoInfo>(InvalidResponseDiscoError());
await _exitDiscoInfoCriticalSection(cacheKey, result, shouldCache);
return result;
}
final result = Result<DiscoError, DiscoInfo>(
DiscoInfo.fromQuery(
query,
entity,
),
);
await _exitDiscoInfoCriticalSection(cacheKey, result, shouldCache);
return result;
}