flutter_inappwebview refused local https connection in flutter app


Toufic Zayed

I'm trying to serve local content from assets over https in order to gain access to features like webrtc that require SSL.

Since the local app server provided in flutter_inappwebview cannot handle ssl connections, I replaced the InAppLocalHostServer class with InAppLocalHostSecureServer with the following code:

import 'dart:io';
import 'dart:async';

import 'package:flutter/services.dart' show rootBundle;
import 'package:mime/mime.dart';

class InAppLocalHostSecureServer {
  HttpServer _server;
  int _port = 8443;

  InAppLocalHostSecureServer({int port = 8443}) {
    this._port = port;
  }

  ///Starts a server on http://localhost:[port]/.
  ///
  ///**NOTE for iOS**: For the iOS Platform, you need to add the `NSAllowsLocalNetworking` key with `true` in the `Info.plist` file (See [ATS Configuration Basics](https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CocoaKeys.html#//apple_ref/doc/uid/TP40009251-SW35)):
  ///```xml
  ///<key>NSAppTransportSecurity</key>
  ///<dict>
  ///    <key>NSAllowsLocalNetworking</key>
  ///    <true/>
  ///</dict>
  ///```
  ///The `NSAllowsLocalNetworking` key is available since **iOS 10**.
  Future<void> start() async {
    if (this._server != null) {
      throw Exception('Server already started on https://localhost:$_port');
    }

    var completer = Completer();

    runZoned(() async {
      SecurityContext context = new SecurityContext();
      var chain = await rootBundle.load('assets/certificates/cert.pem');
      var key = await rootBundle.load('assets/certificates/key.pem');
      context.useCertificateChainBytes(chain.buffer.asInt8List());
      context.usePrivateKeyBytes(key.buffer.asInt8List(), password: 'dartdart');

      HttpServer.bindSecure('127.0.0.1', _port, context).then((server) {
        print('Server running on https://localhost:' + _port.toString());

        this._server = server;

        server.listen((HttpRequest request) async {
          print(request);
          var body = List<int>();
          var path = request.requestedUri.path;
          path = (path.startsWith('/')) ? path.substring(1) : path;
          path += (path.endsWith('/')) ? 'index.html' : '';

          try {
            body = (await rootBundle.load(path)).buffer.asUint8List();
          } catch (e) {
            print(e.toString());
            request.response.close();
            return;
          }

          var contentType = ['text', 'html'];
          if (!request.requestedUri.path.endsWith('/') &&
              request.requestedUri.pathSegments.isNotEmpty) {
            var mimeType =
                lookupMimeType(request.requestedUri.path, headerBytes: body);
            if (mimeType != null) {
              contentType = mimeType.split('/');
            }
          }

          request.response.headers.contentType =
              ContentType(contentType[0], contentType[1], charset: 'utf-8');
          request.response.add(body);
          request.response.close();
        });

        completer.complete();
      });
    }, onError: (e, stackTrace) {
      print('Error: $e $stackTrace');
    });

    return completer.future;
  }

  ///Closes the server.
  Future<void> close() async {
    if (this._server != null) {
      await this._server.close(force: true);
      print('Server running on http://localhost:$_port closed');
      this._server = null;
    }
  }
}

Most of the code is a copy-paste of the original class.

What I changed was that I called HttpServer.bindSecure instead of HttpServer.bind and provided the openssl certificate and key.

There doesn't seem to be an error logged in the console when the server starts, but I can't access it.

Here is the client code trying to access the local URL:


import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'InAppLocalHostSecureServer.dart';

class WebAudioTest extends StatefulWidget {
  @override
  _WebAudioTestState createState() => _WebAudioTestState();
}

class _WebAudioTestState extends State<WebAudioTest> {
  InAppWebViewController webView;
  InAppLocalHostSecureServer localhostServer;
  String url = "https://127.0.0.1:8443/assets/web/index.html";

  @override
  void initState() {
    super.initState();
    this.init();
  }

  void init() async {
    this.localhostServer = new InAppLocalHostSecureServer();
    await localhostServer.start();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Web Audio Test'),
      ),
      body: InAppWebView(
        initialUrl: url,
        initialHeaders: {},
        initialOptions: InAppWebViewGroupOptions(
            crossPlatform: InAppWebViewOptions(
          debuggingEnabled: true,
        )),
        onWebViewCreated: (InAppWebViewController c) {
          webView = c;
        },
        onConsoleMessage: (controller, consoleMessage) {
          print("CONSOLE MESSAGE: " + consoleMessage.message);
        },
      ),
    );
  }
}

No errors are shown in the console, but the page is cluttered with the following error message:

净:: ERR_CONNECTION_REFUSED

Any help is welcome.

Toufic Zayed

Well, to answer my own question:

The problem I'm having is simply building the InAppWebView prematurely before the server startup is complete. The solution is simple, just set the flag to true when starting the server, then create the InAppWebView only when the flag is true.

Other than that, WebRTC works without https on localhost, I tested it on Android and iOS. So local https is not required for this use case.

But anyway, if you need someone to serve https native content for any other reason, the code in this article can serve as a basis for that.

Related


Appwrite with Flutter [Connection refused]

lzb2976a I just tried Flutter's appwrite platform, but this happens after any request I've tried. Server initialized at http://localhost:300 (or https://localhost:301 ) , endpoint = http://localhost:300/v1 static Future<void> init() async { _client = Client(

Nginx HTTPS connection refused

Japiyo I can't get SSL to work with my Nginx installation. I found several other questions related to this, but they didn't solve my problem. Checks I did: nginx -tno error returned ufw disableLet all traffic trough netstat -nltptell me tcp:0.0.0.0:80and tcp:0

