wendux 3 years ago
parent
commit
71b38981bb

+ 6 - 6
README-ZH.md

@@ -14,7 +14,7 @@ dio是一个强大的Dart Http请求库,支持Restful API、FormData、拦截
 
 ```yaml
 dependencies:
-  dio: ^4.0.0 
+  dio: ^4.0.1
 ```
 
 > 如果你是dio 3.x 用户,想了解4.0的变更,请参考 [4.x更新列表](./migration_to_4.x.md)!
@@ -329,7 +329,7 @@ response = await dio.request(
 Response response = await dio.get('https://www.google.com');
 print(response.data);
 print(response.headers);
-print(response.request);
+print(response.requestOptions);
 print(response.statusCode);
 ```
 
@@ -375,12 +375,12 @@ class CustomInterceptors extends Interceptor {
   }
   @override
   Future onResponse(Response response, ResponseInterceptorHandler handler) {
-    print('RESPONSE[${response.statusCode}] => PATH: ${response.request?.path}');
+    print('RESPONSE[${response.statusCode}] => PATH: ${response.requestOptions?.path}');
     return super.onResponse(response, handler);
   }
   @override
   Future onError(DioError err, ErrorInterceptorHandler handler) {
-    print('ERROR[${err.response?.statusCode}] => PATH: ${err.request.path}');
+    print('ERROR[${err.response?.statusCode}] => PATH: ${err.requestOptions?.path}');
     return super.onError(err, handler);
   }
 }
@@ -500,10 +500,10 @@ try {
   if (e.response) {
     print(e.response.data)
     print(e.response.headers)
-    print(e.response.request)
+    print(e.response.requestOptions)
   } else {
     // Something happened in setting up or sending the request that triggered an Error
-    print(e.request)
+    print(e.requestOptions)
     print(e.message)
   }
 }

+ 6 - 6
README.md

@@ -12,7 +12,7 @@ A powerful Http client for Dart, which supports Interceptors, Global configurati
 
 ```yaml
 dependencies:
-  dio: ^4.0.0
+  dio: ^4.0.1
 ```
 > Already know Dio 3 and just want to learn about what's new in Dio 4? Check out the [Migration Guide](./migration_to_4.x.md)!
 
@@ -351,7 +351,7 @@ When request is succeed, you will receive the response as follows:
 Response response = await dio.get('https://www.google.com');
 print(response.data);
 print(response.headers);
-print(response.request);
+print(response.requestOptions);
 print(response.statusCode);
 ```
 
@@ -397,12 +397,12 @@ class CustomInterceptors extends Interceptor {
   }
   @override
   Future onResponse(Response response, ResponseInterceptorHandler handler) {
-    print('RESPONSE[${response.statusCode}] => PATH: ${response.request?.path}');
+    print('RESPONSE[${response.statusCode}] => PATH: ${response.requestOptions.path}');
     return super.onResponse(response, handler);
   }
   @override
   Future onError(DioError err, ErrorInterceptorHandler handler) {
-    print('ERROR[${err.response?.statusCode}] => PATH: ${err.request.path}');
+    print('ERROR[${err.response?.statusCode}] => PATH: ${err.requestOptions.path}');
     return super.onError(err, handler);
   }
 }
@@ -519,10 +519,10 @@ try {
   if (e.response) {
     print(e.response.data)
     print(e.response.headers)
-    print(e.response.request)
+    print(e.response.requestOptions)
   } else {
     // Something happened in setting up or sending the request that triggered an Error
-    print(e.request)
+    print(e.requestOptions)
     print(e.message)
   }
 }

+ 30 - 4
analysis_options.yaml

@@ -1,4 +1,30 @@
-include: package:pedantic/analysis_options.yaml
-analyzer:
-  enable-experiment:
-  - non-nullable
+# This file configures the analyzer, which statically analyzes Dart code to
+# check for errors, warnings, and lints.
+#
+# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
+# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
+# invoked from the command line by running `flutter analyze`.
+
+# The following line activates a set of recommended lints for Flutter apps,
+# packages, and plugins designed to encourage good coding practices.
+include: package:lint/analysis_options.yaml
+
+linter:
+  # The lint rules applied to this project can be customized in the
+  # section below to disable rules from the `package:flutter_lints/flutter.yaml`
+  # included above or to enable additional rules. A list of all available lints
+  # and their documentation is published at
+  # https://dart-lang.github.io/linter/lints/index.html.
+  #
+  # Instead of disabling a lint rule for the entire project in the
+  # section below, it can also be suppressed for a single line of code
+  # or a specific dart file by using the `// ignore: name_of_lint` and
+  # `// ignore_for_file: name_of_lint` syntax on the line or in the file
+  # producing the lint.
+  rules:
+    # avoid_print: false  # Uncomment to disable the `avoid_print` rule
+    # prefer_single_quotes: true  # Uncomment to enable the `prefer_single_quotes` rule
+    parameter_assignments:true
+
+# Additional information about this file can be found at
+# https://dart.dev/guides/language/analysis-options

+ 4 - 0
dio/CHANGELOG.md

@@ -1,4 +1,8 @@
 
+# 4.0.1
+- merge pr #1177 #1196 #1205 #1224 #1225 #1227 #1256 #1263 #1291
+- fix #1257
+
 # 4.0.0
 
 stable version

