connect method

Future<bool> connect()

Implementation

Future<bool> connect() async {
  Socket locSocket;
  try {
    if (serverConfig.isSecure) {
      var securityContext = SecurityContext.defaultContext;
      if (serverConfig.tlsCAFileContent != null &&
          !_caCertificateAlreadyInHash) {
        securityContext
            .setTrustedCertificatesBytes(serverConfig.tlsCAFileContent!);
      }
      if (serverConfig.tlsCertificateKeyFileContent != null) {
        securityContext
          ..useCertificateChainBytes(
              serverConfig.tlsCertificateKeyFileContent!)
          ..usePrivateKeyBytes(serverConfig.tlsCertificateKeyFileContent!,
              password: serverConfig.tlsCertificateKeyFilePassword);
      }

      locSocket = await SecureSocket.connect(
          serverConfig.host, serverConfig.port, context: securityContext,
          onBadCertificate: (certificate) {
        // couldn't find here if the cause is an hostname mismatch
        return serverConfig.tlsAllowInvalidCertificates;
      });
    } else {
      locSocket = await Socket.connect(serverConfig.host, serverConfig.port);
    }
  } on TlsException catch (e) {
    if (e.osError?.message
            .contains('CERT_ALREADY_IN_HASH_TABLE(x509_lu.c:356)') ??
        false) {
      _caCertificateAlreadyInHash = true;
      return connect();
    }
    _closed = true;
    connected = false;
    var ex = ConnectionException(
        'Could not connect to ${serverConfig.hostUrl}\n- $e');
    throw ex;
  } catch (e) {
    _closed = true;
    connected = false;
    var ex = ConnectionException(
        'Could not connect to ${serverConfig.hostUrl}\n- $e');
    throw ex;
  }

  // ignore: unawaited_futures
  locSocket.done.catchError((error) {
    _log.info('Socket error $error');
    throw ConnectionException('Socket error: $error');
  });
  socket = locSocket;

  _repliesSubscription = socket!
      .transform<MongoResponseMessage>(MongoMessageHandler().transformer)
      .listen(_receiveReply,
          onError: (e, st) async {
            _log.severe('Socket error $e $st');
            if (!_closed) {
              await _closeSocketOnError(socketError: e);
            }
          },
          cancelOnError: true,
          // onDone is not called in any case after onData or OnError,
          // it is called when the socket closes, i.e. it is an error.
          // Possible causes:
          // * Trying to connect to a tls encrypted Database
          //   without specifing tls=true in the query parms or setting
          //   the secure parameter to true in db.open()
          onDone: () async {
            if (!_closed) {
              await _closeSocketOnError(socketError: noSecureRequestError);
            }
          });
  connected = true;
  return true;
}