0

I am connecting to signalr using signalr_core. I created the code as below and there is no problem with this connection.

  SignalRNotification() {
    if (this._hubConnection == null) {
      var options =
          IOClient(HttpClient()..badCertificateCallback = (x, y, z) => true);
      this._hubConnection = HubConnectionBuilder()
          .withUrl(serverUrl, options)
          .withAutomaticReconnect()
          .build();
    }

    this._initHub();
  }

I want to modify the header information in options.

I added a header referring to this article. However, a CERTIFICATE_VERIFY_FAILED error occurs.

E/flutter ( 2902): [ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: HandshakeException: Handshake error in client (OS Error: 
E/flutter ( 2902):  CERTIFICATE_VERIFY_FAILED: unable to get local issuer certificate(handshake.cc:354))

Here is my code.

import 'dart:io';
import 'package:http/io_client.dart';
import 'package:signalr_core/signalr_core.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:flutter/foundation.dart';
import '../resources/common.dart';

class _HttpClient extends http.BaseClient {
  final _httpClient = http.Client();

  final Map<String, String> defaultHeaders;

  _HttpClient({@required this.defaultHeaders});

  @override
  Future<http.StreamedResponse> send(http.BaseRequest request) {
    request.headers.addAll(defaultHeaders);
    return _httpClient.send(request);
  }
}

class SignalRNotification {
  static String serverUrl = SignalRURL;
  HubConnection _hubConnection;
  NotificationManager notificationManager = NotificationManager();
  final httpClient = _HttpClient(defaultHeaders: {
    "X-Api-Key": "key",
    "X-Client-Id": "id",
  });

  SignalRNotification() {
    if (this._hubConnection == null) {
      this._hubConnection = HubConnectionBuilder()
          .withUrl(serverUrl, HttpConnectionOptions(client: httpClient))
          .withAutomaticReconnect()
          .build();
    }

    this._initHub();
  }

I think this problem occurs because there is no badCertificateCallback in the _HttpClient

I also referred to this article, but it didn't work. I want to know the solution.

PPADDOA
  • 3
  • 2
  • It's impossible 'class _HttpClient extends http.BaseClient...' Can you give me a specific example? – PPADDOA Apr 15 '21 at 11:06

1 Answers1

1

HttpClient from dart:io (which I will refer to as io.HttpClient) provides a badCertificateCallback setter but package:http's BaseClient does not.

However, package:http provides several implementations for its BaseClient class. One of them is IOClient (which I will refer to as http.IOClient) which is backed by an io.HttpClient.

You therefore should be able to use an http.IOClient with an io.HttpClient that is configured the way you want, something like:

import 'dart:io' as io;
import 'package:http/http.dart' as http;
import 'package:http/io_client.dart' as http;

class _HttpClient extends http.BaseClient {
  final io.HttpClient _ioHttpClient;
  final http.IOClient _httpClient;

  final Map<String, String> defaultHeaders;

  _HttpClient({@required this.defaultHeaders})
     : _ioHttpClient = io.HttpClient() {
    _httpClient = http.IOClient(_ioHttpClient);
  }

  void set badCertificateCallback(BadCertificateCallback callback) =>
    _ioHttpClient.badCertificateCallback = callback;

  @override
  Future<http.StreamedResponse> send(http.BaseRequest request) {
    request.headers.addAll(defaultHeaders);
    return _httpClient.send(request);
  }
}
jamesdlin
  • 81,374
  • 13
  • 159
  • 204
  • I don't think this code is complete. An error has occurred in the IDE. for example : Undefined class 'http.IOClient' , All final variables must be initialized, but '_httpClient' isn't., The function 'IOClient' isn't defined. – PPADDOA Apr 15 '21 at 23:57
  • Sorry, I forgot an `import`. It's an untested example; the point is to demonstrate the approach to point you in the right direction, not necessarily to give you an exact implementation. – jamesdlin Apr 16 '21 at 00:55