+ 6 - 6
dio/README-ZH.md

@@ -14,7 +14,7 @@ dio是一个强大的Dart Http请求库,支持Restful API、FormData、拦截
 
 ```yaml
 dependencies:
-  dio: ^4.0.0 
+  dio: ^4.0.1
 ```
 
 > 如果你是dio 3.x 用户,想了解4.0的变更,请参考 [4.x更新列表](./migration_to_4.x.md)!
@@ -329,7 +329,7 @@ response = await dio.request(
 Response response = await dio.get('https://www.google.com');
 print(response.data);
 print(response.headers);
-print(response.request);
+print(response.requestOptions);
 print(response.statusCode);
 ```
 
@@ -375,12 +375,12 @@ class CustomInterceptors extends Interceptor {
   }
   @override
   Future onResponse(Response response, ResponseInterceptorHandler handler) {
-    print('RESPONSE[${response.statusCode}] => PATH: ${response.request?.path}');
+    print('RESPONSE[${response.statusCode}] => PATH: ${response.requestOptions?.path}');
     return super.onResponse(response, handler);
   }
   @override
   Future onError(DioError err, ErrorInterceptorHandler handler) {
-    print('ERROR[${err.response?.statusCode}] => PATH: ${err.request.path}');
+    print('ERROR[${err.response?.statusCode}] => PATH: ${err.requestOptions?.path}');
     return super.onError(err, handler);
   }
 }
@@ -500,10 +500,10 @@ try {
   if (e.response) {
     print(e.response.data)
     print(e.response.headers)
-    print(e.response.request)
+    print(e.response.requestOptions)
   } else {
     // Something happened in setting up or sending the request that triggered an Error
-    print(e.request)
+    print(e.requestOptions)
     print(e.message)
   }
 }

+ 6 - 6
dio/README.md

@@ -12,7 +12,7 @@ A powerful Http client for Dart, which supports Interceptors, Global configurati
 
 ```yaml
 dependencies:
-  dio: ^4.0.0
+  dio: ^4.0.1
 ```
 > Already know Dio 3 and just want to learn about what's new in Dio 4? Check out the [Migration Guide](./migration_to_4.x.md)!
 
@@ -351,7 +351,7 @@ When request is succeed, you will receive the response as follows:
 Response response = await dio.get('https://www.google.com');
 print(response.data);
 print(response.headers);
-print(response.request);
+print(response.requestOptions);
 print(response.statusCode);
 ```
 
@@ -397,12 +397,12 @@ class CustomInterceptors extends Interceptor {
   }
   @override
   Future onResponse(Response response, ResponseInterceptorHandler handler) {
-    print('RESPONSE[${response.statusCode}] => PATH: ${response.request?.path}');
+    print('RESPONSE[${response.statusCode}] => PATH: ${response.requestOptions.path}');
     return super.onResponse(response, handler);
   }
   @override
   Future onError(DioError err, ErrorInterceptorHandler handler) {
-    print('ERROR[${err.response?.statusCode}] => PATH: ${err.request.path}');
+    print('ERROR[${err.response?.statusCode}] => PATH: ${err.requestOptions.path}');
     return super.onError(err, handler);
   }
 }
@@ -519,10 +519,10 @@ try {
   if (e.response) {
     print(e.response.data)
     print(e.response.headers)
-    print(e.response.request)
+    print(e.response.requestOptions)
   } else {
     // Something happened in setting up or sending the request that triggered an Error
-    print(e.request)
+    print(e.requestOptions)
     print(e.message)
   }
 }

+ 12 - 4
dio/lib/src/adapters/browser_adapter.dart

