GithubHelp home page GithubHelp logo

dint-dev / universal_io Goto Github PK

View Code? Open in Web Editor NEW
93.0 4.0 10.0 1.02 MB

Cross-platform 'dart:io', including browser-compatible HttpClient.

Home Page: https://pub.dev/packages/universal_io

License: Apache License 2.0

Dart 100.00%
dart flutter

universal_io's Introduction

Pub Package package publisher Github Actions CI

Overview

A cross-platform dart:io that works on all platforms, including browsers.

You can simply replace dart:io imports with package:universal_io/io.dart.

Licensed under the Apache License 2.0. Some of the source code was derived from Dart SDK, which was obtained under the BSD-style license of Dart SDK. See LICENSE file for details.

APIs added on top of "dart:io"

Other features

The following features may be deprecated in the future versions (3.x) of the package:

  • HttpClient
    • HttpClient() factory is changed so that it returns BrowserHttpClient on browsers.
  • Platform
    • The package makes methods like Platform.isAndroid and Platform.isMacOS work in the browsers too.
  • InternetAddress
    • The package makes it works in the browsers too.
  • BytesBuilder
    • The package makes it works in the browsers too.

Links

Similar packages

Getting started

1.Add dependency

In pubspec.yaml:

dependencies:
  universal_io: ^2.2.2

2.Use HTTP client

import 'package:universal_io/io.dart';

Future<void> main() async {
  // HttpClient can be used in browser too!
  HttpClient httpClient = newUniversalHttpClient(); // Recommended way of creating HttpClient.
  final request = await httpClient.getUrl(Uri.parse("https://dart.dev/"));
  final response = await request.close();
}

HTTP client behavior

HTTP client is implemented with XMLHttpRequest (XHR) API on browsers.

XHR causes the following differences with dart:io:

  • HTTP connection is created only after request.close() has been called.
  • Same-origin policy limitations. For making cross-origin requests, see documentation below.

Helpful error messages

When requests fail and assertions are enabled, error messages contains descriptions how to fix possible issues such as missing cross-origin headers.

The error messages look like the following:

XMLHttpRequest error.
-------------------------------------------------------------------------------
HTTP method:             PUT
HTTP URL:                http://destination.com/example
Origin:                  http://source.com
Cross-origin:            true
browserCredentialsMode:  false
browserResponseType:     arraybuffer

THE REASON FOR THE XHR ERROR IS UNKNOWN.
(For security reasons, browsers do not explain XHR errors.)

Is the server down? Did the server have an internal error?

Enabling credentials mode would enable use of some HTTP headers in both the
request and the response. For example, credentials mode is required for
sending/receiving cookies. If you think you need to enable 'credentials mode',
do the following:

    final httpClientRequest = ...;
    if (httpClientRequest is BrowserHttpClientRequest) {
      httpClientRequest.browserCredentialsMode = true;
    }

Did the server respond to a cross-origin "preflight" (OPTIONS) request?

Did the server send the following headers?
  * Access-Control-Allow-Origin: http://source.com
    * You can also use wildcard ("*").
    * Always required for cross-origin requests!
  * Access-Control-Allow-Methods: PUT
    * You can also use wildcard ("*").

Sometimes when you do cross-origin requests in browsers, you want to use CORS "credentials mode". This can be achieved with the following pattern:

Future<void> main() async {
    final client = HttpClient();
    final request = client.getUrl(Url.parse('http://example/url'));

    // Enable credentials mode
    if (request is BrowserHttpClientRequest) {
      request.browserCredentialsMode = true;
    }

    // Close request
    final response = await request.close();
    // ...
}

Streaming text responses

The underlying XMLHttpRequest (XHR) API supports response streaming only when responseType is "text".

This package automatically uses responseType "text" based on value of the HTTP request header "Accept". These media types are defined BrowserHttpClient.defaultTextMimes:

  • "text/*" (any text media type)
  • "application/grpc-web"
  • "application/grpc-web+proto"

If you want to disable streaming, use the following pattern:

Future<void> main() async {
    final client = newUniversalHttpClient();
    if (client is BrowserHttpClient) {
      client.textMimes = const {};
    }
    // ...
}

universal_io's People

Contributors

bungeefan avatar terrier989 avatar tvolkert avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

universal_io's Issues

Doesn't detect Platform.operatingSystem: iOS [web]

I LOVE your package and need it very much BUT the package from 0.5.0 above somehow cannot detect iOS. The package thinks iPhone and iPad (your package never detected iPad as iOS but as macOS instead) are macOS instead of iOS. Can you please fix it?

Live Demo

You can check the latest version where at least iPhone was detected as iOS which is 0.4.0 here: https://experiment0.web.app/#/: as you can see iPad is still incorrectly detected as macos.

Results in various devices

Safari on iPad mini 2 (iOS 12) universal_io: 0.2.0+ (basically all versions) : I couldn't test versions below 0.2.0 since they were not compatible with Flutter 1.19
WhatsApp Image 2020-07-05 at 14 47 18

Google Chrome on iPhone XR (iOS 13.5) universal_io: 0.5.0-1.0.1 :
IMG_9D5CC53F0329-1

**Safari on iPhone XR (iOS 13.5) universal_io: 0.5.0-

