Compare commits

..

No commits in common. "b49658784b2ce27dae209ad55079d3f802014cac" and "85995d51e4d9e1518ee8647ea684631a5d927129" have entirely different histories.

6 changed files with 107 additions and 118 deletions

View File

@ -5,7 +5,7 @@ import 'package:moxxmpp/moxxmpp.dart';
import 'package:moxxmpp_socket_tcp/moxxmpp_socket_tcp.dart'; import 'package:moxxmpp_socket_tcp/moxxmpp_socket_tcp.dart';
class ExampleTcpSocketWrapper extends TCPSocketWrapper { class ExampleTcpSocketWrapper extends TCPSocketWrapper {
ExampleTcpSocketWrapper() : super(); ExampleTcpSocketWrapper() : super(false);
@override @override
Future<List<MoxSrvRecord>> srvQuery(String domain, bool dnssec) async { Future<List<MoxSrvRecord>> srvQuery(String domain, bool dnssec) async {
@ -64,7 +64,7 @@ class _MyHomePageState extends State<MyHomePage> {
// The below causes the app to crash. // The below causes the app to crash.
//ExampleTcpSocketWrapper(), //ExampleTcpSocketWrapper(),
// In a production app, the below should be false. // In a production app, the below should be false.
TCPSocketWrapper(), TCPSocketWrapper(true),
); );
TextEditingController jidController = TextEditingController(); TextEditingController jidController = TextEditingController();
TextEditingController passwordController = TextEditingController(); TextEditingController passwordController = TextEditingController();

View File

@ -397,9 +397,6 @@ class XmppConnection {
return; return;
} }
// Close the socket
_socket.close();
if (!error.isRecoverable()) { if (!error.isRecoverable()) {
// We cannot recover this error // We cannot recover this error
_log.severe( _log.severe(

View File

@ -5,7 +5,7 @@ import 'package:test/test.dart';
Future<void> _runTest(String domain) async { Future<void> _runTest(String domain) async {
var gotTLSException = false; var gotTLSException = false;
final socket = TCPSocketWrapper(); final socket = TCPSocketWrapper(false);
final log = Logger('TestLogger'); final log = Logger('TestLogger');
socket.getEventStream().listen((event) { socket.getEventStream().listen((event) {
if (event is XmppSocketTLSFailedEvent) { if (event is XmppSocketTLSFailedEvent) {
@ -15,17 +15,18 @@ Future<void> _runTest(String domain) async {
}); });
final connection = XmppConnection( final connection = XmppConnection(
TestingReconnectionPolicy(), ExponentialBackoffReconnectionPolicy(),
AlwaysConnectedConnectivityManager(),
socket, socket,
)..registerFeatureNegotiators([ );
StartTlsNegotiator(), connection.registerFeatureNegotiators([
]); StartTlsNegotiator(),
await connection.registerManagers([ ]);
DiscoManager([]), connection.registerManagers([
RosterManager(TestingRosterStateManager('', [])), DiscoManager(),
RosterManager(),
PingManager(),
MessageManager(), MessageManager(),
PresenceManager(), PresenceManager('http://moxxmpp.example'),
]); ]);
connection.setConnectionSettings( connection.setConnectionSettings(
@ -33,22 +34,18 @@ Future<void> _runTest(String domain) async {
jid: JID.fromString('testuser@$domain'), jid: JID.fromString('testuser@$domain'),
password: 'abc123', password: 'abc123',
useDirectTLS: true, useDirectTLS: true,
allowPlainAuth: true,
), ),
); );
final result = await connection.connect( final result = await connection.connectAwaitable();
shouldReconnect: false, expect(result.success, false);
waitUntilLogin: true,
enableReconnectOnSuccess: false,
);
expect(result.isType<XmppError>(), false);
expect(gotTLSException, true); expect(gotTLSException, true);
} }
void main() { void main() {
Logger.root.level = Level.ALL; Logger.root.level = Level.ALL;
Logger.root.onRecord.listen((record) { Logger.root.onRecord.listen((record) {
// ignore: avoid_print
print('${record.level.name}: ${record.time}: ${record.message}'); print('${record.level.name}: ${record.time}: ${record.message}');
}); });

View File

@ -6,106 +6,93 @@ import 'package:test/test.dart';
void main() { void main() {
Logger.root.level = Level.ALL; Logger.root.level = Level.ALL;
Logger.root.onRecord.listen((record) { Logger.root.onRecord.listen((record) {
// ignore: avoid_print
print('${record.level.name}: ${record.time}: ${record.message}'); print('${record.level.name}: ${record.time}: ${record.message}');
}); });
final log = Logger('FailureReconnectionTest'); final log = Logger('FailureReconnectionTest');
test( test('Failing an awaited connection with TestingSleepReconnectionPolicy', () async {
'Failing an awaited connection with TestingSleepReconnectionPolicy', var errors = 0;
() async { final connection = XmppConnection(
var errors = 0; TestingSleepReconnectionPolicy(10),
final connection = XmppConnection( TCPSocketWrapper(false),
TestingSleepReconnectionPolicy(10), );
AlwaysConnectedConnectivityManager(), connection.registerFeatureNegotiators([
TCPSocketWrapper(), StartTlsNegotiator(),
)..registerFeatureNegotiators([ ]);
StartTlsNegotiator(), connection.registerManagers([
]); DiscoManager(),
await connection.registerManagers([ RosterManager(),
DiscoManager([]), PingManager(),
RosterManager(TestingRosterStateManager('', [])), MessageManager(),
MessageManager(), PresenceManager('http://moxxmpp.example'),
PresenceManager(), ]);
]); connection.asBroadcastStream().listen((event) {
connection.asBroadcastStream().listen((event) { if (event is ConnectionStateChangedEvent) {
if (event is ConnectionStateChangedEvent) { if (event.state == XmppConnectionState.error) {
if (event.state == XmppConnectionState.error) { errors++;
errors++;
}
} }
}); }
});
connection.setConnectionSettings( connection.setConnectionSettings(
ConnectionSettings( ConnectionSettings(
jid: JID.fromString('testuser@no-sasl.badxmpp.eu'), jid: JID.fromString('testuser@no-sasl.badxmpp.eu'),
password: 'abc123', password: 'abc123',
useDirectTLS: true, useDirectTLS: true,
), allowPlainAuth: true,
); ),
);
final result = await connection.connect( final result = await connection.connectAwaitable();
shouldReconnect: false, log.info('Connection failed as expected');
waitUntilLogin: true, expect(result.success, false);
enableReconnectOnSuccess: false, expect(errors, 1);
);
log.info('Connection failed as expected');
expect(result.isType<XmppError>(), false);
expect(errors, 1);
log.info('Waiting 20 seconds for unexpected reconnections'); log.info('Waiting 20 seconds for unexpected reconnections');
await Future<void>.delayed(const Duration(seconds: 20)); await Future.delayed(const Duration(seconds: 20));
expect(errors, 1); expect(errors, 1);
}, }, timeout: Timeout.factor(2));
timeout: const Timeout.factor(2),
);
test( test('Failing an awaited connection with ExponentialBackoffReconnectionPolicy', () async {
'Failing an awaited connection with ExponentialBackoffReconnectionPolicy', var errors = 0;
() async { final connection = XmppConnection(
var errors = 0; ExponentialBackoffReconnectionPolicy(1),
final connection = XmppConnection( TCPSocketWrapper(false),
TestingReconnectionPolicy(), );
AlwaysConnectedConnectivityManager(), connection.registerFeatureNegotiators([
TCPSocketWrapper(), StartTlsNegotiator(),
)..registerFeatureNegotiators([ ]);
StartTlsNegotiator(), connection.registerManagers([
]); DiscoManager(),
await connection.registerManagers([ RosterManager(),
DiscoManager([]), PingManager(),
RosterManager(TestingRosterStateManager('', [])), MessageManager(),
MessageManager(), PresenceManager('http://moxxmpp.example'),
PresenceManager(), ]);
]); connection.asBroadcastStream().listen((event) {
connection.asBroadcastStream().listen((event) { if (event is ConnectionStateChangedEvent) {
if (event is ConnectionStateChangedEvent) { if (event.state == XmppConnectionState.error) {
if (event.state == XmppConnectionState.error) { errors++;
errors++;
}
} }
}); }
});
connection.setConnectionSettings( connection.setConnectionSettings(
ConnectionSettings( ConnectionSettings(
jid: JID.fromString('testuser@no-sasl.badxmpp.eu'), jid: JID.fromString('testuser@no-sasl.badxmpp.eu'),
password: 'abc123', password: 'abc123',
useDirectTLS: true, useDirectTLS: true,
), allowPlainAuth: true,
); ),
);
final result = await connection.connect( final result = await connection.connectAwaitable();
shouldReconnect: false, log.info('Connection failed as expected');
waitUntilLogin: true, expect(result.success, false);
enableReconnectOnSuccess: false, expect(errors, 1);
);
log.info('Connection failed as expected');
expect(result.isType<XmppError>(), false);
expect(errors, 1);
log.info('Waiting 20 seconds for unexpected reconnections'); log.info('Waiting 20 seconds for unexpected reconnections');
await Future<void>.delayed(const Duration(seconds: 20)); await Future.delayed(const Duration(seconds: 20));
expect(errors, 1); expect(errors, 1);
}, }, timeout: Timeout.factor(2));
timeout: const Timeout.factor(2),
);
} }

View File

@ -10,6 +10,8 @@ import 'package:moxxmpp_socket_tcp/src/rfc_2782.dart';
/// TCP socket implementation for XmppConnection /// TCP socket implementation for XmppConnection
class TCPSocketWrapper extends BaseSocketWrapper { class TCPSocketWrapper extends BaseSocketWrapper {
TCPSocketWrapper(this._logData);
/// The underlying Socket/SecureSocket instance. /// The underlying Socket/SecureSocket instance.
Socket? _socket; Socket? _socket;
@ -29,6 +31,9 @@ class TCPSocketWrapper extends BaseSocketWrapper {
/// Logger /// Logger
final Logger _log = Logger('TCPSocketWrapper'); final Logger _log = Logger('TCPSocketWrapper');
/// Flag to indicate if incoming and outgoing data should get logged.
final bool _logData;
/// Indiacted whether the connection is secure. /// Indiacted whether the connection is secure.
bool _secure = false; bool _secure = false;
@ -212,7 +217,9 @@ class TCPSocketWrapper extends BaseSocketWrapper {
_socketSubscription = _socket!.listen( _socketSubscription = _socket!.listen(
(List<int> event) { (List<int> event) {
final data = utf8.decode(event); final data = utf8.decode(event);
_log.finest('<== $data'); if (_logData) {
_log.finest('<== $data');
}
_dataStream.add(data); _dataStream.add(data);
}, },
onError: (Object error) { onError: (Object error) {
@ -289,16 +296,18 @@ class TCPSocketWrapper extends BaseSocketWrapper {
_eventStream.stream.asBroadcastStream(); _eventStream.stream.asBroadcastStream();
@override @override
void write(String data, {String? redact}) { void write(Object? data, {String? redact}) {
if (_socket == null) { if (_socket == null) {
_log.severe('Failed to write to socket as _socket is null'); _log.severe('Failed to write to socket as _socket is null');
return; return;
} }
if (redact != null) { if (data != null && data is String && _logData) {
_log.finest('**> $redact'); if (redact != null) {
} else { _log.finest('**> $redact');
_log.finest('==> $data'); } else {
_log.finest('==> $data');
}
} }
try { try {