feat(xep): Allow inlining CSI
This commit is contained in:
parent
4a6aa79e56
commit
fbb495dc2f
@ -5,6 +5,7 @@ import 'package:moxxmpp/src/negotiators/namespaces.dart';
|
|||||||
import 'package:moxxmpp/src/negotiators/negotiator.dart';
|
import 'package:moxxmpp/src/negotiators/negotiator.dart';
|
||||||
import 'package:moxxmpp/src/stringxml.dart';
|
import 'package:moxxmpp/src/stringxml.dart';
|
||||||
import 'package:moxxmpp/src/types/result.dart';
|
import 'package:moxxmpp/src/types/result.dart';
|
||||||
|
import 'package:moxxmpp/src/xeps/xep_0386.dart';
|
||||||
|
|
||||||
class CSIActiveNonza extends XMLNode {
|
class CSIActiveNonza extends XMLNode {
|
||||||
CSIActiveNonza()
|
CSIActiveNonza()
|
||||||
@ -23,7 +24,8 @@ class CSIInactiveNonza extends XMLNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A Stub negotiator that is just for "intercepting" the stream feature.
|
/// A Stub negotiator that is just for "intercepting" the stream feature.
|
||||||
class CSINegotiator extends XmppFeatureNegotiatorBase {
|
class CSINegotiator extends XmppFeatureNegotiatorBase
|
||||||
|
implements Bind2FeatureNegotiator {
|
||||||
CSINegotiator() : super(11, false, csiXmlns, csiNegotiator);
|
CSINegotiator() : super(11, false, csiXmlns, csiNegotiator);
|
||||||
|
|
||||||
/// True if CSI is supported. False otherwise.
|
/// True if CSI is supported. False otherwise.
|
||||||
@ -40,19 +42,43 @@ class CSINegotiator extends XmppFeatureNegotiatorBase {
|
|||||||
return const Result(NegotiatorState.done);
|
return const Result(NegotiatorState.done);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<List<XMLNode>> onBind2FeaturesReceived(
|
||||||
|
List<String> bind2Features,
|
||||||
|
) async {
|
||||||
|
if (!bind2Features.contains(csiXmlns)) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
final active = attributes.getManagerById<CSIManager>(csiManager)!.isActive;
|
||||||
|
return [
|
||||||
|
if (active) CSIActiveNonza() else CSIInactiveNonza(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void reset() {
|
void reset() {
|
||||||
_supported = false;
|
_supported = false;
|
||||||
|
|
||||||
super.reset();
|
super.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> postRegisterCallback() async {
|
||||||
|
attributes
|
||||||
|
.getNegotiatorById<Bind2Negotiator>(bind2Negotiator)
|
||||||
|
?.registerNegotiator(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The manager requires a CSINegotiator to be registered as a feature negotiator.
|
/// The manager requires a CSINegotiator to be registered as a feature negotiator.
|
||||||
class CSIManager extends XmppManagerBase {
|
class CSIManager extends XmppManagerBase {
|
||||||
CSIManager() : super(csiManager);
|
CSIManager() : super(csiManager);
|
||||||
|
|
||||||
|
/// Flag indicating whether the application is currently active and the CSI
|
||||||
|
/// traffic optimisation should be disabled (true).
|
||||||
bool _isActive = true;
|
bool _isActive = true;
|
||||||
|
bool get isActive => _isActive;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<bool> isSupported() async {
|
Future<bool> isSupported() async {
|
||||||
@ -71,23 +97,31 @@ class CSIManager extends XmppManagerBase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Tells the server to top optimizing traffic
|
/// Tells the server to stop optimizing traffic.
|
||||||
Future<void> setActive() async {
|
/// If [sendNonza] is false, then no nonza is sent. This is useful
|
||||||
|
/// for setting up the CSI manager for Bind2.
|
||||||
|
Future<void> setActive({bool sendNonza = true}) async {
|
||||||
_isActive = true;
|
_isActive = true;
|
||||||
|
|
||||||
final attrs = getAttributes();
|
if (sendNonza) {
|
||||||
if (await isSupported()) {
|
final attrs = getAttributes();
|
||||||
attrs.sendNonza(CSIActiveNonza());
|
if (await isSupported()) {
|
||||||
|
attrs.sendNonza(CSIActiveNonza());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Tells the server to optimize traffic following XEP-0352
|
/// Tells the server to optimize traffic following XEP-0352
|
||||||
Future<void> setInactive() async {
|
/// If [sendNonza] is false, then no nonza is sent. This is useful
|
||||||
|
/// for setting up the CSI manager for Bind2.
|
||||||
|
Future<void> setInactive({bool sendNonza = true}) async {
|
||||||
_isActive = false;
|
_isActive = false;
|
||||||
|
|
||||||
final attrs = getAttributes();
|
if (sendNonza) {
|
||||||
if (await isSupported()) {
|
final attrs = getAttributes();
|
||||||
attrs.sendNonza(CSIInactiveNonza());
|
if (await isSupported()) {
|
||||||
|
attrs.sendNonza(CSIInactiveNonza());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import 'package:moxxmpp/moxxmpp.dart';
|
import 'package:moxxmpp/moxxmpp.dart';
|
||||||
import 'package:test/test.dart';
|
import 'package:test/test.dart';
|
||||||
|
import '../helpers/logging.dart';
|
||||||
import '../helpers/xmpp.dart';
|
import '../helpers/xmpp.dart';
|
||||||
|
|
||||||
class MockedCSINegotiator extends CSINegotiator {
|
class MockedCSINegotiator extends CSINegotiator {
|
||||||
@ -28,6 +29,8 @@ T? getUnsupportedCSINegotiator<T extends XmppFeatureNegotiatorBase>(String id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
|
initLogger();
|
||||||
|
|
||||||
group('Test the XEP-0352 implementation', () {
|
group('Test the XEP-0352 implementation', () {
|
||||||
test('Test setting the CSI state when CSI is unsupported', () {
|
test('Test setting the CSI state when CSI is unsupported', () {
|
||||||
var nonzaSent = false;
|
var nonzaSent = false;
|
||||||
@ -111,4 +114,95 @@ void main() {
|
|||||||
..setInactive();
|
..setInactive();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('Test CSI with Bind2', () async {
|
||||||
|
final fakeSocket = StubTCPSocket([
|
||||||
|
StringExpectation(
|
||||||
|
"<stream:stream xmlns='jabber:client' version='1.0' xmlns:stream='http://etherx.jabber.org/streams' to='test.server' xml:lang='en'>",
|
||||||
|
'''
|
||||||
|
<stream:stream
|
||||||
|
xmlns="jabber:client"
|
||||||
|
version="1.0"
|
||||||
|
xmlns:stream="http://etherx.jabber.org/streams"
|
||||||
|
from="test.server"
|
||||||
|
xml:lang="en">
|
||||||
|
<stream:features xmlns="http://etherx.jabber.org/streams">
|
||||||
|
<mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl">
|
||||||
|
<mechanism>PLAIN</mechanism>
|
||||||
|
</mechanisms>
|
||||||
|
<authentication xmlns='urn:xmpp:sasl:2'>
|
||||||
|
<mechanism>PLAIN</mechanism>
|
||||||
|
<inline>
|
||||||
|
<bind xmlns="urn:xmpp:bind:0">
|
||||||
|
<inline>
|
||||||
|
<feature var="urn:xmpp:csi:0" />
|
||||||
|
</inline>
|
||||||
|
</bind>
|
||||||
|
</inline>
|
||||||
|
</authentication>
|
||||||
|
<bind xmlns="urn:ietf:params:xml:ns:xmpp-bind">
|
||||||
|
<required/>
|
||||||
|
</bind>
|
||||||
|
</stream:features>''',
|
||||||
|
),
|
||||||
|
StanzaExpectation(
|
||||||
|
'''
|
||||||
|
<authenticate xmlns='urn:xmpp:sasl:2' mechanism='PLAIN'>
|
||||||
|
<user-agent id='d4565fa7-4d72-4749-b3d3-740edbf87770'>
|
||||||
|
<software>moxxmpp</software>
|
||||||
|
<device>PapaTutuWawa's awesome device</device>
|
||||||
|
</user-agent>
|
||||||
|
<initial-response>AHBvbHlub21kaXZpc2lvbgBhYWFh</initial-response>
|
||||||
|
<bind xmlns='urn:xmpp:bind:0'>
|
||||||
|
<inactive xmlns='urn:xmpp:csi:0' />
|
||||||
|
</bind>
|
||||||
|
</authenticate>''',
|
||||||
|
'''
|
||||||
|
<success xmlns='urn:xmpp:sasl:2'>
|
||||||
|
<authorization-identifier>polynomdivision@test.server/test-resource</authorization-identifier>
|
||||||
|
</success>
|
||||||
|
''',
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
final conn = XmppConnection(
|
||||||
|
TestingReconnectionPolicy(),
|
||||||
|
AlwaysConnectedConnectivityManager(),
|
||||||
|
fakeSocket,
|
||||||
|
)..setConnectionSettings(
|
||||||
|
ConnectionSettings(
|
||||||
|
jid: JID.fromString('polynomdivision@test.server'),
|
||||||
|
password: 'aaaa',
|
||||||
|
useDirectTLS: true,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
final csi = CSIManager();
|
||||||
|
await csi.setInactive(sendNonza: false);
|
||||||
|
await conn.registerManagers([
|
||||||
|
RosterManager(TestingRosterStateManager('', [])),
|
||||||
|
DiscoManager([]),
|
||||||
|
csi,
|
||||||
|
]);
|
||||||
|
await conn.registerFeatureNegotiators([
|
||||||
|
SaslPlainNegotiator(),
|
||||||
|
ResourceBindingNegotiator(),
|
||||||
|
FASTSaslNegotiator(),
|
||||||
|
Bind2Negotiator(),
|
||||||
|
CSINegotiator(),
|
||||||
|
Sasl2Negotiator(
|
||||||
|
userAgent: const UserAgent(
|
||||||
|
id: 'd4565fa7-4d72-4749-b3d3-740edbf87770',
|
||||||
|
software: 'moxxmpp',
|
||||||
|
device: "PapaTutuWawa's awesome device",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
|
||||||
|
final result = await conn.connect(
|
||||||
|
waitUntilLogin: true,
|
||||||
|
shouldReconnect: false,
|
||||||
|
enableReconnectOnSuccess: false,
|
||||||
|
);
|
||||||
|
expect(result.isType<NegotiatorError>(), false);
|
||||||
|
expect(fakeSocket.getState(), 2);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user