Nginx HTTPS connection refused

Japiyo I can't get SSL to work with my Nginx installation. I found several other questions related to this, but they didn't solve my problem. Checks I did: nginx -tno error returned ufw disableLet all traffic trough netstat -nltptell me tcp:0.0.0.0:80and tcp:0

Nginx HTTPS connection refused

Japiyo I can't get SSL to work with my Nginx installation. I found several other questions related to this, but they didn't solve my problem. Checks I did: nginx -tno error returned ufw disableLet all traffic trough netstat -nltptell me tcp:0.0.0.0:80and tcp:0

Nginx HTTPS connection refused

Japiyo I can't get SSL to work with my Nginx installation. I found several other questions related to this, but they didn't solve my problem. Checks I did: nginx -tno error returned ufw disableLet all traffic trough netstat -nltptell me tcp:0.0.0.0:80and tcp:0

Nginx HTTPS connection refused

Japiyo I can't get SSL to work with my Nginx installation. I found several other questions related to this, but they didn't solve my problem. Checks I did: nginx -tno error returned ufw disableLet all traffic trough netstat -nltptell me tcp:0.0.0.0:80and tcp:0

Flutter SocketException: OS Error: Connection refused, errno=111

Exusia In my code I am trying to use to Image.network()access this link: https://raw.githubusercontent.com/KZGlobalTeam/map-images/public/thumbnails/kz_ladderall.jpg I found that I have this exception because the site rejected me of the emulator, while other l

Mod_wsgi https error Connection refused

Freestyle076 My team is developing a REST API to support an iPhone application using Django's REST framework. It's time for us to transition from hosting via the development WSGI interface to the mod_wsgi apache interface. We have decided to use mod_wsgi-httpd

Mod_wsgi https error Connection refused

Freestyle076 My team is developing a REST API to support an iPhone application using Django's REST framework. It's time for us to transition from hosting via the development WSGI interface to the mod_wsgi apache interface. We have decided to use mod_wsgi-httpd

Check if an internet connection is available on the Flutter app

Rissmon Suresh: I have a VoIP call to perform. But before that I need to check if the device has internet connection. Here's what I've done so far: var connectivityResult = new Connectivity().checkConnectivity();// User defined class if (connectivityResu

Check if an internet connection is available on the Flutter app

Rissmon Suresh: I have a VoIP call to perform. But before that I need to check if the device has internet connection. Here's what I've done so far: var connectivityResult = new Connectivity().checkConnectivity();// User defined class if (connectivityResu

Check if an internet connection is available on the Flutter app

Rissmon Suresh: I have a VoIP call to perform. But before that I need to check if the device has internet connection. Here's what I've done so far: var connectivityResult = new Connectivity().checkConnectivity();// User defined class if (connectivityResu

CodePipeline + Beanstalk connection refused React + Express app

A13X I'll explain in detail below: Target A React front-end game for socket.iotransferring game state data between players on Express servers. set up I decided to move to CodePipeline + CodeDeploy to Beanstalk after finding out that putting both React/Express

create react app unexpected connection refused

Specialty I keep getting the following error when I try to simply create a new react app. I even set up fiddler on my computer and set the proxy to work with it, but I still get the following error: Deny use of 13.107.6.183:443 Click here to view the full log

CodePipeline + Beanstalk connection refused React + Express app

A13X I'll explain in detail below: Target A React front-end game for socket.iotransferring game state data between players on Express servers. set up I decided to move to CodePipeline + CodeDeploy to Beanstalk after finding out that putting both React/Express

Android app connecting to REST service - connection refused

Krishna Chaitanya I'm developing an Android app that involves calling a RESTful API. I have a REST service written in Python running on a laptop ( ) on 192.168.156.1port 8080 . I tethered the phone to the laptop via the Connectify Wifi connection. The phone is

Connection refused error on Google Chrome for Web app

Yasha I am using Sunone 6.1 and Glassfish 3.1.2 web server to run my application. My application works fine on Internet Explorer, but on Google Chrome I get the error "Connection refused" without further details. I connect to the server using localhost and por

CodePipeline + Beanstalk connection refused React + Express app

A13X I'll explain in detail below: Target A React front-end game for socket.iotransferring game state data between players on Express servers. set up I decided to move to CodePipeline + CodeDeploy to Beanstalk after finding out that putting both React/Express

create react app unexpected connection refused

Specialty I keep getting the following error when I try to simply create a new react app. I even set up fiddler on my computer and set the proxy to work with it, but I still get the following error: Deny use of 13.107.6.183:443 Click here to view the full log

CodePipeline + Beanstalk connection refused React + Express app

A13X I'll explain in detail below: Target A React front-end game for socket.iotransferring game state data between players on Express servers. set up I decided to move to CodePipeline + CodeDeploy to Beanstalk after finding out that putting both React/Express

CodePipeline + Beanstalk connection refused React + Express app

A13X I'll explain in detail below: Target A React front-end game for socket.iotransferring game state data between players on Express servers. set up I decided to move to CodePipeline + CodeDeploy to Beanstalk after finding out that putting both React/Express

Connection refused error on Google Chrome for Web app

Yasha I am using Sunone 6.1 and Glassfish 3.1.2 web server to run my application. My application works fine on Internet Explorer, but on Google Chrome I get the error "Connection refused" without further details. I connect to the server using localhost and por

Android app connecting to REST service - connection refused

Krishna Chaitanya I'm developing an Android app that involves calling a RESTful API. I have a REST service written in Python running on a laptop ( ) on 192.168.156.1port 8080 . I tethered the phone to the laptop via the Connectify Wifi connection. The phone is