CodingAleCR / http_interceptor

A lightweight, simple plugin that allows you to intercept request and response objects and modify them if desired.
MIT License
134 stars 67 forks source link

HandshakeException: Connection terminated during handshake #36

Closed 1996SEJR closed 4 years ago

1996SEJR commented 4 years ago

Obtengo la siguiente excepción cuando hago peticiones http, ¿Qué podría estar sucediendo? En sí la excepción se produce al realizar peticiones get. Nota: esto no ocurre todo el tiempo, es rara vez que se presenta (VERSION: ^0.2.0) image

También suele pasar esto: image

El interceptior corresponde a este código:

import 'dart:async';
import 'package:http_interceptor/http_interceptor.dart';

class Interceptor implements InterceptorContract {

  @override
  Future<RequestData> interceptRequest({RequestData data}) async {
    if (_session != null) {
      data.headers['authorization'] = 'TOKEN';
      data.headers['content-type'] = 'application/json';
    }
    return data;
  }

  @override
  Future<ResponseData> interceptResponse({ResponseData data}) async {
    return data;
  }
}

Y en sí la petición http corresponde a este código

import 'package:http/http.dart' as http;
import 'package:http_interceptor/http_client_with_interceptor.dart';
import 'package:larvia/src/interceptor/interceptor.dart';

class ApiHelper {
  HttpClientWithInterceptor client = HttpClientWithInterceptor.build(interceptors: [
    Interceptor(),
  ]);

  Future<http.Response> get(String url, {Map<String, dynamic> params}) async {
    final Uri uri = Uri(scheme: 'https', host: 'domain', path: url, queryParameters: params);
    http.Response response = await client.get(uri);
    return response;
  }
}
issue-label-bot[bot] commented 4 years ago

Issue-Label Bot is automatically applying the label bug to this issue, with a confidence of 0.60. Please mark this comment with :thumbsup: or :thumbsdown: to give our bot feedback!

Links: app homepage, dashboard and code for this bot.

CodingAleCR commented 4 years ago

Hola, primero muchas gracias por abrir el issue para esto. Ahora, ¿podrías probar con las nuevas versiones del plugin? Me parece muy raro que estuviera relacionado a la librería por el uso interno que hace de http. También me gustaría saber si tienes de casualidad algún porcentaje de incidencias o si te sucede sólo a vos. Podrían ser problemas de conexión con el dispositivo también, pero me gustaría verificarlo todo.

1996SEJR commented 4 years ago

El problema está ocurriendo entre grupo de usuario internos que están probando una aplicación, no tengo un porcentaje, pero no sucede con mucha frecuencia. He visto que podría estar relacionado con el certificado ssl del servidor, pero no tengo una idea clara de que acciones tomar.

CodingAleCR commented 4 years ago

Ummm, la versión 0.3.1+ (recomiendo que utilices la versión más nueva) introduce la capacidad de aprovechar para sobreescribir el comportamiento que acepta o niega el handshake de acuerdo al certificado ssl (por el momento una funcionalidad experimental debido a que no he podido hacer unit testing para ello), tal vez podrías hacer un intento de utilizar esta funcionalidad y verificar si el comportamiento se reduce o si se mantiene. El salto de versión de 0.2.0 a 0.3.2 no debería ser muy difícil ya que no hay breaking changes. Aunque el ejemplo está en el README te lo comparto por acá para mayor facilidad:

Future<Map<String, dynamic>> fetchCityWeather(int id) async {
    var parsedWeather;
    try {
      var response = await HttpWithInterceptor.build(
              interceptors: [WeatherApiInterceptor()],
              badCertificateCallback: (certificate, host, port) => true)
          .get("$baseUrl/weather", params: {'id': "$id"});
      if (response.statusCode == 200) {
        parsedWeather = json.decode(response.body);
      } else {
        throw Exception("Error while fetching. \n ${response.body}");
      }
    } catch (e) {
      print(e);
    }
    return parsedWeather;
  }

Por otro lado, cuando me he encontrado problemas como éste, normalmente están asociados a una mala señal de internet (tal vez usando datos o muy lejos del WiFi Access Point). Si este es el caso tuyo (que en realidad no sabemos) entonces sería bueno que verifiques el estado de la conexión desde tu aplicación y así evitar problemas.

1996SEJR commented 4 years ago

badCertificateCallback no verifica ningun certificado SSL ? o que es lo que hace ?

CodingAleCR commented 4 years ago

badCertificateCallback es una función que permite sobreescribir la manera en que se verifican los certificados SSL. Lo que hace es que se ejecuta cada vez que encuentra un certificado que considera como "malo" y permite que tu código decida si debería permitir la llamada o no. Por defecto tiene 3 parámetros que son:

  1. certificate: que es el objeto representando al certificado.
  2. host: que es el servidor al que estás llamando (ej. https://api.app.com).
  3. port: que es el puerto al que se está consultando (ej. 8080)

Por último, el retorno es un boolean que indica si se acepta el certificado o no.