@@ -28,16 +28,24 @@ class BrowserHttpClientAdapter implements HttpClientAdapter {
 
     xhr
       ..open(options.method, options.uri.toString(), async: true)
-      ..responseType = 'blob'
-      ..withCredentials = options.extra['withCredentials'] ?? withCredentials;
+      ..responseType = 'blob';
+
+    var _withCredentials = options.extra['withCredentials'];
+
+    if (_withCredentials != null) {
+      xhr.withCredentials = _withCredentials == true;
+    } else {
+      xhr.withCredentials = withCredentials;
+    }
+
     options.headers.remove(Headers.contentLengthHeader);
     options.headers.forEach((key, v) => xhr.setRequestHeader(key, '$v'));
 
     var completer = Completer<ResponseBody>();
 
     xhr.onLoad.first.then((_) {
-      // TODO: Set the response type to "arraybuffer" when issue 18542 is fixed.
-      var blob = xhr.response ?? Blob([]);
+      // TODO: Set the response type to "arraybuffer"() when issue 18542 is fixed.
+      Blob blob = xhr.response != null ? (xhr.response as Blob) : Blob([]);
       var reader = FileReader();
 
       reader.onLoad.first.then((_) {

+ 12 - 13
dio/lib/src/adapters/io_adapter.dart

@@ -6,7 +6,7 @@ import '../options.dart';
 import '../dio_error.dart';
 import '../redirect_record.dart';
 
-typedef OnHttpClientCreate = dynamic Function(HttpClient client);
+typedef OnHttpClientCreate = HttpClient? Function(HttpClient client);
 
 HttpClientAdapter createAdapter() => DefaultHttpClientAdapter();
 
@@ -42,26 +42,21 @@ class DefaultHttpClientAdapter implements HttpClientAdapter {
       );
     }
 
-    void _throwReceivingTimeout() {
-      throw DioError(
-        requestOptions: options,
-        error: 'Receiving data timeout[${options.receiveTimeout}ms]',
-        type: DioErrorType.receiveTimeout,
-      );
-    }
-
     late HttpClientRequest request;
+    int timePassed = 0;
     try {
       if (options.connectTimeout > 0) {
+        var start = DateTime.now().millisecond;
         request = await reqFuture
             .timeout(Duration(milliseconds: options.connectTimeout));
+        timePassed = DateTime.now().millisecond - start;
       } else {
         request = await reqFuture;
       }
 
       //Set Headers
       options.headers.forEach((k, v) {
-        if (v != null) request.headers.set(k, v);
+        if (v != null) request.headers.set(k, '$v');
       });
     } on SocketException catch (e) {
       if (e.message.contains('timed out')) {
@@ -79,15 +74,19 @@ class DefaultHttpClientAdapter implements HttpClientAdapter {
       // Transform the request data
       await request.addStream(requestStream);
     }
+    // [receiveTimeout] represents a timeout during data transfer! That is to say the
+    // client has connected to the server, and the server starts to send data to the client.
+    // So, we should use connectTimeout.
+    int responseTimeout = options.connectTimeout - timePassed;
     var future = request.close();
-    if (options.receiveTimeout > 0) {
-      future = future.timeout(Duration(milliseconds: options.receiveTimeout));
+    if (responseTimeout > 0) {
+      future = future.timeout(Duration(milliseconds: responseTimeout));
     }
     late HttpClientResponse responseStream;
     try {
       responseStream = await future;
     } on TimeoutException {
-      _throwReceivingTimeout();
+      _throwConnectingTimeout();
     }
 
     var stream =

+ 1 - 1
dio/lib/src/cancel_token.dart

@@ -41,7 +41,7 @@ class CancelToken {
     );
     _cancelError!.stackTrace = StackTrace.current;
 
-    if(!_completer.isCompleted){
+    if (!_completer.isCompleted) {
       _completer.complete(_cancelError);
     }
   }

+ 1 - 1
dio/lib/src/dio_error.dart

@@ -42,7 +42,7 @@ class DioError implements Exception {
 
   /// The original error/exception object; It's usually not null when `type`
   /// is DioErrorType.DEFAULT
-  dynamic? error;
+  dynamic error;
 
   StackTrace? _stackTrace;
 

+ 11 - 9
dio/lib/src/dio_mixin.dart

@@ -499,7 +499,7 @@ abstract class DioMixin implements Dio {
             Future(() {
               return checkIfNeedEnqueue(interceptors.requestLock, () {
                 var requestHandler = RequestInterceptorHandler();
-                interceptor(state.data, requestHandler);
+                interceptor(state.data as RequestOptions, requestHandler);
                 return requestHandler.future;
               });
             }),
@@ -585,7 +585,7 @@ abstract class DioMixin implements Dio {
       _dispatchRequest(reqOpt).then(
         (value) => handler.resolve(value, true),
         onError: (e) {
-          handler.reject(e, true);
+          handler.reject(e as DioError, true);
         },
       );
     }));
@@ -606,7 +606,7 @@ abstract class DioMixin implements Dio {
         data is InterceptorState ? data.data : data,
         requestOptions,
       );
-    }).catchError((err, stackTrace) {
+    }).catchError((err, StackTrace stackTrace) {
       var isState = err is InterceptorState;
 
       if (isState) {
@@ -655,7 +655,8 @@ abstract class DioMixin implements Dio {
           contentType = headers.value(Headers.contentTypeHeader);
           headers.set(Headers.contentTypeHeader, Headers.jsonContentType);
         }
-        ret.data = await transformer.transformResponse(reqOpt, responseBody);
+        ret.data =
+            (await transformer.transformResponse(reqOpt, responseBody)) as T?;
         if (forceConvert) {
           headers.set(Headers.contentTypeHeader, contentType);
         }
@@ -780,7 +781,7 @@ abstract class DioMixin implements Dio {
     ]);
   }
 
-  static Options checkOptions(method, options) {
+  static Options checkOptions(String method, Options? options) {
     options ??= Options();
     options.method = method;
     return options;
@@ -809,9 +810,9 @@ abstract class DioMixin implements Dio {
       dioError = DioError(requestOptions: requestOptions, error: err);
     }
 
-    var errorStackTrace;
+    StackTrace? errorStackTrace;
     if (dioError.error is Error) {
-      errorStackTrace = dioError.error.stackTrace;
+      errorStackTrace = (dioError.error as Error).stackTrace;
     }
 
     dioError.stackTrace = stackTrace ??
@@ -826,11 +827,11 @@ abstract class DioMixin implements Dio {
       [RequestOptions? requestOptions]) {
     if (response is! Response) {
       return Response<T>(
-        data: response,
+        data: response as T,
         requestOptions: requestOptions ?? RequestOptions(path: ''),
       );
     } else if (response is! Response<T>) {
-      T? data = response.data;
+      T? data = response.data as T;
       return Response<T>(
         data: data,
         headers: response.headers,
@@ -839,6 +840,7 @@ abstract class DioMixin implements Dio {
         isRedirect: response.isRedirect,
         redirects: response.redirects,
         statusMessage: response.statusMessage,
+        extra: response.extra,
       );
     }
     return response;

+ 12 - 9
dio/lib/src/entry/dio_for_native.dart

@@ -26,7 +26,7 @@ class DioForNative with DioMixin implements Dio {
   ///  [urlPath]: The file url.
   ///
   ///  [savePath]: The path to save the downloading file later. it can be a String or
-  ///  a callback:
+  ///  a callback [String Function(Headers)]:
   ///  1. A path with String type, eg "xs.jpg"
   ///  2. A callback `String Function(Headers)`; for example:
   ///  ```dart
@@ -93,7 +93,7 @@ class DioForNative with DioMixin implements Dio {
         if (e.response!.requestOptions.receiveDataWhenStatusError == true) {
           var res = await transformer.transformResponse(
             e.response!.requestOptions..responseType = ResponseType.json,
-            e.response!.data,
+            e.response!.data as ResponseBody,
           );
           e.response!.data = res;
         } else {
@@ -115,7 +115,7 @@ class DioForNative with DioMixin implements Dio {
         ..add('redirects', response.redirects.length.toString())
         ..add('uri', response.realUri.toString());
 
-      file = File(savePath(response.headers));
+      file = File(savePath(response.headers) as String);
     } else {
       file = File(savePath.toString());
     }
@@ -166,19 +166,22 @@ class DioForNative with DioMixin implements Dio {
         asyncWrite = raf.writeFrom(data).then((_raf) {
           // Notify progress
           received += data.length;
-          if (onReceiveProgress != null) {
-            onReceiveProgress(received, total);
-          }
+
+          onReceiveProgress?.call(received, total);
+
           raf = _raf;
           if (cancelToken == null || !cancelToken.isCancelled) {
             subscription.resume();
           }
-        }).catchError((err, stackTrace) async {
+        }).catchError((err, StackTrace stackTrace) async {
           try {
             await subscription.cancel();
           } finally {
             completer.completeError(DioMixin.assureDioError(
-                err, response.requestOptions, stackTrace));
+              err,
+              response.requestOptions,
+              stackTrace,
+            ));
           }
         });
       },
@@ -218,7 +221,7 @@ class DioForNative with DioMixin implements Dio {
           .timeout(Duration(
         milliseconds: response.requestOptions.receiveTimeout,
       ))
-          .catchError((err) async {
+          .catchError((Object err) async {
         await subscription.cancel();
         await _closeAndDelete();
         if (err is TimeoutException) {

+ 2 - 1
dio/lib/src/form_data.dart

@@ -88,7 +88,8 @@ class FormData {
     }
     header = '$header\r\n'
         'content-type: ${file.contentType}';
-    if (file.headers != null) { // append additional headers
+    if (file.headers != null) {
+      // append additional headers
       file.headers!.forEach((key, values) {
         values.forEach((value) {
           header = '$header\r\n'

+ 4 - 2
dio/lib/src/headers.dart

@@ -14,7 +14,8 @@ class Headers {
 
   // Header field value
   static const jsonContentType = 'application/json; charset=utf-8';
-  static const formUrlEncodedContentType = 'application/x-www-form-urlencoded';
+  static const formUrlEncodedContentType =
+      'application/x-www-form-urlencoded;charset=utf-8';
   static const textPlainContentType = 'text/plain';
 
   static final jsonMimeType = MediaType.parse(jsonContentType);
@@ -59,11 +60,12 @@ class Headers {
   /// Sets a header. The header named [name] will have all its values
   /// cleared before the value [value] is added as its value.
   void set(String name, dynamic value) {
+    if (value == null) return;
     name = name.trim().toLowerCase();
     if (value is List) {
       _map[name] = value.map<String>((e) => e.toString()).toList();
     } else {
-      _map[name] = [value.trim()];
+      _map[name] = ['$value'.trim()];
     }
   }
 

+ 2 - 1
dio/lib/src/multipart_file.dart

@@ -45,8 +45,9 @@ class MultipartFile {
     this.length, {
     this.filename,
     MediaType? contentType,
-    this.headers,
+    Map<String, List<String>>? headers,
   })  : _stream = stream,
+        headers = caseInsensitiveKeyMap(headers),
         contentType = contentType ?? MediaType('application', 'octet-stream');
 
   /// Creates a new [MultipartFile] from a byte array.

+ 6 - 2
dio/lib/src/multipart_file_stub.dart

@@ -6,9 +6,13 @@ final _err = UnsupportedError(
     'MultipartFile is only supported where dart:io is available.');
 
 Future<MultipartFile> multipartFileFromPath(String filePath,
-        {String? filename, MediaType? contentType, final Map<String, List<String>>? headers}) =>
+        {String? filename,
+        MediaType? contentType,
+        final Map<String, List<String>>? headers}) =>
     throw _err;
 
 MultipartFile multipartFileFromPathSync(String filePath,
-        {String? filename, MediaType? contentType, final Map<String, List<String>>? headers}) =>
+        {String? filename,
+        MediaType? contentType,
+        final Map<String, List<String>>? headers}) =>
     throw _err;

+ 7 - 6
dio/lib/src/options.dart

@@ -289,11 +289,11 @@ class Options {
     var _headers = caseInsensitiveKeyMap(baseOpt.headers);
     _headers.remove(Headers.contentTypeHeader);
 
-    var _contentType;
+    String? _contentType;
 
     if (headers != null) {
       _headers.addAll(headers!);
-      _contentType = _headers[Headers.contentTypeHeader];
+      _contentType = _headers[Headers.contentTypeHeader] as String?;
     }
 
     var _extra = Map<String, dynamic>.from(baseOpt.extra);
@@ -556,7 +556,7 @@ class RequestOptions extends _RequestConfig with OptionsMixin {
   ///
   /// The value can be overridden per value by adding a [MultiParam]
   /// object wrapping the actual List value and the desired format.
-  dynamic? data;
+  dynamic data;
 
   /// If the `path` starts with 'http(s)', the `baseURL` will be ignored, otherwise,
   /// it will be combined and then resolved with the baseUrl.
@@ -641,8 +641,9 @@ class _RequestConfig {
   late int sendTimeout;
 
   ///  Timeout in milliseconds for receiving data.
-  ///  [Dio] will throw the [DioError] with [DioErrorType.receiveTimeout] type
-  ///  when time out.
+  ///
+  ///  Note: [receiveTimeout]  represents a timeout during data transfer! That is to say the
+  ///  client has connected to the server, and the server starts to send data to the client.
   ///
   /// [0] meanings no timeout limit.
   late int receiveTimeout;
@@ -663,7 +664,7 @@ class _RequestConfig {
 
   String? _defaultContentType;
 
-  String? get contentType => _headers[Headers.contentTypeHeader];
+  String? get contentType => _headers[Headers.contentTypeHeader] as String?;
 
   /// [responseType] indicates the type of data that the server will respond with
   /// options which defined in [ResponseType] are `json`, `stream`, `plain`.

+ 6 - 9
dio/lib/src/transformer.dart

@@ -67,7 +67,8 @@ class DefaultTransformer extends Transformer {
       if (_isJsonMime(options.contentType)) {
         return json.encode(options.data);
       } else if (data is Map) {
-        options.contentType = Headers.formUrlEncodedContentType;
+        options.contentType =
+            options.contentType ?? Headers.formUrlEncodedContentType;
         return Transformer.urlEncodeMap(data);
       }
     }
@@ -96,9 +97,7 @@ class DefaultTransformer extends Transformer {
         sink.add(data);
         if (showDownloadProgress) {
           received += data.length;
-          if (options.onReceiveProgress != null) {
-            options.onReceiveProgress!(received, length);
-          }
+          options.onReceiveProgress?.call(received, length);
         }
       },
     ));
@@ -110,12 +109,10 @@ class DefaultTransformer extends Transformer {
         finalSize += chunk.length;
         chunks.add(chunk);
       },
-      onError: (e, stackTrace) {
-        completer.completeError(e, stackTrace);
-      },
-      onDone: () {
-        completer.complete();
+      onError: (Object error, StackTrace stackTrace) {
+        completer.completeError(error, stackTrace);
       },
+      onDone: () => completer.complete(),
       cancelOnError: true,
     );
     // ignore: unawaited_futures

+ 6 - 3
dio/lib/src/utils.dart

@@ -32,7 +32,7 @@ Encoding encodingForCharset(String? charset, [Encoding fallback = latin1]) {
   return encoding ?? fallback;
 }
 
-typedef DioEncodeHandler = Function(String key, Object? value);
+typedef DioEncodeHandler = String? Function(String key, Object? value);
 
 String encodeMap(
   data,
@@ -79,9 +79,12 @@ String encodeMap(
     } else if (sub is Map) {
       sub.forEach((k, v) {
         if (path == '') {
-          urlEncode(v, '${encodeComponent(k)}');
+          urlEncode(v, '${encodeComponent(k as String)}');
         } else {
-          urlEncode(v, '$path$leftBracket${encodeComponent(k)}$rightBracket');
+          urlEncode(
+            v,
+            '$path$leftBracket${encodeComponent(k as String)}$rightBracket',
+          );
         }
       });
     } else {

+ 3 - 2
dio/pubspec.yaml

@@ -1,6 +1,6 @@
 name: dio
 description: A powerful Http client for Dart, which supports Interceptors, FormData, Request Cancellation, File Downloading, Timeout etc.
-version: 4.0.0
+version: 4.0.1
 homepage: https://github.com/flutterchina/dio
 
 environment:
@@ -11,7 +11,8 @@ dependencies:
   path: ^1.8.0
 
 dev_dependencies:
-  test: ^1.16.0
+  test: ^1.5.1
+  lint: ^1.0.0
   pedantic: ^1.10.0
   test_coverage: ^0.5.0
 #  flutter_test:

+ 5 - 5
dio/test/basic_test.dart

@@ -8,7 +8,6 @@ import 'package:dio/dio.dart';
 import 'package:test/test.dart';
 
 void main() {
-
   test('#test headers', () {
     var headers = Headers.fromMap({
       'set-cookie': ['k=v', 'k1=v1'],
@@ -43,7 +42,9 @@ void main() {
 
   test('#send with an invalid URL', () {
     expect(
-      Dio().get('http://http.invalid').catchError((e) => throw e.error),
+      Dio()
+          .get('http://http.invalid')
+          .catchError((e) => throw e.error as Object),
       throwsA(const TypeMatcher<SocketException>()),
     );
   });
@@ -60,16 +61,15 @@ void main() {
     expect(
       dio
           .get(url, cancelToken: token)
-          .catchError((e) => throw CancelToken.isCancel(e)),
+          .catchError((e) => throw CancelToken.isCancel(e as DioError)),
       throwsA(isTrue),
     );
   });
 
   test('#status error', () async {
     var dio = Dio()..options.baseUrl = 'http://httpbin.org/status/';
-
     expect(
-      dio.get('401').catchError((e) => throw e.response.statusCode),
+      dio.get('401').catchError((e) => throw e.response.statusCode as Object),
       throwsA(401),
     );
 

+ 9 - 5
dio/test/download_test.dart

@@ -45,8 +45,9 @@ void main() {
     const savePath = '../_download_test.md';
     var dio = Dio();
     dio.options.baseUrl = serverUrl.toString();
-    var r =
-        await dio.download('/error', savePath).catchError((e) => e.response);
+    var r = await dio
+        .download('/error', savePath)
+        .catchError((e) => (e as DioError).response!);
     assert(r.data == 'error');
     r = await dio
         .download(
@@ -54,7 +55,7 @@ void main() {
           savePath,
           options: Options(receiveDataWhenStatusError: false),
         )
-        .catchError((e) => e.response);
+        .catchError((e) => (e as DioError).response!);
     assert(r.data == null);
   });
 
@@ -64,7 +65,10 @@ void main() {
       receiveTimeout: 1,
       baseUrl: serverUrl.toString(),
     ));
-    expect(dio.download('/download', savePath).catchError((e) => throw e.type),
+    expect(
+        dio
+            .download('/download', savePath)
+            .catchError((e) => throw (e as DioError).type),
         throwsA(DioErrorType.receiveTimeout));
     //print(r);
   });
@@ -82,7 +86,7 @@ void main() {
             savePath,
             cancelToken: cancelToken,
           )
-          .catchError((e) => throw e.type),
+          .catchError((e) => throw (e as DioError).type),
       throwsA(DioErrorType.cancel),
     );
     //print(r);

+ 0 - 1
dio/test/echo_adapter.dart

@@ -4,7 +4,6 @@ import 'dart:typed_data';
 import 'package:dio/adapter.dart';
 import 'package:dio/dio.dart';
 
-
 class EchoAdapter extends HttpClientAdapter {
   static const mockHost = 'mockserver';
   static const mockBase = 'http://$mockHost';

+ 22 - 14
dio/test/formdata_test.dart

@@ -12,17 +12,23 @@ void main() async {
     var fm = FormData.fromMap({
       'name': 'wendux',
       'age': 25,
-      'file': MultipartFile.fromString('hello world.', headers: { 'test': <String>['a'] }),
+      'file': MultipartFile.fromString('hello world.', headers: {
+        'test': <String>['a']
+      }),
       'files': [
         await MultipartFile.fromFile(
           '../dio/test/_testfile',
           filename: '1.txt',
-          headers: { 'test': <String>['b'] },
+          headers: {
+            'test': <String>['b']
+          },
         ),
         MultipartFile.fromFileSync(
           '../dio/test/_testfile',
           filename: '2.txt',
-            headers: { 'test': <String>['c'] },
+          headers: {
+            'test': <String>['c']
+          },
         ),
       ]
     });
@@ -43,23 +49,25 @@ void main() async {
     fm1.fields.add(MapEntry('age', '25'));
     fm1.files.add(MapEntry(
       'file',
-      MultipartFile.fromString('hello world.', headers: { 'test': <String>['a'] }),
+      MultipartFile.fromString('hello world.', headers: {
+        'test': <String>['a']
+      }),
     ));
     fm1.files.add(MapEntry(
       'files',
-      await MultipartFile.fromFile(
-        '../dio/test/_testfile',
-        filename: '1.txt',
-          headers: { 'test': <String>['b'] }
-      ),
+      await MultipartFile.fromFile('../dio/test/_testfile',
+          filename: '1.txt',
+          headers: {
+            'test': <String>['b']
+          }),
     ));
     fm1.files.add(MapEntry(
       'files',
-      await MultipartFile.fromFile(
-        '../dio/test/_testfile',
-        filename: '2.txt',
-          headers: { 'test': <String>['c'] }
-      ),
+      await MultipartFile.fromFile('../dio/test/_testfile',
+          filename: '2.txt',
+          headers: {
+            'test': <String>['c']
+          }),
     ));
     assert(fmStr.length == fm1.length);
   });

+ 24 - 16
dio/test/interceptor_test.dart

@@ -165,27 +165,31 @@ void main() {
       assert(response.data == 100);
 
       expect(
-        dio.get('/reject').catchError((e) => throw e.error),
+        dio.get('/reject').catchError((e) => throw e.error as num),
         throwsA(3),
       );
 
       expect(
-        dio.get('/reject-next').catchError((e) => throw e.error),
+        dio.get('/reject-next').catchError((e) => throw e.error as num),
         throwsA(6),
       );
 
       expect(
-        dio.get('/reject-next/reject').catchError((e) => throw e.error),
+        dio.get('/reject-next/reject').catchError((e) => throw e.error as num),
         throwsA(5),
       );
 
       expect(
-        dio.get('/resolve-next/reject').catchError((e) => throw e.error),
+        dio
+            .get('/resolve-next/reject')
+            .catchError((e) => throw e.error as Object),
         throwsA('/resolve-next/reject'),
       );
 
       expect(
-        dio.get('/resolve-next/reject-next').catchError((e) => throw e.error),
+        dio
+            .get('/resolve-next/reject-next')
+            .catchError((e) => throw e.error as num),
         throwsA(2),
       );
     });
@@ -210,7 +214,7 @@ void main() {
       );
 
       expect(
-        dio.get('/error').catchError((e) => throw e.error),
+        dio.get('/error').catchError((e) => throw e.error as String),
         throwsA('unexpected error'),
       );
 
@@ -241,7 +245,7 @@ void main() {
             dio
                 .get('/test')
                 .then(handler.resolve)
-                .catchError((e) => handler.reject(e));
+                .catchError((e) => handler.reject(e as DioError));
             break;
           case '/fakepath3':
             handler.reject(DioError(
@@ -275,11 +279,11 @@ void main() {
       expect(response.data['errCode'], 0);
 
       expect(
-        dio.get('/fakepath3').catchError((e) => throw e.message),
+        dio.get('/fakepath3').catchError((e) => throw (e as DioError).message),
         throwsA('test error'),
       );
       expect(
-        dio.get('/fakepath4').catchError((e) => throw e.message),
+        dio.get('/fakepath4').catchError((e) => throw (e as DioError).message),
         throwsA('test error'),
       );
 
@@ -338,7 +342,9 @@ void main() {
       var response = await dio.get('/test');
       expect(response.data['path'], '/test');
       expect(
-        dio.get(URL_NOT_FIND).catchError((e) => throw e.response.statusCode),
+        dio
+            .get(URL_NOT_FIND)
+            .catchError((e) => throw (e as DioError).response!.statusCode!),
         throwsA(404),
       );
       response = await dio.get(URL_NOT_FIND + '1');
@@ -346,7 +352,9 @@ void main() {
       response = await dio.get(URL_NOT_FIND + '2');
       expect(response.data, 'fake data');
       expect(
-        dio.get(URL_NOT_FIND + '3').catchError((e) => throw e.message),
+        dio
+            .get(URL_NOT_FIND + '3')
+            .catchError((e) => throw (e as DioError).message),
         throwsA('custom error info [404]'),
       );
     });
@@ -397,10 +405,10 @@ void main() {
             tokenRequestCounts++;
             tokenDio.get('/token').then((d) {
               options.headers['csrfToken'] =
-                  csrfToken = d.data['data']['token'];
+                  csrfToken = d.data['data']['token'] as String;
               handler.next(options);
             }).catchError((e) {
-              handler.reject(e, true);
+              handler.reject(e as DioError, true);
             }).whenComplete(() {
               dio.unlock();
             }); // unlock the dio
@@ -456,7 +464,7 @@ void main() {
                 dio
                     .fetch(options)
                     .then(handler.resolve)
-                    .catchError((e) => handler.reject(e));
+                    .catchError((e) => handler.reject(e as DioError));
                 return;
               }
               // update token and repeat
@@ -468,7 +476,7 @@ void main() {
               tokenDio.get('/token').then((d) {
                 //update csrfToken
                 options.headers['csrfToken'] =
-                    csrfToken = d.data['data']['token'];
+                    csrfToken = d.data['data']['token'] as String;
               }).whenComplete(() {
                 dio.unlock();
                 dio.interceptors.responseLock.unlock();
@@ -478,7 +486,7 @@ void main() {
                 dio
                     .fetch(options)
                     .then(handler.resolve)
-                    .catchError((e) => handler.reject(e));
+                    .catchError((e) => handler.reject(e as DioError));
               });
             } else {
               handler.next(error);

+ 3 - 6
dio/test/options_test.dart

@@ -240,9 +240,7 @@ void main() {
   test('#test default content-type2', () async {
     final dio = Dio();
     dio.options.setRequestContentTypeWhenNoPayload = true;
-    Options(method: 'GET')
-        .compose(dio.options, '/test')
-        .copyWith(baseUrl: 'https://www.example.com');
+    dio.options.baseUrl = 'https://www.example.com';
 
     var r1 = Options(method: 'GET').compose(dio.options, '/test').copyWith(
       headers: {Headers.contentTypeHeader: Headers.textPlainContentType},
@@ -268,9 +266,8 @@ void main() {
 
     dio.options.setRequestContentTypeWhenNoPayload = false;
 
-    var r3 = Options(method: 'GET')
-        .compose(dio.options, '/test')
-        .copyWith(baseUrl: 'https://www.example.com');
+    var r3 = Options(method: 'GET').compose(dio.options, '/test');
+    assert(r3.uri.toString() == 'https://www.example.com/test');
     assert(r3.headers[Headers.contentTypeHeader] == null);
   });
 }

+ 27 - 24
dio/test/readtimeout_test.dart

@@ -1,6 +1,5 @@
 import 'dart:async';
 import 'dart:io';
-import 'dart:isolate';
 import 'package:pedantic/pedantic.dart';
 import 'package:dio/dio.dart';
 import 'package:test/test.dart';
@@ -16,27 +15,30 @@ Future<int> getUnusedPort() async {
   try {
     server = await HttpServer.bind('localhost', 0);
     return server.port;
-  }  finally {
+  } finally {
     unawaited(server?.close());
   }
 }
 
-void startServer(port) async {
+void startServer() async {
+  var port = await getUnusedPort();
+  serverUrl = Uri.parse('http://localhost:$port');
   _server = await HttpServer.bind('localhost', port);
   _server?.listen((request) {
-      const content = 'success';
-      var response = request.response;
+    const content = 'success';
+    var response = request.response;
 
-      sleep(const Duration(milliseconds: SLEEP_DURATION_AFTER_CONNECTION_ESTABLISHED));
+    sleep(const Duration(
+        milliseconds: SLEEP_DURATION_AFTER_CONNECTION_ESTABLISHED));
 
-      response
-        ..statusCode = 200
-        ..contentLength = content.length
-        ..write(content);
+    response
+      ..statusCode = 200
+      ..contentLength = content.length
+      ..write(content);
 
-      response.close();
-      return;
-    });
+    response.close();
+    return;
+  });
 }
 
 void stopServer() {
@@ -47,20 +49,18 @@ void stopServer() {
 }
 
 void main() {
-  setUp(() async {
-    var port = await getUnusedPort();
-    serverUrl = Uri.parse('http://localhost:$port');
-    unawaited(Isolate.spawn(startServer, port));
-  });
+  setUp(startServer);
 
   tearDown(stopServer);
 
-  test('#read_timeout - catch DioError when receiveTimeout < $SLEEP_DURATION_AFTER_CONNECTION_ESTABLISHED', () async {
+  test(
+      '#read_timeout - catch DioError when receiveTimeout < $SLEEP_DURATION_AFTER_CONNECTION_ESTABLISHED',
+      () async {
     var dio = Dio();
 
     dio.options
       ..baseUrl = serverUrl.toString()
-      ..receiveTimeout = SLEEP_DURATION_AFTER_CONNECTION_ESTABLISHED - 1000;
+      ..connectTimeout = SLEEP_DURATION_AFTER_CONNECTION_ESTABLISHED - 1000;
 
     DioError error;
 
@@ -72,15 +72,17 @@ void main() {
     }
 
     expect(error, isNotNull);
-    expect(error.type == DioErrorType.receiveTimeout, isTrue);
+    expect(error.type == DioErrorType.connectTimeout, isTrue);
   });
 
-  test('#read_timeout - no DioError when receiveTimeout > $SLEEP_DURATION_AFTER_CONNECTION_ESTABLISHED', () async {
+  test(
+      '#read_timeout - no DioError when receiveTimeout > $SLEEP_DURATION_AFTER_CONNECTION_ESTABLISHED',
+      () async {
     var dio = Dio();
 
     dio.options
       ..baseUrl = serverUrl.toString()
-      ..receiveTimeout = SLEEP_DURATION_AFTER_CONNECTION_ESTABLISHED + 1000;
+      ..connectTimeout = SLEEP_DURATION_AFTER_CONNECTION_ESTABLISHED + 1000;
 
     DioError? error;
 
@@ -88,8 +90,9 @@ void main() {
       await dio.get('/');
     } on DioError catch (e) {
       error = e;
+      print(e.requestOptions.uri);
     }
 
     expect(error, isNull);
   });
-}
+}

+ 4 - 2
dio/test/request_test.dart

@@ -66,7 +66,10 @@ void main() {
       expect(response.data['path'], '/test');
 
       // error test
-      expect(dio.get('/error').catchError((e) => throw e.response.statusCode),
+      expect(
+          dio
+              .get('/error')
+              .catchError((e) => throw (e as DioError).response!.statusCode!),
           throwsA(equals(400)));
 
       // redirect test
@@ -149,6 +152,5 @@ void main() {
       assert(response.data is List);
       expect(response.data[0], 1);
     });
-
   });
 }

+ 13 - 17
pubspec.yaml

@@ -7,21 +7,17 @@ author: wendux <824783146@qq.com>
 environment:
   sdk: ">=2.12.0-0 <3.0.0"
 
-dependencies:
-  dio:
-    path: dio
-  dio_http2_adapter:
-    path: plugins/http2_adapter
-  dio_cookie_manager:
-    path: plugins/cookie_manager
-  test: ^1.16.0
-  pedantic: ^1.10.0
-  test_coverage: ^0.5.0
+#dependencies:
+#  dio:
+#    path: dio
+#  dio_http2_adapter:
+#    path: plugins/http2_adapter
+#  dio_cookie_manager:
+#    path: plugins/cookie_manager
+#  test: ^1.16.0
+#  pedantic: ^1.10.0
+#  test_coverage: ^0.5.0
 
-dependency_overrides:
-  dio:
-    path: dio
-  dio_http2_adapter:
-    path: plugins/http2_adapter
-  dio_cookie_manager:
-    path: plugins/cookie_manager
+dev_dependencies:
+  test: ^1.5.1
+  lint: ^1.0.0