1.0.1 :** (same thing on iPhone 5S (iOS12)
IMG_6A16FE43DE9B-1

The package detects following OS:

  • macOS: as macOS
  • iPad: as macOS
  • iPhone (0.5.0+): as macOS
  • windows: as windows
  • android: as android

Min repro code

Just use the default counter flutter app and add Platform.operatingSystem like this:

import 'package:flutter/material.dart';
import 'package:universal_io/io.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        // This is the theme of your application.
        //
        // Try running your application with "flutter run". You'll see the
        // application has a blue toolbar. Then, without quitting the app, try
        // changing the primarySwatch below to Colors.green and then invoke
        // "hot reload" (press "r" in the console where you ran "flutter run",
        // or simply save your changes to "hot reload" in a Flutter IDE).
        // Notice that the counter didn't reset back to zero; the application
        // is not restarted.
        primarySwatch: Colors.blue,
        // This makes the visual density adapt to the platform that you run
        // the app on. For desktop platforms, the controls will be smaller and
        // closer together (more dense) than on mobile platforms.
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  // This widget is the home page of your application. It is stateful, meaning
  // that it has a State object (defined below) that contains fields that affect
  // how it looks.

  // This class is the configuration for the state. It holds the values (in this
  // case the title) provided by the parent (in this case the App widget) and
  // used by the build method of the State. Fields in a Widget subclass are
  // always marked "final".

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      // This call to setState tells the Flutter framework that something has
      // changed in this State, which causes it to rerun the build method below
      // so that the display can reflect the updated values. If we changed
      // _counter without calling setState(), then the build method would not be
      // called again, and so nothing would appear to happen.
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    // This method is rerun every time setState is called, for instance as done
    // by the _incrementCounter method above.
    //
    // The Flutter framework has been optimized to make rerunning build methods
    // fast, so that you can just rebuild anything that needs updating rather
    // than having to individually change instances of widgets.
    return Scaffold(
      appBar: AppBar(
        // Here we take the value from the MyHomePage object that was created by
        // the App.build method, and use it to set our appbar title.
        title: Text('Platform: ${Platform.operatingSystem}'),
      ),
      body: Center(
        // Center is a layout widget. It takes a single child and positions it
        // in the middle of the parent.
        child: Column(
          // Column is also a layout widget. It takes a list of children and
          // arranges them vertically. By default, it sizes itself to fit its
          // children horizontally, and tries to be as tall as its parent.
          //
          // Invoke "debug painting" (press "p" in the console, choose the
          // "Toggle Debug Paint" action from the Flutter Inspector in Android
          // Studio, or the "Toggle Debug Paint" command in Visual Studio Code)
          // to see the wireframe for each widget.
          //
          // Column has various properties to control how it sizes itself and
          // how it positions its children. Here we use mainAxisAlignment to
          // center the children vertically; the main axis here is the vertical
          // axis because Columns are vertical (the cross axis would be
          // horizontal).
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}
flutter doctor -v
[✓] Flutter (Channel beta, 1.19.0-4.1.pre, on Mac OS X 10.13.6 17G65, locale en-SK)
    • Flutter version 1.19.0-4.1.pre at /Users/tomas/code/flutter
    • Framework revision f994b76974 (4 weeks ago), 2020-06-09 15:53:13 -0700
    • Engine revision 9a28c3bcf4
    • Dart version 2.9.0 (build 2.9.0-14.1.beta)

[✗] Android toolchain - develop for Android devices
    ✗ Unable to locate Android SDK.
      Install Android Studio from: https://developer.android.com/studio/index.html
      On first launch it will assist you in installing the Android SDK components.
      (or visit https://flutter.dev/docs/get-started/install/macos#android-setup for detailed instructions).
      If the Android SDK has been installed to a custom location, set ANDROID_SDK_ROOT to that location.
      You may also want to add it to your PATH environment variable.


[✗] Xcode - develop for iOS and macOS
    ✗ Xcode installation is incomplete; a full installation is necessary for iOS development.
      Download at: https://developer.apple.com/xcode/download/
      Or install Xcode via the App Store.
      Once installed, run:
        sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer
        sudo xcodebuild -runFirstLaunch
    ✗ CocoaPods not installed.
        CocoaPods is used to retrieve the iOS and macOS platform side's plugin code that responds to your plugin usage on the
        Dart side.
        Without CocoaPods, plugins will not work on iOS or macOS.
        For more info, see https://flutter.dev/platform-plugins
      To install:
        sudo gem install cocoapods

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[!] Android Studio (not installed)
    • Android Studio not found; download from https://developer.android.com/studio/index.html
      (or visit https://flutter.dev/docs/get-started/install/macos#android-setup for detailed instructions).

[✓] VS Code (version 1.46.1)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.12.1

[✓] Connected device (2 available)
    • Web Server • web-server • web-javascript • Flutter Tools
    • Chrome     • chrome     • web-javascript • Google Chrome 83.0.4103.116

! Doctor found issues in 3 categories.

Flutter Web : Unable to convert uint8list to File

When I try to convert using universal IO package,Im getting Missing extension byte at 11.Please provide solution to convert uint8list byte to file or please provide solution to download file for flutter web using http client.

import 'package:universal_io/io.dart'; var req = await http.get(uri, headers: headers); var bytes = req.bodyBytes; if (UniversalPlatform.isWeb) { try { File file =File.fromRawPath(bytes); return file; } catch (ex) { print(ex); } }

Exception:FormatException: Missing extension byte (at offset 11)

File object not working with Flutter Web

will socket be supported?

As the title mentioned. I just want use WebSocket in Flutter web application, as we know, dart:html can not be used in Flutter SDK. So guys, I'm counting on you

Error: The argument type 'HttpRequest/*1*/' can't be assigned to the parameter type 'HttpRequest/*2*/'.

I'm trying to do a connection with steam for an app but it give me this error when i try to launch the app
Here is my code and the complete error

import 'package:universal_io/io.dart';
import 'package:steam_login/steam_login.dart';

Future<void> main() async {
  // Bind the HttpServer.
  var server = await HttpServer.bind(
    InternetAddress.loopbackIPv4,
    80,
  );

  // Start listening for HttpRequests.
  server.listen((request) async {
    //Check if the path is '/login'
    if (request.uri.path == '/login') {
      // Create OpenId instance with the current request.
      OpenId openId = OpenId(request);

      // Switch the mode
      switch (openId.mode) {
      // No mode is set
        case '':
          {
            //Redirect the user to the authUrl.
            request.response
              ..redirect(openId.authUrl())
              ..close();
            break;
          }
      // Authentication failed/cancelled.
        case 'cancel':
          {
            request.response
              ..write('Auth cancelled')
              ..close();
            break;
          }
      // Usually mode = 'id_res'.
        default:
          {
            // Validate the authentication and the the steamid64.
            String? steamId = await openId.validate();

            // Save the steamid into the session.
            request.session['steamid'] = steamId;

            // Redirect the user.
            request.response
              ..redirect(Uri.parse('http://localhost'))
              ..close();
          }
      }
    } else {
      // Check if the user is already logged
      if (request.session['steamid'] == null) {
        request.response.write('Go to /login in order to log in!');
      } else {
        // If he's logged in display his steam display name.
        // Get the steamapi key here: https://steamcommunity.com/dev/apikey
        Map<String, dynamic>? summaries = await GetPlayerSummaries(
            request.session['steamid'], 'yoursteamapikey');
        request.response
            .write('Thanks for logging in: ${summaries['personname']}');
      }
      request.response.close();
    }
  });
}
Launching lib/testjson.dart on Chrome in debug mode...
Waiting for connection from debug service on Chrome...
lib/testjson.dart:16:30: Error: The argument type 'HttpRequest/*1*/' can't be assigned to the parameter type 'HttpRequest/*2*/'.
 - 'HttpRequest/*1*/' is from 'package:universal_io/src/http/http.dart' ('../../snap/flutter/common/flutter/.pub-cache/hosted/pub.dartlang.org/universal_io-2.0.4/lib/src/http/http.dart').
 - 'HttpRequest/*2*/' is from 'dart:_http'.
      OpenId openId = OpenId(request);
                             ^
Failed to compile application.

InternetAddress.lookup() is not working on WEB

Hey guys, thank you very much for your work. I am trying to use InternetAddress.lookup() and its not working properly. could you please check it out?

static Future checkInternetConnection() async {
try {
final response = await InternetAddress.lookup("dart.dev");

  if (response.isNotEmpty) {
    return true;
  }

  return false;
} catch (_) {
  return false;
}

}

here is a piece of code.

it works just fine on mobile. The issue is on WEB

Thanks a lot,
Gabriel Duarte

HttpClientRequest.abort() fails silently on web

Hi,
I'm trying to abort ongoing HTTP requests when a new route is pushed on top of the navigator route stack. However, on the web platform the abort() method on HttpClientRequest doesn't seem to cancel the request and doesn't throw.

I could reproduce the issue with the following sample:

import "dart:async";

import "package:flutter/material.dart";
import "package:universal_io/io.dart";

// Set the API URL here
const String baseUrl = "...";
const String endpoint = "...";

void main() {
  testNative();

  runApp(Container(color: Colors.black));
}

void testNative() async {
  final HttpClient client = newUniversalHttpClient();
  final Uri url = Uri.https(baseUrl, endpoint);
  final HttpClientRequest request = await client.postUrl(url);

  Timer(const Duration(milliseconds: 50), () {
    request.abort();

    debugPrint("abort");
  });

  request
      .close()
      .then(
        (_) => debugPrint("then()"),
        onError: (_) => debugPrint("onError()"),
      )
      .catchError(
        (_) => debugPrint("catchError()"),
      );
}

abort() is called before the request done future was completed, but it doesn't complete with an error.

Output of flutter doctor -v:

[✓] Flutter (Channel stable, 3.10.4, on Ubuntu 22.04.2 LTS 5.19.0-43-generic, locale en_US.UTF-8)
    • Flutter version 3.10.4 on channel stable at /home/keole/snap/flutter/common/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 682aa387cf (10 days ago), 2023-06-05 18:04:56 -0500
    • Engine revision 2a3401c9bb
    • Dart version 3.0.3
    • DevTools version 2.23.1

[✗] Android toolchain - develop for Android devices
    ✗ Unable to locate Android SDK.
      Install Android Studio from: https://developer.android.com/studio/index.html
      On first launch it will assist you in installing the Android SDK components.
      (or visit https://flutter.dev/docs/get-started/install/linux#android-setup for detailed instructions).
      If the Android SDK has been installed to a custom location, please use
      `flutter config --android-sdk` to update to that location.


[✓] Chrome - develop for the web
    • Chrome at google-chrome

[✓] Linux toolchain - develop for Linux desktop
    • clang version 10.0.0-4ubuntu1
    • cmake version 3.16.3
    • ninja version 1.10.0
    • pkg-config version 0.29.1

[!] Android Studio (not installed)
    • Android Studio not found; download from https://developer.android.com/studio/index.html
      (or visit https://flutter.dev/docs/get-started/install/linux#android-setup for detailed instructions).

[✓] VS Code (version 1.79.1)
    • VS Code at /usr/share/code
    • Flutter extension version 3.66.0

[✓] VS Code
    • VS Code at /snap/code/current
    • Flutter extension version 3.66.0

[✓] Connected device (2 available)
    • Linux (desktop) • linux  • linux-x64      • Ubuntu 22.04.2 LTS 5.19.0-43-generic
    • Chrome (web)    • chrome • web-javascript • Google Chrome 114.0.5735.133

[✓] Network resources
    • All expected network resources are available.

IOSink for Web

Is it possible to have IOSink implementation for web?

Add a X509Certificate support

Any solutions to add not null X509Certificate in BrowserHttpClientResponseImpl?

@override X509Certificate? get certificate => null;

It's useful for SSL pinning

InternetAddress.lookup produce an error on web

I use the method InternetAddress.lookup from the ConnectionStatusHandler.checkConnection method on the web and it's producing an unimplemented error
and it happens both when I have and when I don't have internet connection
here is the full log:

Error: UnimplementedError
    at Object.throw_ [as throw] (http://localhost:11909/dart_sdk.js:5334:11)
    at Function.lookup (http://localhost:11909/packages/universal_io/src/io/sync_socket.dart.lib.js:3085:24)
    at connection_status_handler.ConnectionStatusHandler._internal.checkConnection (http://localhost:11909/packages/flutter_app/util/connection_status_handler.dart.lib.js:119:64)
    at checkConnection.next (<anonymous>)
    at runBody (http://localhost:11909/dart_sdk.js:39052:34)
    at Object._async [as async] (http://localhost:11909/dart_sdk.js:39083:7)
    at connection_status_handler.ConnectionStatusHandler._internal.checkConnection (http://localhost:11909/packages/flutter_app/util/connection_status_handler.dart.lib.js:116:20)
    at connection_status_handler.ConnectionStatusHandler._internal.initialize (http://localhost:11909/packages/flutter_app/util/connection_status_handler.dart.lib.js:90:12)
    at main$ (http://localhost:11909/packages/flutter_app/game_server/socket_handler.dart.lib.js:196625:24)
    at main$.next (<anonymous>)
    at http://localhost:11909/dart_sdk.js:39032:33
    at _RootZone.runUnary (http://localhost:11909/dart_sdk.js:38889:58)
    at _FutureListener.thenAwait.handleValue (http://localhost:11909/dart_sdk.js:33875:29)
    at handleValueCallback (http://localhost:11909/dart_sdk.js:34435:49)
    at Function._propagateToListeners (http://localhost:11909/dart_sdk.js:34473:17)
    at _Future.new.[_completeWithValue] (http://localhost:11909/dart_sdk.js:34315:23)
    at async._AsyncCallbackEntry.new.callback (http://localhost:11909/dart_sdk.js:34338:35)
    at Object._microtaskLoop (http://localhost:11909/dart_sdk.js:39176:13)
    at _startMicrotaskLoop (http://localhost:11909/dart_sdk.js:39182:13)
    at http://localhost:11909/dart_sdk.js:34689:9

[web] Build error due to wrong types

When I try to build the current version 0.8.6 for web I get the following errors:

Compiler message:
../../.pub-cache/hosted/pub.dartlang.org/universal_io-0.8.6/lib/src/driver_for_browser/browser_http_client_request.dart:22:1: Error:
'BrowserLikeHttpClientRequest' is imported from both 'package:universal_io/src/io/cors_vm.dart' and
'package:universal_io/src/io/cors_browser.dart'.
import 'package:universal_io/src/io/io.dart';                           
^^^^^^^^^^^^^^^^^^^^^^^^^^^^                                            
../../.pub-cache/hosted/pub.dartlang.org/universal_io-0.8.6/lib/src/driver_for_browser/browser_http_client.dart:41:29: Error: The
return type of the method 'BrowserHttpClient.didOpenUrl' is 'Future<HttpClientRequest/*1*/>', which does not match the return type,
'Future<HttpClientRequest/*2*/>', of the overridden method, 'BaseHttpClient.didOpenUrl'.
 - 'Future' is from 'dart:async'.                                       
 - 'HttpClientRequest/*1*/' is from 'package:universal_io/src/io/http/http.dart'
 ('../../.pub-cache/hosted/pub.dartlang.org/universal_io-0.8.6/lib/src/io/http/http.dart').
 - 'HttpClientRequest/*2*/' is from 'dart:_http'.                       
Change to a subtype of 'Future<HttpClientRequest/*2*/>'.                
  Future<HttpClientRequest> didOpenUrl(String method, Uri url) {        
                            ^                                           
../../.pub-cache/hosted/pub.dartlang.org/universal_io-0.8.6/lib/src/driver_base/base_http_client.dart:89:29: Context: This is the
overridden method ('didOpenUrl').
  Future<HttpClientRequest> didOpenUrl(String method, Uri url);         
                            ^                                           
../../.pub-cache/hosted/pub.dartlang.org/universal_io-0.8.6/lib/src/driver_for_browser/browser_http_client_request.dart:52:30: Error:
The return type of the method 'BrowserHttpClientRequest.didClose' is 'Future<HttpClientResponse/*1*/>', which does not match the
return type, 'Future<HttpClientResponse/*2*/>', of the overridden method, 'BaseHttpClientRequest.didClose'.
 - 'Future' is from 'dart:async'.                                       
 - 'HttpClientResponse/*1*/' is from 'package:universal_io/src/io/http/http.dart'
 ('../../.pub-cache/hosted/pub.dartlang.org/universal_io-0.8.6/lib/src/io/http/http.dart').
 - 'HttpClientResponse/*2*/' is from 'dart:_http'.                      
Change to a subtype of 'Future<HttpClientResponse/*2*/>'.               
  Future<HttpClientResponse> didClose() {                               
                             ^                                          
../../.pub-cache/hosted/pub.dartlang.org/universal_io-0.8.6/lib/src/driver_base/base_http_client.dart:303:30: Context: This is the
overridden method ('didClose').
  Future<HttpClientResponse> didClose();                                
                             ^                                          
../../.pub-cache/hosted/pub.dartlang.org/universal_io-0.8.6/lib/src/driver_for_browser/browser_http_client_request.dart:44:26: Error:
The return type of the method 'BrowserHttpClientRequest.connectionInfo' is 'HttpConnectionInfo/*1*/', which does not match the return
type, 'HttpConnectionInfo/*2*/', of the overridden method, 'BaseHttpClientRequest.connectionInfo'.
 - 'HttpConnectionInfo/*1*/' is from 'package:universal_io/src/io/http/http.dart'
 ('../../.pub-cache/hosted/pub.dartlang.org/universal_io-0.8.6/lib/src/io/http/http.dart').
 - 'HttpConnectionInfo/*2*/' is from 'dart:_http'.                      
Change to a subtype of 'HttpConnectionInfo/*2*/'.                       
  HttpConnectionInfo get connectionInfo => null;                        
                         ^                                              
../../.pub-cache/hosted/pub.dartlang.org/universal_io-0.8.6/lib/src/driver_base/base_http_client.dart:214:26: Context: This is the
overridden method ('connectionInfo').
  HttpConnectionInfo get connectionInfo => null;                        
                         ^              

It seems due to wrongly typed variables. Any fix available?

BrowserHttpClientRequest::addStream() fails with "StreamSink is bound to a stream"

When using the browser version of HttpClientRequest and calling addStream() it fails with the following error message:

StateError: StreamSink is bound to a stream

@override
Future<void> addStream(Stream<List<int>> stream) async {
if (_completer.isCompleted) {
throw StateError('StreamSink is closed');
}
if (_addStreamFuture != null) {
throw StateError('StreamSink is bound to a stream');
}
final future = stream.listen((item) {
add(item);
}, onError: (error) {
addError(error);
}, cancelOnError: true).asFuture(null);
_addStreamFuture = future;
await future;
_addStreamFuture = null;
return null;
}

addStream() checks and sets _addStreamFuture and while listening to the stream calling add() which again checks for _addStreamFuture, resulting in the state error.

@override
void add(List<int> event) {
if (!_supportsBody) {
throw StateError('HTTP method $method does not support body');
}
if (_completer.isCompleted) {
throw StateError('StreamSink is closed');
}
if (_addStreamFuture != null) {
throw StateError('StreamSink is bound to a stream');
}
_buffer.addAll(event);
}

File file = File(path); not work by uses universal_io but work by uses dart:io. What I should do?

flutter doctor

[√] Flutter (Channel stable, 2.0.4, on Microsoft Windows [Version 10.0.19042.906], locale en-US)
• Flutter version 2.0.4 at C:\flutter
• Framework revision b1395592de (10 days ago), 2021-04-01 14:25:01 -0700
• Engine revision 2dce47073a
• Dart version 2.12.2

[√] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
• Android SDK at C:\Users\sitti\AppData\Local\Android\Sdk
• Platform android-30, build-tools 30.0.3
• Java binary at: C:\Program Files\Android\Android Studio\jre\bin\java
• Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b01)
• All Android licenses accepted.

[√] Chrome - develop for the web
• Chrome at C:\Program Files\Google\Chrome\Application\chrome.exe

[√] Android Studio (version 4.1.0)
• Android Studio at C:\Program Files\Android\Android Studio
• Flutter plugin can be installed from:
https://plugins.jetbrains.com/plugin/9212-flutter
• Dart plugin can be installed from:
https://plugins.jetbrains.com/plugin/6351-dart
• Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b01)

[√] VS Code (version 1.55.0)
• VS Code at C:\Users\sitti\AppData\Local\Programs\Microsoft VS Code
• Flutter extension can be installed from:
https://marketplace.visualstudio.com/items?itemName=Dart-Code.flutter

[√] Connected device (2 available)
• Chrome (web) • chrome • web-javascript • Google Chrome 89.0.4389.114
• Edge (web) • edge • web-javascript • Microsoft Edge 89.0.774.75

• No issues found!

universal_io ignores ContentType parameters

The copied ContentType implementation ignores the given parameters and therefore things like "boundary" don't work in browsers.

Original code which would be needed:
https://github.com/dart-lang/sdk/blob/36e8d9ab6fbfbc148a41fd9baa75b7ab8dd4aa9b/sdk/lib/_http/http_headers.dart#L902-L912

Is missing here:

_ContentType(String primaryType, String subType, String? charset,
Map<String, String?> parameters)
: _primaryType = primaryType,
_subType = subType,
super('') {
// TODO(40614): Remove once non-nullability is sound.
String emptyIfNull(String? string) => string ?? '';
_primaryType = emptyIfNull(_primaryType);
_subType = emptyIfNull(_subType);
_value = '$_primaryType/$_subType';
// TODO(40614): Remove once non-nullability is sound.
if (charset != null) {
_ensureParameters()['charset'] = charset.toLowerCase();
}
}

credentialsMode argument missing

Hi I tried implementing your below example but it says that there is no setter. Please suggest a solution

`
final request = HttpClient().getUrl(Uri.parse('https://example.com/path'));

if (request is BrowserHttpClientRequest) {
request.credentialsMode = BrowserHttpClientCredentialsMode.include;
}

final response = await request.close();
`

It's not working for web builds

I get this error during compil time import 'package:universal_io/io.dart';

Compiler message:
/Users/hackerhgl/.pub-cache/hosted/pub.dartlang.org/universal_io-1.0.0/lib/src/io_impl_js/overrides.dart:81:29: Error: A value of type 'IOOverrides/*1*/' can't be assigned to a variable of type 'IOOverrides/*2*/'.
 - 'IOOverrides/*1*/' is from 'dart:io'.
 - 'IOOverrides/*2*/' is from 'package:universal_io/src/io_impl_js/overrides.dart' ('/Users/hackerhgl/.pub-cache/hosted/pub.dartlang.org/universal_io-1.0.0/lib/src/io_impl_js/overrides.dart').
    return IODriver.current.ioOverrides;
                            ^
/Users/hackerhgl/.pub-cache/hosted/pub.dartlang.org/universal_io-1.0.0/lib/src/io_impl_js/overrides.dart:92:20: Error: The argument type 'IOOverrides/*1*/' can't be assigned to the parameter type 'IOOverrides/*2*/'.
 - 'IOOverrides/*1*/' is from 'package:universal_io/src/io_impl_js/overrides.dart' ('/Users/hackerhgl/.pub-cache/hosted/pub.dartlang.org/universal_io-1.0.0/lib/src/io_impl_js/overrides.dart').
 - 'IOOverrides/*2*/' is from 'dart:io'.
      ioOverrides: overrides,
                   ^
/Users/hackerhgl/.pub-cache/hosted/pub.dartlang.org/universal_io-1.0.0/lib/src/io_impl_js/overrides.dart:198:24: Error: The argument type 'IOOverrides/*1*/' can't be assigned to the parameter type 'IOOverrides/*2*/'.
 - 'IOOverrides/*1*/' is from 'package:universal_io/src/io_impl_js/overrides.dart' ('/Users/hackerhgl/.pub-cache/hosted/pub.dartlang.org/universal_io-1.0.0/lib/src/io_impl_js/overrides.dart').
 - 'IOOverrides/*2*/' is from 'dart:io'.
          ioOverrides: overrides,
                       ^
/Users/hackerhgl/.pub-cache/hosted/pub.dartlang.org/universal_io-1.0.0/lib/src/driver/driver_impl_js.dart:68:19: Error: The argument type 'IODriver/*1*/' can't be assigned to the parameter type 'IODriver/*2*/'.
 - 'IODriver/*1*/' is from 'package:universal_io/src/driver/driver_impl_vm.dart' ('/Users/hackerhgl/.pub-cache/hosted/pub.dartlang.org/universal_io-1.0.0/lib/src/driver/driver_impl_vm.dart').
 - 'IODriver/*2*/' is from 'package:universal_io/src/driver/driver_impl_js.dart' ('/Users/hackerhgl/.pub-cache/hosted/pub.dartlang.org/universal_io-1.0.0/lib/src/driver/driver_impl_js.dart').
    defaultValue: defaultIODriver,
                  ^
/Users/hackerhgl/.pub-cache/hosted/pub.dartlang.org/universal_io-1.0.0/lib/src/driver/default_impl_browser.dart:40:30: Error: The class 'NetworkInterfaceOverrides' is abstract and can't be instantiated.
  networkInterfaceOverrides: NetworkInterfaceOverrides(),

When I import package from import 'package:universal_io/prefer_universal/io.dart'; app compiles successfully but I get Javascript error in chrome console.

dart_sdk.js:5291 Uncaught (in promise) Error: Unsupported operation: Platform._operatingSystem
    at Object.throw_ [as throw] (dart_sdk.js:4011)
    at Function._operatingSystem (dart_sdk.js:56675)
    at Function.get operatingSystem [as operatingSystem] (dart_sdk.js:56724)
    at get _operatingSystem (dart_sdk.js:56637)
    at Function.desc.get [as _operatingSystem] (dart_sdk.js:5037)
    at get isLinux (dart_sdk.js:56649)
    at Function.desc.get [as isLinux] (dart_sdk.js:5037)
    at Object.main$ [as main] (main.dart:10)
    at main$ (web_entrypoint.dart:8)
    at main$.next (<anonymous>)
    at onValue (dart_sdk.js:41054)
    at _RootZone.runUnary (dart_sdk.js:40940)
    at _FutureListener.thenAwait.handleValue (dart_sdk.js:36685)
    at handleValueCallback (dart_sdk.js:37185)
    at Function._propagateToListeners (dart_sdk.js:37217)
    at async._AsyncCallbackEntry.new.callback (dart_sdk.js:36973)
    at Object._microtaskLoop (dart_sdk.js:41153)
    at _startMicrotaskLoop (dart_sdk.js:41159)
    at dart_sdk.js:37420

Here's my flutter doctor logs:

[✓] Flutter (Channel master, v1.15.4-pre.134, on Mac OS X 10.15.3 19D76, locale en-PK)
 
[✓] Android toolchain - develop for Android devices (Android SDK version 29.0.1)
[✓] Xcode - develop for iOS and macOS (Xcode 11.3.1)
[✓] Chrome - develop for the web
[!] Android Studio (version 3.5)
    ✗ Flutter plugin not installed; this adds Flutter specific functionality.
    ✗ Dart plugin not installed; this adds Dart specific functionality.
[✓] VS Code (version 1.42.1)
[✓] Connected device (3 available)

Dart version:
Dart VM version: 2.7.1 (Thu Jan 23 13:02:26 2020 +0100) on "macos_x64"

The multiple set-cookie headers case is not handled properly for browser case

Several flutter libraries including this one don't take care of cases where there are more than one set-cookie headers. In fact, not even one of the set-cookie headers is present in the response headers and also in cookies attribute. Things work fine on iOS. I see same behaviour with dart http and dio package.

The InternetAddress.type parameter is missing

From Dart 2.8, the InternetAddress constructor in dart:io has a optional named parameter InternetAddressType type, which is missing in universal_io 1.0.1.

Cfr socket.dart in dart:io:

external factory InternetAddress(String address,
      {@Since("2.8") InternetAddressType type});

OSError not extending Exception in universal_io

Hi!

I encountered an issue when using this package as a replacement for dart:io for web. The class OSError does not extend Exception in universal_io, while in dart:io it does extend Exception. Since message is already a property, it seems it's just a matter of replacing line 55 in lib/src/io/exceptions.dart:

class OSError {
with
class OSError implements Exception {

OSError already has a message property, so, this is basically it. But maybe I'm missing something here?

Best regards,

Mark

The argument type 'File/*1*/' can't be assigned to the parameter type 'File/*2*/'.

Latest version of universal_io

$ flutter run -d chrome
Launching lib/main.dart on Chrome in debug mode...
lib/myapp/pages/profile/profile_image_edit_page.dart:148:76: Error: The argument type 'File/*1*/' can't be assigned to the parameter type 'File/*2*/'.
 - 'File/*1*/' is from 'package:universal_io/src/io/file.dart'
 ('/usr/local/Caskroom/flutter/1.22.6/flutter/.pub-cache/hosted/pub.dartlang.org/universal_io-2.0.0/lib/src/io/file.dart').
 - 'File/*2*/' is from 'dart:io'.
                    var storageUploadTask = await storageReference.putFile(profileImage);
                                                                           ^
lib/myapp/pages/profile/profile_image_edit_page.dart:215:57: Error: The argument type 'File/*1*/' can't be assigned to the parameter type 'File/*2*/'.
 - 'File/*1*/' is from 'package:universal_io/src/io/file.dart'
 ('/usr/local/Caskroom/flutter/1.22.6/flutter/.pub-cache/hosted/pub.dartlang.org/universal_io-2.0.0/lib/src/io/file.dart').
 - 'File/*2*/' is from 'dart:io'.
                          child: Image(image: FileImage(profileImage), fit: BoxFit.fitHeight),

The argument type 'File/*1*/' can't be assigned to the parameter type 'File/*2*/'.

This issue is still not fixed in the latest version i.e 2.0.4

flutter run -d chrome

Launching lib\main.dart on Chrome in debug mode...
lib/screens/myprofilescreen.dart:93:51: Error: The argument type 'File/1/' can't be assigned to the parameter type
'File/2/'.

  • 'File/1/' is from 'package:universal_io/src/io/file.dart'
    ('/D:/flutter/.pub-cache/hosted/pub.dartlang.org/universal_io-2.0.4/lib/src/io/file.dart').
  • 'File/2/' is from 'dart:io'.
    : new FileImage(_imageFile),
    ^
    lib/screens/CreatePostScreen.dart:163:46: Error: The argument type 'File/1/' can't be assigned to the parameter type
    'File/2/'.
  • 'File/1/' is from 'package:universal_io/src/io/file.dart'
    ('/D:/flutter/.pub-cache/hosted/pub.dartlang.org/universal_io-2.0.4/lib/src/io/file.dart').
  • 'File/2/' is from 'dart:io'.
    child: _image != null ? Image.file(_image) : null,
    ^
    lib/screens/EditPostScreen.dart:155:46: Error: The argument type 'File/1/' can't be assigned to the parameter type
    'File/2/'.
  • 'File/1/' is from 'package:universal_io/src/io/file.dart'
    ('/D:/flutter/.pub-cache/hosted/pub.dartlang.org/universal_io-2.0.4/lib/src/io/file.dart').
  • 'File/2/' is from 'dart:io'.
    child: _image != null ? Image.file(File(_image.path)) : null,

Change of Copyright notice

Hello! According to the Appendix of Apache License 2.0, if you want to license your software under this License you should "attach the boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information". This condition is not met now. Please add a copyright notice in the appropriate form, including the year of the software development and your name and surname. Thank you in advance

Copyright [yyyy] [name of copyright owner]

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

Web support

It doesn't mention "web" in the supported platforms on pub.dev. Even though I can see some open issues related to using this package on the web, I believe this is supported on the web. Please add web to the supported platforms, so people don't just skip this package before using it because of that.

window is not defined

Awesome job with this package. :D

I'm trying to use it in a nodejs env with Cloud Functions, but I get window is not defined. It seems like _BrowserHttpOverrides and such are included. Any ideas on how to overcome this?

FormatException

I have a Uint8List i want to create a filepath . But i'm getting Error: FormatException: Invalid UTF-8 byte (at offset 0)

Uint8List unit8List;
uio.File createFileFromUint8List(Uint8List uint8list) => uio.File.fromRawPath(uint8list);

Can someone tell me how to resolve this ?

Grpc Web

Have you tested if your fork supports grpc web inside a web browser ? I always thought the lack of frames support prevented this

[Question] Not sure to understand how web support works

Something is not clear for me about the web support. I will take an example to explain.
If I have a mobile application that download and saves file on local storage with dart.io, and if I replace all the imports of dart.io by universal_io to make it compatible with web, how would it behave on borwser, would it save the downloaded files on local web storage ?

Compile Error: File argument type assignment error while using video_player plugin

Seeing the below error at compilation for web. Below are the details. pls let me know if any more info is needed.

Error

: Error: The argument type 'File/*1*/' can't be assigned to the parameter type 'File/*2*/'.
lib/main.dart:8
- 'File/*1*/' is from 'package:universal_io/src/io/file.dart' ('/home/ravi/snap/flutter/common/flutter/.pub-cache/hosted/pub.dartlang.org/universal_io-2.0.4/lib/src/io/file.dart').
package:universal_io/…/io/file.dart:1
 - 'File/*2*/' is from 'dart:io'.
    VideoPlayerController.file(File('a non existent file'));
                               ^

Failed to compile application.

Minimal code to recreate the issue

//@dart=2.9

import 'package:universal_io/io.dart';
import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';

VideoPlayerController vpc =
    VideoPlayerController.file(File('a non existent file'));

void main() {
  runApp(Container());
}

flutter doctor -v

flutter doctor -v
[✓] Flutter (Channel stable, 2.5.2, on Ubuntu 20.04.2 LTS 5.4.0-89-generic, locale en_US.UTF-8)
    • Flutter version 2.5.2 at /home/ravi/snap/flutter/common/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 3595343e20 (4 weeks ago), 2021-09-30 12:58:18 -0700
    • Engine revision 6ac856380f
    • Dart version 2.14.3

[✓] Android toolchain - develop for Android devices (Android SDK version 31.0.0)
    • Android SDK at /home/ravi/Android/Sdk/
    • Platform android-31, build-tools 31.0.0
    • Java binary at: /usr/local/android-studio/jre/bin/java
    • Java version OpenJDK Runtime Environment (build 11.0.10+0-b96-7249189)
    • All Android licenses accepted.

[✓] Chrome - develop for the web
    • Chrome at google-chrome

[✓] Android Studio (version 2020.3)
    • Android Studio at /usr/local/android-studio
    • Flutter plugin version 61.2.2
    • Dart plugin version 203.8430
    • Java version OpenJDK Runtime Environment (build 11.0.10+0-b96-7249189)

[✓] VS Code (version 1.61.0)
    • VS Code at /usr/share/code
    • Flutter extension version 3.27.0

[✓] Connected device (2 available)
    • Pixel 4a (mobile) • 192.168.1.6:5555 • android-arm64  • Android 11 (API 30)
    • Chrome (web)      • chrome           • web-javascript • Google Chrome 93.0.4577.63
    ! Device emulator-5554 is offline.

• No issues found!

pubspec dependencies

dependencies:
  flutter:
    sdk: flutter
  video_player: ^2.2.5
  universal_io:

A value of type 'SecurityContext/*1*/' can't be assigned to a variable of type 'SecurityContext/*2*/'

Hi!

I'm building my project for web and I have an error with SecurtyContext but no idea how to resolve it because it is complaining about types.

Target dart2js failed: Exception: lib/courier/bloc/courier_bloc.dart:78:32:
Error: A value of type 'SecurityContext/*1*/' can't be assigned to a variable of type 'SecurityContext/*2*/'.
 - 'SecurityContext/*1*/' is from 'package:universal_io/src/io_impl_js/security_context.dart'
 ('../../flutter/.pub-cache/hosted/pub.dartlang.org/universal_io-1.0.1/lib/src/io_impl_js/security_context.dart').
 - 'SecurityContext/*2*/' is from 'dart:io'.
      client.securityContext = securityContext;
                               ^
lib/location/bloc/delivery_location_bloc.dart:65:32:
Error: A value of type 'SecurityContext/*1*/' can't be assigned to a variable of type 'SecurityContext/*2*/'.
 - 'SecurityContext/*1*/' is from 'package:universal_io/src/io_impl_js/security_context.dart'
 ('../../flutter/.pub-cache/hosted/pub.dartlang.org/universal_io-1.0.1/lib/src/io_impl_js/security_context.dart').
 - 'SecurityContext/*2*/' is from 'dart:io'.
      client.securityContext = securityContext;
                               ^

IOOverrides.current always null on web

Causes issue #16 or equivalent
ie. it doesn't look like any filesystem call can work on the web
It looks like the intent is for us to use "IOOverrides.runZoned..."
However, the methods in _IOOverridesScope are null so that also generates UnimplementedError

Install page contains deprecated code

The install page is talking about importing

import 'package:universal_io/prefer_sdk/io.dart';
import 'package:universal_io/prefer_universal/io.dart';

image

that are deprecated as far as the IDE tells me

image

Should I open pull request to remove them ?

"Error: UnimplementedError" when trying in initialize Directory in Flutter app.

As stated above.

Below is my main.dart.


import 'package:flutter/material.dart';

final dir = Directory('../assets');
String fileListString = '';

Future<void> main() async {
  List<FileSystemEntity> fileList = await dir.list().toList();
  fileListString = fileList.map((e) => e.path).join(',');

  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  static const String _title = 'Flutter Code Sample';

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      title: _title,
      home: MyStatefulWidget(),
    );
  }
}

class MyStatefulWidget extends StatefulWidget {
  const MyStatefulWidget({super.key});

  @override
  State<MyStatefulWidget> createState() => _MyStatefulWidgetState();
}

class _MyStatefulWidgetState extends State<MyStatefulWidget> {
  int _count = 0;

  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.white,
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          AnimatedSwitcher(
            duration: const Duration(milliseconds: 500),
            transitionBuilder: (Widget child, Animation<double> animation) {
              return RotationTransition(turns: animation, child: child);
            },
            switchOutCurve: Curves.easeInOutCubic,
            switchInCurve: Curves.easeInOutCubic,
            child: Text(
              '$_count',
              // This key causes the AnimatedSwitcher to interpret this as a "new"
              // child each time the count changes, so that it will begin its animation
              // when the count changes.
              key: ValueKey<int>(_count),
              style: Theme.of(context).textTheme.headline4,
            ),
          ),
          ElevatedButton(
            child: const Text('Increment'),
            onPressed: () {
              setState(() {
                _count += 1;
              });
            },
          ),
          Text(fileListString)
        ],
      ),
    );
  }
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.