feat(xep): Improve the ergonomics of Bind2 negotiators
This commit is contained in:
parent
ec6b5ab753
commit
b354ca8d0a
@ -28,7 +28,7 @@ enum _StreamManagementNegotiatorState {
|
||||
/// StreamManagementManager at least once before connecting, if stream resumption
|
||||
/// is wanted.
|
||||
class StreamManagementNegotiator extends Sasl2FeatureNegotiator
|
||||
implements Bind2FeatureNegotiator {
|
||||
implements Bind2FeatureNegotiatorInterface {
|
||||
StreamManagementNegotiator()
|
||||
: super(10, false, smXmlns, streamManagementNegotiator);
|
||||
|
||||
@ -256,6 +256,9 @@ class StreamManagementNegotiator extends Sasl2FeatureNegotiator
|
||||
];
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> onBind2Success(XMLNode response) async {}
|
||||
|
||||
@override
|
||||
Future<List<XMLNode>> onSasl2FeaturesReceived(XMLNode sasl2Features) async {
|
||||
final inline = sasl2Features.firstTag('inline')!;
|
||||
|
@ -9,11 +9,8 @@ import 'package:moxxmpp/src/managers/handlers.dart';
|
||||
import 'package:moxxmpp/src/managers/namespaces.dart';
|
||||
import 'package:moxxmpp/src/namespaces.dart';
|
||||
import 'package:moxxmpp/src/negotiators/namespaces.dart';
|
||||
import 'package:moxxmpp/src/negotiators/negotiator.dart';
|
||||
import 'package:moxxmpp/src/negotiators/sasl2.dart';
|
||||
import 'package:moxxmpp/src/stanza.dart';
|
||||
import 'package:moxxmpp/src/stringxml.dart';
|
||||
import 'package:moxxmpp/src/types/result.dart';
|
||||
import 'package:moxxmpp/src/xeps/xep_0030/xep_0030.dart';
|
||||
import 'package:moxxmpp/src/xeps/xep_0297.dart';
|
||||
import 'package:moxxmpp/src/xeps/xep_0386.dart';
|
||||
@ -202,9 +199,8 @@ class CarbonsManager extends XmppManagerBase {
|
||||
}
|
||||
}
|
||||
|
||||
class CarbonsNegotiator extends Sasl2FeatureNegotiator
|
||||
implements Bind2FeatureNegotiator {
|
||||
CarbonsNegotiator() : super(0, false, carbonsXmlns, carbonsNegotiator);
|
||||
class CarbonsNegotiator extends Bind2FeatureNegotiator {
|
||||
CarbonsNegotiator() : super(0, carbonsXmlns, carbonsNegotiator);
|
||||
|
||||
/// Flag indicating whether we requested to enable carbons inline (true) or not
|
||||
/// (false).
|
||||
@ -214,42 +210,26 @@ class CarbonsNegotiator extends Sasl2FeatureNegotiator
|
||||
final Logger _log = Logger('CarbonsNegotiator');
|
||||
|
||||
@override
|
||||
bool canInlineFeature(List<XMLNode> features) => true;
|
||||
|
||||
@override
|
||||
Future<List<XMLNode>> onSasl2FeaturesReceived(XMLNode sasl2Features) async {
|
||||
return [];
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Result<bool, NegotiatorError>> onSasl2Success(XMLNode response) async {
|
||||
if (_requestedEnablement) {
|
||||
final enabled = response
|
||||
.firstTag('bound', xmlns: bind2Xmlns)
|
||||
?.firstTag('enabled', xmlns: carbonsXmlns);
|
||||
final cm = attributes.getManagerById<CarbonsManager>(carbonsManager)!;
|
||||
if (enabled != null) {
|
||||
_log.finest('Successfully enabled Message Carbons inline');
|
||||
cm.setEnabled();
|
||||
} else {
|
||||
_log.warning('Failed to enable Message Carbons inline');
|
||||
cm.setDisabled();
|
||||
}
|
||||
Future<void> onBind2Success(XMLNode response) async {
|
||||
if (!_requestedEnablement) {
|
||||
return;
|
||||
}
|
||||
|
||||
return const Result(true);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Result<NegotiatorState, NegotiatorError>> negotiate(
|
||||
XMLNode nonza,
|
||||
) async {
|
||||
return const Result(NegotiatorState.done);
|
||||
final enabled = response.firstTag('enabled', xmlns: carbonsXmlns);
|
||||
final cm = attributes.getManagerById<CarbonsManager>(carbonsManager)!;
|
||||
if (enabled != null) {
|
||||
_log.finest('Successfully enabled Message Carbons inline');
|
||||
cm.setEnabled();
|
||||
} else {
|
||||
_log.warning('Failed to enable Message Carbons inline');
|
||||
cm.setDisabled();
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<XMLNode>> onBind2FeaturesReceived(
|
||||
List<String> bind2Features) async {
|
||||
List<String> bind2Features,
|
||||
) async {
|
||||
if (!bind2Features.contains(carbonsXmlns)) {
|
||||
return [];
|
||||
}
|
||||
@ -263,16 +243,6 @@ class CarbonsNegotiator extends Sasl2FeatureNegotiator
|
||||
];
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> postRegisterCallback() async {
|
||||
attributes
|
||||
.getNegotiatorById<Sasl2Negotiator>(sasl2Negotiator)
|
||||
?.registerNegotiator(this);
|
||||
attributes
|
||||
.getNegotiatorById<Bind2Negotiator>(bind2Negotiator)
|
||||
?.registerNegotiator(this);
|
||||
}
|
||||
|
||||
@override
|
||||
void reset() {
|
||||
_requestedEnablement = false;
|
||||
|
@ -25,7 +25,7 @@ class CSIInactiveNonza extends XMLNode {
|
||||
|
||||
/// A Stub negotiator that is just for "intercepting" the stream feature.
|
||||
class CSINegotiator extends XmppFeatureNegotiatorBase
|
||||
implements Bind2FeatureNegotiator {
|
||||
implements Bind2FeatureNegotiatorInterface {
|
||||
CSINegotiator() : super(11, false, csiXmlns, csiNegotiator);
|
||||
|
||||
/// True if CSI is supported. False otherwise.
|
||||
@ -50,12 +50,16 @@ class CSINegotiator extends XmppFeatureNegotiatorBase
|
||||
return [];
|
||||
}
|
||||
|
||||
_supported = true;
|
||||
final active = attributes.getManagerById<CSIManager>(csiManager)!.isActive;
|
||||
return [
|
||||
if (active) CSIActiveNonza() else CSIInactiveNonza(),
|
||||
];
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> onBind2Success(XMLNode response) async {}
|
||||
|
||||
@override
|
||||
void reset() {
|
||||
_supported = false;
|
||||
|
@ -1,4 +1,5 @@
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
import 'package:moxxmpp/src/namespaces.dart';
|
||||
import 'package:moxxmpp/src/negotiators/namespaces.dart';
|
||||
import 'package:moxxmpp/src/negotiators/negotiator.dart';
|
||||
@ -9,10 +10,43 @@ import 'package:moxxmpp/src/types/result.dart';
|
||||
/// An interface that allows registering against Bind2's feature list in order to
|
||||
/// negotiate features inline with Bind2.
|
||||
// ignore: one_member_abstracts
|
||||
abstract class Bind2FeatureNegotiator {
|
||||
abstract class Bind2FeatureNegotiatorInterface {
|
||||
/// Called by the Bind2 negotiator when Bind2 features are received. The returned
|
||||
/// [XMLNode]s are added to Bind2's bind request.
|
||||
Future<List<XMLNode>> onBind2FeaturesReceived(List<String> bind2Features);
|
||||
|
||||
/// Called by the Bind2 negotiator when Bind2 results are received.
|
||||
Future<void> onBind2Success(XMLNode result);
|
||||
}
|
||||
|
||||
/// A class that allows for simple negotiators that only registers itself against
|
||||
/// the Bind2 negotiator. You only have to implement the functions required by
|
||||
/// [Bind2FeatureNegotiatorInterface].
|
||||
abstract class Bind2FeatureNegotiator extends XmppFeatureNegotiatorBase
|
||||
implements Bind2FeatureNegotiatorInterface {
|
||||
Bind2FeatureNegotiator(
|
||||
int priority,
|
||||
String negotiatingXmlns,
|
||||
String id,
|
||||
) : super(priority, false, negotiatingXmlns, id);
|
||||
|
||||
@override
|
||||
bool matchesFeature(List<XMLNode> features) => false;
|
||||
|
||||
@override
|
||||
Future<Result<NegotiatorState, NegotiatorError>> negotiate(
|
||||
XMLNode nonza,
|
||||
) async {
|
||||
return const Result(NegotiatorState.done);
|
||||
}
|
||||
|
||||
@mustCallSuper
|
||||
@override
|
||||
Future<void> postRegisterCallback() async {
|
||||
attributes
|
||||
.getNegotiatorById<Bind2Negotiator>(bind2Negotiator)!
|
||||
.registerNegotiator(this);
|
||||
}
|
||||
}
|
||||
|
||||
/// A negotiator implementing XEP-0386. This negotiator is useless on its own
|
||||
@ -21,15 +55,15 @@ class Bind2Negotiator extends Sasl2FeatureNegotiator {
|
||||
Bind2Negotiator() : super(0, false, bind2Xmlns, bind2Negotiator);
|
||||
|
||||
/// A list of negotiators that can work with Bind2.
|
||||
final List<Bind2FeatureNegotiator> _negotiators =
|
||||
List<Bind2FeatureNegotiator>.empty(growable: true);
|
||||
final List<Bind2FeatureNegotiatorInterface> _negotiators =
|
||||
List<Bind2FeatureNegotiatorInterface>.empty(growable: true);
|
||||
|
||||
/// A tag to sent to the server when requesting Bind2.
|
||||
String? tag;
|
||||
|
||||
/// Register [negotiator] against the Bind2 negotiator to append data to the Bind2
|
||||
/// negotiation.
|
||||
void registerNegotiator(Bind2FeatureNegotiator negotiator) {
|
||||
void registerNegotiator(Bind2FeatureNegotiatorInterface negotiator) {
|
||||
_negotiators.add(negotiator);
|
||||
}
|
||||
|
||||
@ -87,8 +121,14 @@ class Bind2Negotiator extends Sasl2FeatureNegotiator {
|
||||
|
||||
@override
|
||||
Future<Result<bool, NegotiatorError>> onSasl2Success(XMLNode response) async {
|
||||
attributes.removeNegotiatingFeature(bindXmlns);
|
||||
final bound = response.firstTag('bound', xmlns: bind2Xmlns);
|
||||
if (bound != null) {
|
||||
for (final negotiator in _negotiators) {
|
||||
await negotiator.onBind2Success(bound);
|
||||
}
|
||||
}
|
||||
|
||||
attributes.removeNegotiatingFeature(bindXmlns);
|
||||
return const Result(true);
|
||||
}
|
||||
|
||||
|
@ -141,6 +141,8 @@ void main() {
|
||||
expect(result.isType<NegotiatorError>(), false);
|
||||
expect(conn.resource, 'test-resource');
|
||||
expect(
|
||||
conn.getManagerById<CarbonsManager>(carbonsManager)!.isEnabled, true);
|
||||
conn.getManagerById<CarbonsManager>(carbonsManager)!.isEnabled,
|
||||
true,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
@ -204,5 +204,9 @@ void main() {
|
||||
);
|
||||
expect(result.isType<NegotiatorError>(), false);
|
||||
expect(fakeSocket.getState(), 2);
|
||||
expect(
|
||||
conn.getNegotiatorById<CSINegotiator>(csiNegotiator)!.isSupported,
|
||||
true,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user