Showing preview only (1,133K chars total). Download the full file or copy to clipboard to get everything.
Repository: cfug/dio
Branch: main
Commit: 85aa6f121620
Files: 423
Total size: 1.0 MB
Directory structure:
gitextract_7_0du2a0/
├── .github/
│ ├── FUNDING.yml
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug.yml
│ │ ├── config.yaml
│ │ ├── feature.yml
│ │ └── infra.yml
│ ├── PULL_REQUEST_TEMPLATE.md
│ ├── dependabot.yaml
│ └── workflows/
│ ├── check_issues_access.yml
│ ├── coverage_base.yml
│ ├── coverage_comment.yml
│ ├── publish.yml
│ └── tests.yml
├── .gitignore
├── .idea/
│ └── modules.xml
├── CODEOWNERS
├── CODE_OF_CONDUCT.md
├── COMPATIBILITY_POLICY.md
├── CONTRIBUTING-ZH.md
├── CONTRIBUTING.md
├── LICENSE
├── README-ZH.md
├── README.md
├── SECURITY.md
├── analysis_options.yaml
├── dio/
│ ├── .gitignore
│ ├── CHANGELOG.md
│ ├── LICENSE
│ ├── README-ZH.md
│ ├── README.md
│ ├── analysis_options.yaml
│ ├── dart_test.yaml
│ ├── dartdoc_options.yaml
│ ├── dio.iml
│ ├── doc/
│ │ ├── migration_guide.md
│ │ └── plugins.md
│ ├── example/
│ │ └── dio.dart
│ ├── lib/
│ │ ├── browser.dart
│ │ ├── dio.dart
│ │ ├── fix_data/
│ │ │ └── fix.yaml
│ │ ├── io.dart
│ │ └── src/
│ │ ├── adapter.dart
│ │ ├── adapters/
│ │ │ ├── browser_adapter.dart
│ │ │ └── io_adapter.dart
│ │ ├── cancel_token.dart
│ │ ├── compute/
│ │ │ ├── compute.dart
│ │ │ ├── compute_io.dart
│ │ │ └── compute_web.dart
│ │ ├── dio/
│ │ │ ├── dio_for_browser.dart
│ │ │ └── dio_for_native.dart
│ │ ├── dio.dart
│ │ ├── dio_exception.dart
│ │ ├── dio_mixin.dart
│ │ ├── form_data.dart
│ │ ├── headers.dart
│ │ ├── interceptor.dart
│ │ ├── interceptors/
│ │ │ ├── imply_content_type.dart
│ │ │ └── log.dart
│ │ ├── multipart_file/
│ │ │ ├── browser_multipart_file.dart
│ │ │ └── io_multipart_file.dart
│ │ ├── multipart_file.dart
│ │ ├── options.dart
│ │ ├── parameter.dart
│ │ ├── progress_stream/
│ │ │ ├── browser_progress_stream.dart
│ │ │ └── io_progress_stream.dart
│ │ ├── redirect_record.dart
│ │ ├── response/
│ │ │ └── response_stream_handler.dart
│ │ ├── response.dart
│ │ ├── transformer.dart
│ │ ├── transformers/
│ │ │ ├── background_transformer.dart
│ │ │ ├── fused_transformer.dart
│ │ │ ├── sync_transformer.dart
│ │ │ └── util/
│ │ │ ├── consolidate_bytes.dart
│ │ │ └── transform_empty_to_null.dart
│ │ └── utils.dart
│ ├── pubspec.yaml
│ └── test/
│ ├── adapters_test.dart
│ ├── cancel_token_test.dart
│ ├── connect_timeout_integration_test.dart
│ ├── dio_mixin_test.dart
│ ├── encoding_test.dart
│ ├── exception_test.dart
│ ├── formdata_test.dart
│ ├── headers_test.dart
│ ├── interceptor_test.dart
│ ├── mimetype_test.dart
│ ├── mock/
│ │ ├── _formdata
│ │ ├── _testfile
│ │ ├── adapters.dart
│ │ ├── http_mock.dart
│ │ └── http_mock.mocks.dart
│ ├── multipart_file_test.dart
│ ├── options_test.dart
│ ├── options_timeout_integration_test.dart
│ ├── parameter_test.dart
│ ├── pinning_test.dart
│ ├── queued_interceptor_test.dart
│ ├── response/
│ │ └── response_stream_test.dart
│ ├── stacktrace_test.dart
│ ├── test_suite_test.dart
│ ├── timeout_test.dart
│ ├── transformer_test.dart
│ └── utils.dart
├── dio_test/
│ ├── LICENSE
│ ├── README.md
│ ├── analysis_options.yaml
│ ├── dio_test.iml
│ ├── lib/
│ │ ├── src/
│ │ │ ├── httpbun.dart
│ │ │ ├── matcher.dart
│ │ │ ├── test/
│ │ │ │ ├── basic_tests.dart
│ │ │ │ ├── cancellation_tests.dart
│ │ │ │ ├── cors_tests.dart
│ │ │ │ ├── download_tests.dart
│ │ │ │ ├── headers_tests.dart
│ │ │ │ ├── http_method_tests.dart
│ │ │ │ ├── parameter_tests.dart
│ │ │ │ ├── redirect_tests.dart
│ │ │ │ ├── status_code_tests.dart
│ │ │ │ ├── suite.dart
│ │ │ │ ├── timeout_tests.dart
│ │ │ │ ├── upload_tests.dart
│ │ │ │ └── url_encoded_tests.dart
│ │ │ └── utils.dart
│ │ ├── tests.dart
│ │ └── util.dart
│ └── pubspec.yaml
├── dio_workspace.iml
├── example_dart/
│ ├── .gitignore
│ ├── analysis_options.yaml
│ ├── dart_test.yaml
│ ├── dio_example.iml
│ ├── lib/
│ │ ├── adapter.dart
│ │ ├── cancel_request.dart
│ │ ├── certificate_pinning.dart
│ │ ├── cookie_mgr.dart
│ │ ├── custom_cache_interceptor.dart
│ │ ├── dio.dart
│ │ ├── download.dart
│ │ ├── download_with_trunks.dart
│ │ ├── extend_dio.dart
│ │ ├── formdata.dart
│ │ ├── generic.dart
│ │ ├── http2_adapter.dart
│ │ ├── options.dart
│ │ ├── post_stream_and_bytes.dart
│ │ ├── proxy.dart
│ │ ├── queue_interceptors.dart
│ │ ├── queued_interceptor_crsftoken.dart
│ │ ├── request_interceptors.dart
│ │ ├── response_interceptor.dart
│ │ ├── test.dart
│ │ ├── transformer.dart
│ │ └── upload.txt
│ └── pubspec.yaml
├── example_flutter_app/
│ ├── .gitignore
│ ├── .metadata
│ ├── README.md
│ ├── analysis_options.yaml
│ ├── android/
│ │ ├── .gitignore
│ │ ├── app/
│ │ │ ├── build.gradle.kts
│ │ │ └── src/
│ │ │ └── main/
│ │ │ ├── AndroidManifest.xml
│ │ │ ├── kotlin/
│ │ │ │ └── cn/
│ │ │ │ └── flutter/
│ │ │ │ └── dio_flutter_example/
│ │ │ │ └── MainActivity.kt
│ │ │ └── res/
│ │ │ ├── drawable/
│ │ │ │ └── launch_background.xml
│ │ │ ├── drawable-v21/
│ │ │ │ └── launch_background.xml
│ │ │ ├── values/
│ │ │ │ └── styles.xml
│ │ │ └── values-night/
│ │ │ └── styles.xml
│ │ ├── build.gradle.kts
│ │ ├── dio_flutter_example_android.iml
│ │ ├── gradle/
│ │ │ └── wrapper/
│ │ │ └── gradle-wrapper.properties
│ │ ├── gradle.properties
│ │ └── settings.gradle.kts
│ ├── dio_flutter_example.iml
│ ├── example_flutter_app.iml
│ ├── ios/
│ │ ├── .gitignore
│ │ ├── Flutter/
│ │ │ ├── AppFrameworkInfo.plist
│ │ │ ├── Debug.xcconfig
│ │ │ └── Release.xcconfig
│ │ ├── Runner/
│ │ │ ├── AppDelegate.swift
│ │ │ ├── Assets.xcassets/
│ │ │ │ ├── AppIcon.appiconset/
│ │ │ │ │ └── Contents.json
│ │ │ │ └── LaunchImage.imageset/
│ │ │ │ ├── Contents.json
│ │ │ │ └── README.md
│ │ │ ├── Base.lproj/
│ │ │ │ ├── LaunchScreen.storyboard
│ │ │ │ └── Main.storyboard
│ │ │ ├── Info.plist
│ │ │ └── Runner-Bridging-Header.h
│ │ ├── Runner.xcodeproj/
│ │ │ ├── project.pbxproj
│ │ │ ├── project.xcworkspace/
│ │ │ │ ├── contents.xcworkspacedata
│ │ │ │ └── xcshareddata/
│ │ │ │ ├── IDEWorkspaceChecks.plist
│ │ │ │ └── WorkspaceSettings.xcsettings
│ │ │ └── xcshareddata/
│ │ │ └── xcschemes/
│ │ │ └── Runner.xcscheme
│ │ ├── Runner.xcworkspace/
│ │ │ ├── contents.xcworkspacedata
│ │ │ └── xcshareddata/
│ │ │ ├── IDEWorkspaceChecks.plist
│ │ │ └── WorkspaceSettings.xcsettings
│ │ └── RunnerTests/
│ │ └── RunnerTests.swift
│ ├── lib/
│ │ ├── http.dart
│ │ ├── main.dart
│ │ └── routes/
│ │ └── request.dart
│ ├── linux/
│ │ ├── .gitignore
│ │ ├── CMakeLists.txt
│ │ ├── flutter/
│ │ │ ├── CMakeLists.txt
│ │ │ ├── generated_plugin_registrant.cc
│ │ │ ├── generated_plugin_registrant.h
│ │ │ └── generated_plugins.cmake
│ │ └── runner/
│ │ ├── CMakeLists.txt
│ │ ├── main.cc
│ │ ├── my_application.cc
│ │ └── my_application.h
│ ├── macos/
│ │ ├── .gitignore
│ │ ├── Flutter/
│ │ │ ├── Flutter-Debug.xcconfig
│ │ │ ├── Flutter-Release.xcconfig
│ │ │ └── GeneratedPluginRegistrant.swift
│ │ ├── Runner/
│ │ │ ├── AppDelegate.swift
│ │ │ ├── Assets.xcassets/
│ │ │ │ └── AppIcon.appiconset/
│ │ │ │ └── Contents.json
│ │ │ ├── Base.lproj/
│ │ │ │ └── MainMenu.xib
│ │ │ ├── Configs/
│ │ │ │ ├── AppInfo.xcconfig
│ │ │ │ ├── Debug.xcconfig
│ │ │ │ ├── Release.xcconfig
│ │ │ │ └── Warnings.xcconfig
│ │ │ ├── DebugProfile.entitlements
│ │ │ ├── Info.plist
│ │ │ ├── MainFlutterWindow.swift
│ │ │ └── Release.entitlements
│ │ ├── Runner.xcodeproj/
│ │ │ ├── project.pbxproj
│ │ │ ├── project.xcworkspace/
│ │ │ │ └── xcshareddata/
│ │ │ │ └── IDEWorkspaceChecks.plist
│ │ │ └── xcshareddata/
│ │ │ └── xcschemes/
│ │ │ └── Runner.xcscheme
│ │ ├── Runner.xcworkspace/
│ │ │ ├── contents.xcworkspacedata
│ │ │ └── xcshareddata/
│ │ │ └── IDEWorkspaceChecks.plist
│ │ └── RunnerTests/
│ │ └── RunnerTests.swift
│ ├── pubspec.yaml
│ ├── web/
│ │ ├── index.html
│ │ └── manifest.json
│ └── windows/
│ ├── .gitignore
│ ├── CMakeLists.txt
│ ├── flutter/
│ │ ├── CMakeLists.txt
│ │ ├── generated_plugin_registrant.cc
│ │ ├── generated_plugin_registrant.h
│ │ └── generated_plugins.cmake
│ └── runner/
│ ├── CMakeLists.txt
│ ├── Runner.rc
│ ├── flutter_window.cpp
│ ├── flutter_window.h
│ ├── main.cpp
│ ├── resource.h
│ ├── runner.exe.manifest
│ ├── utils.cpp
│ ├── utils.h
│ ├── win32_window.cpp
│ └── win32_window.h
├── melos.yaml
├── plugins/
│ ├── compatibility_layer/
│ │ ├── .gitignore
│ │ ├── CHANGELOG.md
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── analysis_options.yaml
│ │ ├── dart_test.yaml
│ │ ├── dio_compatibility_layer.iml
│ │ ├── example/
│ │ │ └── conversion_layer_example.dart
│ │ ├── lib/
│ │ │ ├── dio_compatibility_layer.dart
│ │ │ └── src/
│ │ │ └── conversion_layer_adapter.dart
│ │ ├── pubspec.yaml
│ │ └── test/
│ │ ├── client_mock.dart
│ │ └── conversion_layer_adapter_test.dart
│ ├── cookie_manager/
│ │ ├── .gitignore
│ │ ├── .metadata
│ │ ├── CHANGELOG.md
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── analysis_options.yaml
│ │ ├── dart_test.yaml
│ │ ├── dio_cookie_manager.iml
│ │ ├── example/
│ │ │ └── example.dart
│ │ ├── lib/
│ │ │ ├── dio_cookie_manager.dart
│ │ │ └── src/
│ │ │ ├── cookie_mgr.dart
│ │ │ └── exception.dart
│ │ ├── pubspec.yaml
│ │ └── test/
│ │ ├── basic_test.dart
│ │ ├── cookies_persistance_test.dart
│ │ └── cookies_test.dart
│ ├── http2_adapter/
│ │ ├── .gitignore
│ │ ├── .metadata
│ │ ├── CHANGELOG.md
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── analysis_options.yaml
│ │ ├── dart_test.yaml
│ │ ├── dio_http2_adapter.iml
│ │ ├── doc/
│ │ │ └── migration_guide.md
│ │ ├── example/
│ │ │ └── example.dart
│ │ ├── lib/
│ │ │ ├── dio_http2_adapter.dart
│ │ │ └── src/
│ │ │ ├── client_setting.dart
│ │ │ ├── connection_manager.dart
│ │ │ ├── connection_manager_imp.dart
│ │ │ └── http2_adapter.dart
│ │ ├── pubspec.yaml
│ │ └── test/
│ │ ├── http2_test.dart
│ │ ├── pinning_test.dart
│ │ ├── redirect_test.dart
│ │ └── test_suite_test.dart
│ ├── native_dio_adapter/
│ │ ├── .gitignore
│ │ ├── CHANGELOG.md
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── analysis_options.yaml
│ │ ├── example/
│ │ │ ├── .gitignore
│ │ │ ├── analysis_options.yaml
│ │ │ ├── android/
│ │ │ │ ├── .gitignore
│ │ │ │ ├── app/
│ │ │ │ │ ├── build.gradle
│ │ │ │ │ └── src/
│ │ │ │ │ ├── debug/
│ │ │ │ │ │ └── AndroidManifest.xml
│ │ │ │ │ ├── main/
│ │ │ │ │ │ ├── AndroidManifest.xml
│ │ │ │ │ │ ├── kotlin/
│ │ │ │ │ │ │ └── com/
│ │ │ │ │ │ │ └── example/
│ │ │ │ │ │ │ └── example/
│ │ │ │ │ │ │ └── MainActivity.kt
│ │ │ │ │ │ └── res/
│ │ │ │ │ │ ├── drawable/
│ │ │ │ │ │ │ └── launch_background.xml
│ │ │ │ │ │ ├── drawable-v21/
│ │ │ │ │ │ │ └── launch_background.xml
│ │ │ │ │ │ ├── values/
│ │ │ │ │ │ │ └── styles.xml
│ │ │ │ │ │ └── values-night/
│ │ │ │ │ │ └── styles.xml
│ │ │ │ │ └── profile/
│ │ │ │ │ └── AndroidManifest.xml
│ │ │ │ ├── build.gradle
│ │ │ │ ├── gradle/
│ │ │ │ │ └── wrapper/
│ │ │ │ │ └── gradle-wrapper.properties
│ │ │ │ ├── gradle.properties
│ │ │ │ └── settings.gradle
│ │ │ ├── ios/
│ │ │ │ ├── .gitignore
│ │ │ │ ├── Flutter/
│ │ │ │ │ ├── AppFrameworkInfo.plist
│ │ │ │ │ ├── Debug.xcconfig
│ │ │ │ │ └── Release.xcconfig
│ │ │ │ ├── Podfile
│ │ │ │ ├── Runner/
│ │ │ │ │ ├── AppDelegate.swift
│ │ │ │ │ ├── Assets.xcassets/
│ │ │ │ │ │ ├── AppIcon.appiconset/
│ │ │ │ │ │ │ └── Contents.json
│ │ │ │ │ │ └── LaunchImage.imageset/
│ │ │ │ │ │ ├── Contents.json
│ │ │ │ │ │ └── README.md
│ │ │ │ │ ├── Base.lproj/
│ │ │ │ │ │ ├── LaunchScreen.storyboard
│ │ │ │ │ │ └── Main.storyboard
│ │ │ │ │ ├── Info.plist
│ │ │ │ │ └── Runner-Bridging-Header.h
│ │ │ │ ├── Runner.xcodeproj/
│ │ │ │ │ ├── project.pbxproj
│ │ │ │ │ ├── project.xcworkspace/
│ │ │ │ │ │ ├── contents.xcworkspacedata
│ │ │ │ │ │ └── xcshareddata/
│ │ │ │ │ │ ├── IDEWorkspaceChecks.plist
│ │ │ │ │ │ └── WorkspaceSettings.xcsettings
│ │ │ │ │ └── xcshareddata/
│ │ │ │ │ └── xcschemes/
│ │ │ │ │ └── Runner.xcscheme
│ │ │ │ └── Runner.xcworkspace/
│ │ │ │ ├── contents.xcworkspacedata
│ │ │ │ └── xcshareddata/
│ │ │ │ ├── IDEWorkspaceChecks.plist
│ │ │ │ └── WorkspaceSettings.xcsettings
│ │ │ ├── lib/
│ │ │ │ └── main.dart
│ │ │ ├── linux/
│ │ │ │ ├── .gitignore
│ │ │ │ ├── CMakeLists.txt
│ │ │ │ ├── flutter/
│ │ │ │ │ ├── CMakeLists.txt
│ │ │ │ │ ├── generated_plugin_registrant.cc
│ │ │ │ │ ├── generated_plugin_registrant.h
│ │ │ │ │ └── generated_plugins.cmake
│ │ │ │ ├── main.cc
│ │ │ │ ├── my_application.cc
│ │ │ │ └── my_application.h
│ │ │ ├── macos/
│ │ │ │ ├── .gitignore
│ │ │ │ ├── Flutter/
│ │ │ │ │ ├── Flutter-Debug.xcconfig
│ │ │ │ │ ├── Flutter-Release.xcconfig
│ │ │ │ │ └── GeneratedPluginRegistrant.swift
│ │ │ │ ├── Podfile
│ │ │ │ ├── Runner/
│ │ │ │ │ ├── AppDelegate.swift
│ │ │ │ │ ├── Assets.xcassets/
│ │ │ │ │ │ └── AppIcon.appiconset/
│ │ │ │ │ │ └── Contents.json
│ │ │ │ │ ├── Base.lproj/
│ │ │ │ │ │ └── MainMenu.xib
│ │ │ │ │ ├── Configs/
│ │ │ │ │ │ ├── AppInfo.xcconfig
│ │ │ │ │ │ ├── Debug.xcconfig
│ │ │ │ │ │ ├── Release.xcconfig
│ │ │ │ │ │ └── Warnings.xcconfig
│ │ │ │ │ ├── DebugProfile.entitlements
│ │ │ │ │ ├── Info.plist
│ │ │ │ │ ├── MainFlutterWindow.swift
│ │ │ │ │ └── Release.entitlements
│ │ │ │ ├── Runner.xcodeproj/
│ │ │ │ │ ├── project.pbxproj
│ │ │ │ │ ├── project.xcworkspace/
│ │ │ │ │ │ └── xcshareddata/
│ │ │ │ │ │ └── IDEWorkspaceChecks.plist
│ │ │ │ │ └── xcshareddata/
│ │ │ │ │ └── xcschemes/
│ │ │ │ │ └── Runner.xcscheme
│ │ │ │ └── Runner.xcworkspace/
│ │ │ │ ├── contents.xcworkspacedata
│ │ │ │ └── xcshareddata/
│ │ │ │ └── IDEWorkspaceChecks.plist
│ │ │ ├── pubspec.yaml
│ │ │ ├── web/
│ │ │ │ ├── index.html
│ │ │ │ └── manifest.json
│ │ │ └── windows/
│ │ │ ├── .gitignore
│ │ │ ├── CMakeLists.txt
│ │ │ ├── flutter/
│ │ │ │ ├── CMakeLists.txt
│ │ │ │ ├── generated_plugin_registrant.cc
│ │ │ │ ├── generated_plugin_registrant.h
│ │ │ │ └── generated_plugins.cmake
│ │ │ └── runner/
│ │ │ ├── CMakeLists.txt
│ │ │ ├── Runner.rc
│ │ │ ├── flutter_window.cpp
│ │ │ ├── flutter_window.h
│ │ │ ├── main.cpp
│ │ │ ├── resource.h
│ │ │ ├── runner.exe.manifest
│ │ │ ├── utils.cpp
│ │ │ ├── utils.h
│ │ │ ├── win32_window.cpp
│ │ │ └── win32_window.h
│ │ ├── lib/
│ │ │ ├── fix_data/
│ │ │ │ └── fix.yaml
│ │ │ ├── native_dio_adapter.dart
│ │ │ └── src/
│ │ │ ├── conversion_layer_adapter.dart
│ │ │ ├── cronet_adapter.dart
│ │ │ ├── cupertino_adapter.dart
│ │ │ └── native_adapter.dart
│ │ ├── native_dio_adapter.iml
│ │ ├── pubspec.yaml
│ │ └── test/
│ │ ├── client_mock.dart
│ │ └── conversion_layer_adapter_test.dart
│ └── web_adapter/
│ ├── .gitignore
│ ├── CHANGELOG.md
│ ├── LICENSE
│ ├── README.md
│ ├── analysis_options.yaml
│ ├── dart_test.yaml
│ ├── dio_web_adapter.iml
│ ├── example/
│ │ └── main.dart
│ ├── lib/
│ │ ├── dio_web_adapter.dart
│ │ └── src/
│ │ ├── adapter.dart
│ │ ├── adapter_impl.dart
│ │ ├── compute.dart
│ │ ├── compute_impl.dart
│ │ ├── dio_impl.dart
│ │ ├── multipart_file.dart
│ │ ├── multipart_file_impl.dart
│ │ ├── progress_stream.dart
│ │ └── progress_stream_impl.dart
│ ├── pubspec.yaml
│ └── test/
│ └── browser_test.dart
├── pubspec.yaml
└── scripts/
├── melos_packages.dart
└── prepare_pinning_certs.sh
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/FUNDING.yml
================================================
github: [AlexV525, kuhnroyal]
================================================
FILE: .github/ISSUE_TEMPLATE/bug.yml
================================================
name: 🐞 Bug Report
description: Tell us about something that's not working the way we (probably) intend.
labels: ["s: bug", "h: need triage"]
body:
- type: markdown
attributes:
value: |
🧐 **Guidelines:**
- Search through [existing issues](https://github.com/cfug/dio/issues) first to ensure that this bug has not been reported before.
- Write a descriptive title for your issue. Avoid generic or vague titles such as "Something's not working" or "A couple of problems".
- Keep your issue focused on one single problem. If you have multiple bug reports, please create separate issues for each of them.
- Provide as much context as possible in the fields below. Include screenshots, screen recordings, links, references, or anything else you may consider relevant.
- If you want to ask a question instead of reporting a bug, please use [discussions](https://github.com/cfug/dio/discussions/new) instead.
- type: dropdown
id: package
attributes:
label: Package
description: Which package has a problem?
options:
- dio
- compatibility_layer
- cookie_manager
- http2_adapter
- native_dio_adapter
- web_adapter
validations:
required: true
- type: input
id: version
attributes:
label: Version
placeholder: 1.2.3
description: Which version of that package do you use?
validations:
required: true
- type: dropdown
id: os
attributes:
label: Operating-System
description: On which OS does the problem occur?
multiple: true
options:
- Android
- iOS
- Web
- MacOS
- Linux
- Windows
validations:
required: true
- type: dropdown
id: adapter
attributes:
label: Adapter
description: Which adapter(s) are used?
multiple: true
options:
- Default Dio
- NativeAdapter
- Http2Adapter
- ConversionLayerAdapter
validations:
required: true
- type: textarea
id: flutter_info
attributes:
label: Output of `flutter doctor -v`
description: Required when used with Flutter. The input is automatically formatted in code fences
render: shell
- type: input
id: dart_version
attributes:
label: Dart Version
placeholder: 1.2.3
description: Which version of Dart do you use?
validations:
required: false
- type: textarea
id: repro
attributes:
label: Steps to Reproduce
description: How can we see what you're seeing? Specific is terrific.
placeholder: |-
1. foo
2. bar
3. baz
validations:
required: true
- type: textarea
id: expected
attributes:
label: Expected Result
validations:
required: true
- type: textarea
id: actual
attributes:
label: Actual Result
description: Logs? Screenshots? Yes, please.
validations:
required: true
================================================
FILE: .github/ISSUE_TEMPLATE/config.yaml
================================================
blank_issues_enabled: true
================================================
FILE: .github/ISSUE_TEMPLATE/feature.yml
================================================
name: 💡 Feature Request
description: Tell us about a problem dio could solve but doesn't.
labels: ["s: feature"]
body:
- type: textarea
id: problem
attributes:
label: Request Statement
description: What problem could dio solve that it doesn't?
validations:
required: true
- type: textarea
id: expected
attributes:
label: Solution Brainstorm
description: We know you have bright ideas to share ... share away, friend.
validations:
required: false
================================================
FILE: .github/ISSUE_TEMPLATE/infra.yml
================================================
name: 👷 Infra
description: Something is wrong with the CI setup or could be improved
labels: ["infra"]
body:
- type: textarea
id: problem
attributes:
label: Request Statement
validations:
required: true
================================================
FILE: .github/PULL_REQUEST_TEMPLATE.md
================================================
<!-- Write down your pull request descriptions. -->
### New Pull Request Checklist
- [ ] I have read the [Documentation](https://pub.dev/documentation/dio/latest/)
- [ ] I have searched for a similar pull request in the [project](https://github.com/cfug/dio/pulls) and found none
- [ ] I have updated this branch with the latest `main` branch to avoid conflicts (via merge from master or rebase)
- [ ] I have added the required tests to prove the fix/feature I'm adding
- [ ] I have updated the documentation (if necessary)
- [ ] I have run the tests without failures
- [ ] I have updated the `CHANGELOG.md` in the corresponding package
### Additional context and info (if any)
<!-- Provide more context and info about the PR. -->
================================================
FILE: .github/dependabot.yaml
================================================
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
labels:
- "infra"
- "github-actions"
================================================
FILE: .github/workflows/check_issues_access.yml
================================================
# Not allow users without write access to create "infra" or blank issues.
name: Check issues access
on:
issues:
types: [ opened, reopened, edited ]
jobs:
verify_access:
runs-on: ubuntu-latest
if: ${{ join(github.event.issue.labels) == '' || contains(github.event.issue.labels.*.name, 'infra')}}
steps:
- uses: actions-cool/check-user-permission@v2.3.0
id: checkUser
with:
require: 'write'
- name: Write comment
if: steps.checkUser.outputs.require-result == 'false'
uses: actions-cool/issues-helper@v3.7.6
with:
actions: 'create-comment'
issue-number: ${{ github.event.issue.number }}
body: |
@${{ github.event.issue.user.login }} Infra and blank issues are only available for moderators. You're apparently using the wrong issue template.
> Infra 和空白 issue 仅供管理人员使用,请选择其他 issue 模板创建 issue。
- name: Close issue
if: steps.checkUser.outputs.require-result == 'false'
uses: actions-cool/issues-helper@v3.7.6
with:
actions: 'close-issue'
issue-number: ${{ github.event.issue.number }}
- name: Lock issue
if: steps.checkUser.outputs.require-result == 'false'
uses: actions-cool/issues-helper@v3.7.6
with:
actions: 'lock-issue'
issue-number: ${{ github.event.issue.number }}
lock-reason: 'off-topic'
================================================
FILE: .github/workflows/coverage_base.yml
================================================
name: 'coverage_baseline'
# The code-coverage-report-action uses workflow artifacts to store the coverage report.
# The action will upload the coverage report as an artifact,
# and the action will also download the coverage report from the artifact in PRs.
# The action will then compare the coverage report from the PR with the coverage report from the base branch.
# For this to work, the action needs to be run on the base branch after each pushed commit
# or at least once before the artifact retention period ends.
on:
# Allow for manual runs
workflow_dispatch:
# Runs at 00:00, on day 1 of the month (every ~30 days)
schedule:
- cron: '0 0 1 * *'
push:
branches:
- main
jobs:
generate:
runs-on: ubuntu-latest
env:
TEST_PRESET: all
steps:
- uses: actions/checkout@v6
- uses: subosito/flutter-action@v2
with:
cache: true
- run: |
chmod +x ./scripts/prepare_pinning_certs.sh
./scripts/prepare_pinning_certs.sh
- name: Install proxy for tests
run: sudo apt-get update && sudo apt-get install -y squid
- run: dart pub get
- uses: bluefireteam/melos-action@v3
with:
run-bootstrap: false
melos-version: '^6.0.0'
- name: Check satisfied packages
run: |
dart ./scripts/melos_packages.dart
echo $(cat .melos_packages) >> $GITHUB_ENV
- name: Melos Bootstrap
run: melos bootstrap
# Tests
- run: ./scripts/prepare_pinning_certs.sh
- name: Install proxy for tests
run: sudo apt-get update && sudo apt-get install -y squid mkcert
- name: Start local httpbun
run: |
mkcert -install
mkcert -cert-file '/tmp/cert.pem' -key-file '/tmp/key.pem' httpbun.local
echo '127.0.0.1 httpbun.local' | sudo tee --append /etc/hosts
docker run \
--name httpbun \
--detach \
--publish 443:443 \
--volume /tmp:/tmp:ro \
--env HTTPBUN_TLS_CERT=/tmp/cert.pem \
--env HTTPBUN_TLS_KEY=/tmp/key.pem \
--pull always \
sharat87/httpbun
sleep 1
curl --fail --silent --show-error https://httpbun.local/any
- name: Use httpbun.local for tests
run: melos run httpbun:local
- name: '[Verify step] Test Dart packages [VM]'
run: melos run test:vm
- name: Use httpbun.com for Web/Flutter tests
run: melos run httpbun:com
- name: '[Verify step] Test Dart packages [Chrome]'
run: melos run test:web:chrome
- name: '[Verify step] Test Dart packages [Firefox]'
run: melos run test:web:firefox
- name: '[Verify step] Test Flutter packages'
run: melos run test:flutter
- name: '[Coverage] Generate report'
run: melos run coverage:combine
- uses: clearlyip/code-coverage-report-action@v6
with:
filename: 'coverage/cobertura.xml'
================================================
FILE: .github/workflows/coverage_comment.yml
================================================
name: 'coverage_comment'
# This workflow runs after the 'Verify packages abilities' workflow is completed for a pull request.
# The workflow downloads the coverage report if the 'Verify packages abilities' workflow was successful.
# The workflow then adds a comment to the PR with the coverage report.
on:
workflow_run:
workflows: ['Verify packages abilities']
types:
- completed
jobs:
download_coverage:
runs-on: ubuntu-latest
if: github.event.workflow_run.event == 'pull_request'
steps:
- name: Download artifact
id: download-artifact
uses: dawidd6/action-download-artifact@v18
with:
workflow: tests.yml
workflow_conclusion: success
run_id: ${{ github.event.workflow_run.id }}
name: code-coverage-results
- name: Determine PR number
id: pr-number
run: |
PR_NUMBER=$(cat pr_number.txt)
echo "Found PR:$PR_NUMBER"
echo "value=$PR_NUMBER" >> $GITHUB_OUTPUT
- name: Add PR comment
uses: marocchino/sticky-pull-request-comment@v3
with:
number: ${{ steps.pr-number.outputs.value }}
recreate: true
path: code-coverage-results.md
================================================
FILE: .github/workflows/publish.yml
================================================
name: Publish from comments
on:
issue_comment:
types: [created]
jobs:
publish:
# https://github.com/cfug/dio/issues/1633
if: github.event.issue.number == 1633
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
token: ${{ secrets.CFUG_PUBLISHER }}
- uses: dart-lang/setup-dart@v1.4
- uses: cfug/dio_issue_release_action@v2
with:
github-token: ${{ secrets.CFUG_PUBLISHER }}
pub-credentials-json: ${{ secrets.CREDENTIAL_JSON }}
================================================
FILE: .github/workflows/tests.yml
================================================
name: Verify packages abilities
on:
push:
branches:
- main
- '6.0.0'
paths-ignore:
- "**.md"
pull_request:
branches:
- main
- '6.0.0'
paths-ignore:
- "**.md"
# Ensure that new pushes/updates cancel running jobs
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
defaults:
run:
shell: bash -leo pipefail {0}
jobs:
workflows:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
sdk: [ min, stable, beta ]
env:
TEST_PRESET: all
steps:
- uses: actions/checkout@v6
- uses: subosito/flutter-action@v2
with:
cache: true
flutter-version: ${{ matrix.sdk == 'min' && '3.3.0' || '' }}
channel: ${{ matrix.sdk == 'min' && '' || matrix.channel }}
- run: |
echo TARGET_DART_SDK=${{ matrix.sdk }} >> $GITHUB_ENV
- name: Prepare dependencies for the project management
run: dart pub get
- uses: bluefireteam/melos-action@v3
with:
run-bootstrap: false
melos-version: ${{ matrix.sdk == 'min' && '3.4.0' || '^6.0.0' }}
- name: Remove dio_web_adapter overrides
if: ${{ matrix.sdk == 'min' }}
run: rm -rf plugins/web_adapter
- name: Check satisfied packages
run: |
dart ./scripts/melos_packages.dart
echo $(cat .melos_packages) >> $GITHUB_ENV
- name: Melos Bootstrap
run: melos bootstrap
- name: '[Verify step] Format'
if: ${{ matrix.sdk == 'stable' }}
run: melos run format
- name: '[Verify step] Analyze packages'
if: ${{ matrix.sdk == 'stable' }}
run: melos run analyze
- name: '[Verify step] Publish dry-run'
if: ${{ matrix.sdk == 'stable' }}
run: melos run publish-dry-run
# Tests
- run: ./scripts/prepare_pinning_certs.sh
- name: Install proxy for tests
run: sudo apt-get update && sudo apt-get install -y squid mkcert
- name: Start local httpbun
run: |
mkcert -install
mkcert -cert-file '/tmp/cert.pem' -key-file '/tmp/key.pem' httpbun.local
echo '127.0.0.1 httpbun.local' | sudo tee --append /etc/hosts
docker run \
--name httpbun \
--detach \
--publish 443:443 \
--volume /tmp:/tmp:ro \
--env HTTPBUN_TLS_CERT=/tmp/cert.pem \
--env HTTPBUN_TLS_KEY=/tmp/key.pem \
--pull always \
sharat87/httpbun
sleep 1
curl --fail --silent --show-error https://httpbun.local/any
- name: Use httpbun.local for tests
run: melos run httpbun:local
- name: '[Verify step] Test Dart packages [VM]'
run: melos run test:vm
- name: Use httpbun.com for Web/Flutter tests
run: melos run httpbun:com
- name: '[Verify step] Test Dart packages [Chrome]'
run: melos run test:web:chrome
- name: '[Verify step] Test Dart packages [Firefox]'
run: melos run test:web:firefox
- name: '[Verify step] Test Flutter packages'
run: melos run test:flutter
- uses: actions/setup-java@v5
if: ${{ matrix.sdk == 'stable' }}
with:
distribution: 'adopt'
java-version: '17'
- name: '[Verify step] Build Flutter APK'
if: ${{ matrix.sdk == 'stable' }}
run: melos run build:example:apk
# Coverage
- name: '[Coverage] Format & print test coverage'
if: ${{ matrix.sdk == 'stable' }}
run: melos run coverage:show
- name: '[Coverage] Create Report'
uses: clearlyip/code-coverage-report-action@v6
id: code_coverage_report
if: ${{ matrix.sdk == 'stable' && github.actor != 'dependabot[bot]'}}
with:
artifact_download_workflow_names: 'Verify packages abilities,coverage_baseline'
filename: 'coverage/cobertura.xml'
only_list_changed_files: true
- name: '[Coverage] Write PR number to file'
if: ${{ matrix.sdk == 'stable' && github.actor != 'dependabot[bot]'}}
run: echo ${{ github.event.number }} > pr_number.txt
- name: '[Coverage] Upload'
if: ${{ matrix.sdk == 'stable' && github.actor != 'dependabot[bot]'}}
uses: actions/upload-artifact@v7
with:
name: code-coverage-results
path: |
coverage/cobertura.xml
code-coverage-results.md
pr_number.txt
================================================
FILE: .gitignore
================================================
# Files and directories created by pub
.packages
.dart_tool/
.pub/
.example/flutter.png
build/
# Remove the following pattern if you wish to check in your lock file
pubspec.lock
pubspec_overrides.yaml
# Directory created by dartdoc
doc/api/
.cookies/
.vscode/
# Miscellaneous
.DS_Store
**/DerivedData/
# IDEA configurations
/.idea/*
!/.idea/dio.iml
!/.idea/modules.xml
# Coverage
coverage
# Melos
**/.melos_package
.melos_packages
melos_overrides.yaml
# FVM Version Cache
.fvm/
.fvmrc
================================================
FILE: .idea/modules.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/dio/dio.iml" filepath="$PROJECT_DIR$/dio/dio.iml" />
<module fileurl="file://$PROJECT_DIR$/plugins/compatibility_layer/dio_compatibility_layer.iml" filepath="$PROJECT_DIR$/plugins/compatibility_layer/dio_compatibility_layer.iml" />
<module fileurl="file://$PROJECT_DIR$/plugins/cookie_manager/dio_cookie_manager.iml" filepath="$PROJECT_DIR$/plugins/cookie_manager/dio_cookie_manager.iml" />
<module fileurl="file://$PROJECT_DIR$/example_dart/dio_example.iml" filepath="$PROJECT_DIR$/example_dart/dio_example.iml" />
<module fileurl="file://$PROJECT_DIR$/example_flutter_app/dio_flutter_example.iml" filepath="$PROJECT_DIR$/example_flutter_app/dio_flutter_example.iml" />
<module fileurl="file://$PROJECT_DIR$/plugins/http2_adapter/dio_http2_adapter.iml" filepath="$PROJECT_DIR$/plugins/http2_adapter/dio_http2_adapter.iml" />
<module fileurl="file://$PROJECT_DIR$/dio_test/dio_test.iml" filepath="$PROJECT_DIR$/dio_test/dio_test.iml" />
<module fileurl="file://$PROJECT_DIR$/plugins/web_adapter/dio_web_adapter.iml" filepath="$PROJECT_DIR$/plugins/web_adapter/dio_web_adapter.iml" />
<module fileurl="file://$PROJECT_DIR$/plugins/native_dio_adapter/native_dio_adapter.iml" filepath="$PROJECT_DIR$/plugins/native_dio_adapter/native_dio_adapter.iml" />
<module fileurl="file://$PROJECT_DIR$/plugins/native_dio_adapter/example/native_dio_adapter_example.iml" filepath="$PROJECT_DIR$/plugins/native_dio_adapter/example/native_dio_adapter_example.iml" />
<module fileurl="file://$PROJECT_DIR$/dio_workspace.iml" filepath="$PROJECT_DIR$/dio_workspace.iml" />
</modules>
</component>
</project>
================================================
FILE: CODEOWNERS
================================================
* @cfug/dio-core
================================================
FILE: CODE_OF_CONDUCT.md
================================================
# Contributor Covenant Code of Conduct
## Our Pledge
We as members, contributors, and leaders pledge to participate in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity
and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to a positive environment for our
community includes:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
overall community
Examples of unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or
advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
address, without their explicit permission
* Other conduct that could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.
Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.
## Scope
This Code of Conduct applies within all community spaces and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
[cfug-team@googlegroups.com](mailto:cfug-team@googlegroups.com).
All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the
reporter of any incident.
## Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series
of actions.
**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or
permanent ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within
the community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available at
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
Community Impact Guidelines were inspired by [Mozilla's code of conduct
enforcement ladder](https://github.com/mozilla/diversity).
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see the FAQ at
https://www.contributor-covenant.org/faq. Translations are available at
https://www.contributor-covenant.org/translations.
================================================
FILE: COMPATIBILITY_POLICY.md
================================================
# Compatibility Policy
As an open-source project, all activities happened when the maintainers have spare time and energy.
The support range is limited due to the above condition.
Therefore, we have a general compatibility policy to help people
that are not actively adapting SDK updates or intended to use any old SDKs to acknowledge the support range.
## Policy Details
For all packages, the oldest Dart SDK we typically support
is one that was **released less than 2 years ago**.
### Exceptions
- The minimum SDK version will follow the dependencies' requirement.
For example: `http2: ^2.1.0` requires Dart SDK >=3.0.0.
- The implementation can no longer compatible between the latest and previous SDKs.
- Previous SDKs have security issues that require to use a new version.
To raise your suggestions and reports, use the issue tracker
or contact cfug-team@googlegroups.com if you want to do this privately.
================================================
FILE: CONTRIBUTING-ZH.md
================================================
# 贡献指南
Language: [English](CONTRIBUTING.md) | 简体中文
首先,感谢您考虑为 `dio` 项目做出贡献!像这样的开源项目得以成长和繁荣,多亏了像您这样的贡献者。无论您是在修复错误、添加新功能、改进文档还是报告问题,每一份贡献都是宝贵和值得赞赏的。
本文档提供了一些指南,以帮助确保您的贡献尽可能有效。在提交您的贡献之前,请花一点时间阅读这些指南。
请记住,每个为这个项目做出贡献的人都需要遵循我们的行为准则。这有助于确保所有贡献者的积极和包容环境。
再次感谢您的贡献,我们期待看到您将为 `dio` 项目带来什么!
## 创建好的工单
> [!TIP]
> 在创建新问题之前,搜索已有的工单和拉取请求以避免重复是一个好习惯。
### 错误报告
报告错误时,请包括以下信息:
1. **标题**:简短描述性的错误标题。
2. **包**:指定有问题的包。
3. **版本**:您正在使用的包版本。
4. **操作系统**:出现问题的操作系统。
5. **适配器**:指定使用的适配器。
6. **`flutter doctor -v` 的输出**:使用 Flutter 时需要。
7. **Dart 版本**:您使用的 Dart 版本。
8. **重现步骤**:详细步骤说明如何重现错误。
9. **预期结果**:您期望发生的事情。
10. **实际结果**:实际发生的事情。包括日志、屏幕截图或任何其他相关信息。
### 功能请求
请求新功能时,请包括以下信息:
1. **标题**:功能请求的简短描述性标题。
2. **请求声明**:描述您认为 `dio` 项目能解决但目前没有解决的问题。
3. **解决方案头脑风暴**:分享您的想法,关于如何解决问题。如果您没有特定的解决方案,那也没关系!
> [!TIP]
> 记住,您提供的信息越多,我们就越容易理解和解决问题。感谢您的贡献!
> 请避免评论旧的、已关闭的工单。如果旧问题似乎与您的问题有关但并未完全解决您的问题,最好开一个新工单并引用旧的。
## 开发
此项目使用 [Melos](https://github.com/invertase/melos) 管理单体仓库和大多数任务。Melos 是一个为 Dart 和 Flutter 的多包项目优化工作流的工具。有关如何使用 Melos 的更多信息,请参阅 [Melos 文档](https://melos.invertase.dev)。
### 设置
开始之前,您需要全局安装 Melos:
```bash
dart pub global activate melos
```
在安装 Melos 后,可以克隆仓库并安装依赖项:
```bash
git clone https://github.com/cfug/dio.git
cd dio
melos bootstrap
```
## 提交更改
在以拉取请求提交您的更改之前,请确保格式化和分析您的代码并运行所有测试。以下是您应该了解的主要 melos 脚本:
### 代码质量
要格式化(和修复)所有包,请运行:
```bash
melos run format
# 或者
melos run format:fix
```
要分析所有包,请运行:
```bash
melos run analyze
```
### 测试
要运行所有测试,请使用:
```bash
melos run test
```
可以使用适当的脚本运行单个测试目标:
```bash
melos run test:vm
melos run test:web
melos run test:web:chrome
melos run test:web:firefox
```
================================================
FILE: CONTRIBUTING.md
================================================
# Contributing Guidelines
Language: English | [简体中文](CONTRIBUTING-ZH.md)
First of all, thank you for considering contributing to the `dio` project! Open source projects like this one grow and thrive thanks to the contributions from people like you. Whether you're fixing bugs, adding new features, improving the documentation, or even reporting issues, every contribution is valuable and appreciated.
This document provides some guidelines to help ensure that your contributions are as effective as possible. Please take a moment to read through these guidelines before submitting your contribution.
Remember, everyone contributing to this project is expected to follow our code of conduct. This helps ensure a positive and inclusive environment for all contributors.
Thank you again for your contributions, and we look forward to seeing what you will bring to the `dio` project!
## Creating Good Tickets
> [!TIP]
> Before creating a new issue, it's a good practice to search for open tickets and pull requests to avoid duplicates.
### Bug Reports
When reporting a bug, please include the following information:
1. **Title**: A brief, descriptive title for the bug.
2. **Package**: Specify which package has the problem.
3. **Version**: The version of the package you are using.
4. **Operating System**: The OS on which the problem occurs.
5. **Adapter**: Specify which adapter(s) are used.
6. **Output of `flutter doctor -v`**: Required when used with Flutter.
7. **Dart Version**: The version of Dart you are using.
8. **Steps to Reproduce**: Detailed steps on how to reproduce the bug.
9. **Expected Result**: What you expected to happen.
10. **Actual Result**: What actually happened. Include logs, screenshots, or any other relevant information.
### Feature Requests
When requesting a new feature, please include the following information:
1. **Title**: A brief, descriptive title for the feature request.
2. **Request Statement**: Describe the problem that you believe the `dio` project could solve but currently doesn't.
3. **Solution Brainstorm**: Share your ideas on how the problem could be solved. If you don't have a specific solution in mind, that's okay too!
> [!TIP]
> Remember, the more information you provide, the easier it is for us to understand and address the issue. Thank you for your contributions!
> Please refrain from commenting on old, closed tickets. If an old issue seems related but doesn't fully address your problem, it's best to open a new ticket and reference the old one instead.
## Development
This project uses [Melos](https://github.com/invertase/melos) to manage the mono-repo and most tasks. Melos is a tool that optimizes the workflow for multi-package Dart and Flutter projects. For more information on how to use Melos, please refer to the [Melos documentation](https://melos.invertase.dev).
### Setup
To get started, you'll need to install Melos globally:
```bash
dart pub global activate melos
```
After installing Melos, you can clone the repository and install the dependencies:
```bash
git clone https://github.com/cfug/dio.git
cd dio
melos bootstrap
```
## Submitting changes
Before submitting your changes as a pull request, please make sure to format and analyze your and run the all tests. Here are the main melos scripts you should be aware of:
### Code quality
To format (and fix) all packages, run:
```bash
melos run format
# OR
melos run format:fix
```
To analyze all packages, run:
```bash
melos run analyze
```
### Testing
To run all tests, use:
```bash
melos run test
```
Individual test targets can be run with the appropriate scripts:
```bash
melos run test:vm
melos run test:web
melos run test:web:chrome
melos run test:web:firefox
```
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2018 Wen Du (wendux)
Copyright (c) 2022 The CFUG Team
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: README-ZH.md
================================================
# dio
Language: [English](README.md) | 简体中文
此处是 **dio** 项目的基础仓库。请前往项目各自的路径查看指引。
> 别忘了为你发布的与 dio 相关的 package 添加
> [#dio](https://pub.flutter-io.cn/packages?q=topic%3Adio) 分类标签!
> 了解更多:https://dart.cn/tools/pub/pubspec#topics
## 版本问题
**在你更新之前:大版本和次要版本可能会包含不兼容的重大改动。<br/>
请阅读 [迁移指南][] 了解完整的重大变更内容。**
想要了解我们的兼容性政策,请参阅 [兼容性政策][]文档。
[迁移指南]: https://pub.flutter-io.cn/documentation/dio/latest/topics/Migration%20Guide-topic.html
[兼容性政策]: COMPATIBILITY_POLICY.md
## 所有依赖
### dio
- dio: [链接](dio)
[](https://pub.flutter-io.cn/packages/dio)
### 插件
- cookie_manager: [链接](plugins/cookie_manager)
[](https://pub.flutter-io.cn/packages/dio_cookie_manager)
- compatibility_layer: [链接](plugins/compatibility_layer)
[](https://pub.flutter-io.cn/packages/dio_compatibility_layer)
- http2_adapter: [链接](plugins/http2_adapter)
[](https://pub.flutter-io.cn/packages/dio_http2_adapter)
- native_dio_adapter: [链接](plugins/native_dio_adapter)
[](https://pub.dev/packages/native_dio_adapter)
- web_adapter: [链接](plugins/web_adapter)
[](https://pub.dev/packages/dio_web_adapter)
### 示例
- example: [链接](example_dart)
- example_flutter_app: [链接](example_flutter_app)
## 版权 & 协议
该项目由 [@flutterchina](https://github.com/flutterchina)
开源组织的 [@wendux](https://github.com/wendux) 创作,
并在 2023 年转移至
[Flutter 中文社区 (@cfug)](https://github.com/cfug) 组织进行维护。
该项目遵循 [MIT 开源协议](LICENSE)。
================================================
FILE: README.md
================================================
# dio
Language: English | [简体中文](README-ZH.md)
This is the base repo of the **dio** project.
Please move specific paths for project instructions.
> Don't forget to add [#dio](https://pub.dev/packages?q=topic%3Adio)
> topic to your published dio related packages!
> See more: https://dart.dev/tools/pub/pubspec#topics
## Versioning
**Before you upgrade: Breaking changes might happen in major and minor versions of packages.<br/>
See the [Migration Guide][] for the complete breaking changes list.**
To know about our compatibility policy, see the [Compatibility Policy][] doc.
[Migration Guide]: https://pub.dev/documentation/dio/latest/topics/Migration%20Guide-topic.html
[Compatibility Policy]: COMPATIBILITY_POLICY.md
## All Packages
### dio
- dio: [link](dio)
[](https://pub.dev/packages/dio)
### Plugins
- cookie_manager: [link](plugins/cookie_manager)
[](https://pub.dev/packages/dio_cookie_manager)
- compatibility_layer: [link](plugins/compatibility_layer)
[](https://pub.dev/packages/dio_compatibility_layer)
- http2_adapter: [link](plugins/http2_adapter)
[](https://pub.dev/packages/dio_http2_adapter)
- native_dio_adapter: [link](plugins/native_dio_adapter)
[](https://pub.dev/packages/native_dio_adapter)
- web_adapter: [link](plugins/web_adapter)
[](https://pub.dev/packages/dio_web_adapter)
### Examples
- example: [link](example_dart)
- example_flutter_app: [link](example_flutter_app)
## Copyright & License
The project and its underlying projects
are originally authored by
[@wendux](https://github.com/wendux)
with the organization
[@flutterchina](https://github.com/flutterchina),
started being maintained by
[Chinese Flutter User Group (@cfug)](https://github.com/cfug)
since 2023.
The project consents [the MIT license](LICENSE).
## Star History
<a href="https://star-history.com/#cfug/dio&Date">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=cfug/dio&type=Date&theme=dark" />
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=cfug/dio&type=Date" />
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=cfug/dio&type=Date" />
</picture>
</a>
================================================
FILE: SECURITY.md
================================================
# Security Policy
## Supported Versions
| Version | Supported |
|---------|-----------|
| >=5.0 | ✅ |
| < 5.0 | ❌ |
## Reporting a Vulnerability
Contact cfug-team@googlegroups.com with your vulnerability report.
================================================
FILE: analysis_options.yaml
================================================
include: package:lints/recommended.yaml
analyzer:
errors:
always_declare_return_types: error
always_put_control_body_on_new_line: error
avoid_renaming_method_parameters: error
avoid_void_async: error
camel_case_types: error
constant_identifier_names: error
deprecated_member_use_from_same_package: ignore
non_constant_identifier_names: error
prefer_single_quotes: error
require_trailing_commas: error
todo: ignore
linter:
rules:
always_declare_return_types: true
always_put_control_body_on_new_line: true
avoid_renaming_method_parameters: true
avoid_unnecessary_containers: true
avoid_void_async: true
curly_braces_in_flow_control_structures: true
directives_ordering: true
library_annotations: false
prefer_const_constructors: true
prefer_const_constructors_in_immutables: false
prefer_final_fields: true
prefer_final_in_for_each: true
prefer_final_locals: true
prefer_relative_imports: true
prefer_single_quotes: true
require_trailing_commas: true
sort_constructors_first: true
sort_unnamed_constructors_first: true
unnecessary_await_in_return: true
unnecessary_breaks: true
unnecessary_late: true
unnecessary_library_name: false
unnecessary_parenthesis: true
================================================
FILE: dio/.gitignore
================================================
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/
# IntelliJ related
*.ipr
*.iws
.idea/
# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
#.vscode/
# Flutter/Dart/Pub related
**/doc/api/
.dart_tool/
.flutter-plugins
.packages
.pub-cache/
.pub/
build/
# Exceptions to above rules.
!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
# Project related.
test/*_pinning.txt
coverage
================================================
FILE: dio/CHANGELOG.md
================================================
# CHANGELOG
**Before you upgrade: Breaking changes might happen in major and minor versions of packages.<br/>
See the [Migration Guide][] for the complete breaking changes list.**
## Unreleased
*None.*
## 5.9.2
- Fixes `kIsWeb` across different Flutter SDKs.
- Provides `httpVersion` in `Response.extra` when using `IOHttpClientAdapter`.
## 5.9.1
- Add `requestUrl` and `responseUrl` parameters to `LogInterceptor` for more precise control over URL logging.
- Fix `QueuedInterceptor` hanging indefinitely when interceptor callbacks throw synchronous exceptions.
## 5.9.0
- Do not allow updating the error field after a cancel token has canceled.
- Allow passing an initial interceptors list to the constructor of `Interceptors`.
- Use `package:mime` to help determine the `content-type` of `MultipartFile` base on the provided `filename`.
## 5.8.0+1
- Raise the version constraint of `dio_web_adapter`.
## 5.8.0
- Update comments and strings with `MultipartFile`.
- Removes redundant warnings when composing request options on Web.
- Fixes boundary inconsistency in `FormData.clone()`.
- Support `FileAccessMode` in `Dio.download` and `Dio.downloadUri` to change download file opening mode.
- Fix `ListParam` equality by using the `DeepCollectionEquality`.
- Enables configuring the logging details of `DioException` globally and locally.
- Enables using `Dio.clone` to reuse base options, client adapter, interceptors, and transformer,
in a new `Dio` instance.
## 5.7.0
- Graceful handling of responses with nonzero `Content-Length`, `Content-Type` that is json, and empty payload.
- Empty responses are now transformed to `null`.
## 5.6.0
- Supports the WASM environment. Users should upgrade the adapter with
`dart pub upgrade` or `flutter pub upgrade` to use the WASM-supported version.
## 5.5.0+1
- Fix WASM compile errors after moving the web implementation to `dio_web_adapter`.
## 5.5.0
- Raise the min Dart SDK version to 2.18.0.
- Add constructor for `DioExceptionType.badCertificate`.
- Create type alias `DioMediaType` for `http_parser`'s `MediaType`.
- Fix the type conversion regression when using `MultipartFile.fromBytes`.
- Split the Web implementation to `package:dio_web_adapter`.
- Add FusedTransformer for improved performance when decoding JSON.
- Set FusedTransformer as the default transformer.
- Improves `InterceptorState.toString()`.
- If the `CancelToken` got canceled before making requests,
throws the exception directly rather than cut actual HTTP requests afterward.
- Catch `MediaType` parse exception in `Transformer.isJsonMimeType`.
- Improves warning logs on the Web platform.
- Improves memory allocating when using `CancelToken`.
## 5.4.3+1
- Fix type promotions for the UTF-8 encoder on previous Dart SDKs.
## 5.4.3
- Remove sockets detach in `IOHttpClientAdapter`.
- Allows to define `FormData.boundaryName` instead of the default `--dio-boundary-`.
## 5.4.2+1
- Revert "Catch sync/async exceptions in interceptors' handlers".
## 5.4.2
- Fix `receiveTimeout` throws exception after the request has been cancelled.
- Catch sync/async exceptions in interceptors' handlers.
- Throws precise `StateError` for handler's duplicated calls.
## 5.4.1
- Provide fix suggestions for `dart fix`.
- Fix `receiveTimeout` for streamed responses.
- Fix cancellation for streamed responses and downloads when using `IOHttpClientAdapter`.
- Fix receive progress for streamed responses and downloads when using `IOHttpClientAdapter`.
- Support relative `baseUrl` on the Web platform.
- Avoid fake uncaught exceptions during debugging with IDEs.
## 5.4.0
- Improve `SyncTransformer`'s stream transform.
- Allow case-sensitive header keys with the `preserveHeaderCase` flag through options.
- Fix `receiveTimeout` for the `IOHttpClientAdapter`.
- Fix `receiveTimeout` for the `download` method of `DioForNative`.
- Improve the stream byte conversion.
## 5.3.4
- Raise warning for `Map`s other than `Map<String, dynamic>` when encoding request data.
- Improve exception messages.
- Allow `ResponseDecoder` and `RequestEncoder` to be async.
- Ignores `Duration.zero` timeouts.
## 5.3.3
- Fix failing requests throw `DioException`s with `.unknown` instead of `.connectionError` on `SocketException`.
- Removes the accidentally added `options` argument for `Options.compose`.
- Fix wrong formatting of multi-value header in `BrowserHttpClientAdapter`.
- Add warning in debug mode when trying to send data with a `GET` request in web.
- Reduce cases in which browsers would trigger a CORS preflight request.
- Add warnings in debug mode when using `sendTimeout` and `onSendProgress` with an empty request body.
- Fix `receiveTimeout` not working correctly on web.
- Fix `ImplyContentTypeInterceptor` can be removed by `Interceptors.clear()` by default.
## 5.3.2
- Revert removed `download` for `DioMixin`.
- Fix for `Dio.download` not cleaning the file on data handling error.
## 5.3.1
- Improve package descriptions and code formats.
- Improve comments.
- Fix error when cloning `MultipartFile` from `FormData` with regression test.
- Deprecate `MultipartFile` constructor in favor `MultipartFile.fromStream`.
- Add `FormData.clone`.
## 5.3.0
- Remove `http` from `dev_dependencies`.
- Add support for cloning `MultipartFile` from `FormData`.
- Only produce null response body when `ResponseType.json`.
## 5.2.1+1
- Fix changelog on pub.dev.
## 5.2.1
- Revert changes to handling of `List<int>` body data.
## 5.2.0+1
- Fix `DioErrorType` deprecation hint.
## 5.2.0
- Make `LogInterceptor` prints in DEBUG mode (when the assertion is enabled) by default.
- Deprecate `DioError` in favor of `DioException`.
- Fix `IOHttpClientAdapter.onHttpClientCreate` Repeated calls
- `IOHttpClientAdapter.onHttpClientCreate` has been deprecated and is scheduled for removal in
Dio 6.0.0 - Please use the replacement `IOHttpClientAdapter.createHttpClient` instead.
- Using `CancelToken` no longer closes and re-creates `HttpClient` for each request when `IOHttpClientAdapter` is used.
- Fix timeout handling for browser `receiveTimeout`.
- Improve performance when sending binary data (`List<int>`/`Uint8List`).
## 5.1.2
- Allow `FormData` to send a null entry value as an empty string.
## 5.1.1
- Revert changes to `CancelToken.cancel()` behavior, as a result the `DioError`
provided by the `CancelToken.cancelError` does not contain useful information
when the token was not used with a request.
- Fix wrong `ListFormat` being used for comparison during encoding of `FormData`
and `application/x-www-form-urlencoded`, resulting in potential wrong output encoding
for `ListFormat.multi` and `ListFormat.multiCompatible` since Dio 4.0.x.
- Respect `Options.listFormat` when encoding `x-www-url-encoded` content.
## 5.1.0
- Fix double-completion when using `connectionTimeout` on web platform.
- Allow defining adapter methods through their constructors.
- Fix `FormData` encoding regression for maps with dynamic keys, introduced in 5.0.3.
- Mark several static `DioMixin` functions as `@internal`.
- Make `DioError.stackTrace` non-nullable.
- Ensure `DioError.stackTrace` always points to the correct call site.
## 5.0.3
- Imply `List<Map>` as JSON content in `ImplyContentTypeInterceptor`.
- Fix `FormData` encoding for collections and objects.
## 5.0.2
- Improve code formats according to linter rules.
- Remove the force conversion for the response body.
- Fix `DioErrorType.cancel` in `Interceptors`.
- Fix wrong encoding of collection query parameters.
- Fix "unsupported operation" error on web platform.
## 5.0.1
- Add `ImplyContentTypeInterceptor` as a default interceptor.
- Add `Headers.multipartFormDataContentType` for headers usage.
- Fix variable shadowing of `withCredentials` in `browser_adapter.dart`.
## 5.0.0
- Raise the min Dart SDK version to 2.15.0 to support `BackgroundTransformer`.
- Change `Dio.transformer` from `DefaultTransformer` to `BackgroundTransformer`.
- Remove plain ASCII check in `FormData`.
- Allow asynchronous method with `savePath`.
- Allow `data` in all request methods.
- A platform independent `HttpClientAdapter` can now be instantiated by doing
`dio.httpClientAdapter = HttpClientAdapter();`.
- Add `ValidateCertificate` to handle certificate pinning better.
- Support `Content-Disposition` header case sensitivity.
### Breaking Changes
- The default charset `utf-8` in `Headers` content type constants has been removed.
- `BaseOptions.setRequestContentTypeWhenNoPayload` has been removed.
- Improve `DioError`s. There are now more cases in which the inner original stacktrace is supplied.
- `HttpClientAdapter` must now be implemented instead of extended.
- Any classes specific to `dart:io` platforms can now be imported via `import 'package:dio/io.dart';`.
Classes specific to web can be imported via `import 'package:dio/browser.dart';`.
- `connectTimeout`, `sendTimeout`, and `receiveTimeout` are now `Duration`s.
## 4.0.6
- fix #1452
## 4.0.5
- require Dart `2.12.1` which fixes exception handling for secure socket connections (#45214)
- Only delete file if it exists when downloading.
- Fix `BrowserHttpClientAdapter` canceled hangs
- Correct JSON MIME Type detection
- [Web] support send/receive progress in web platform
- refactor timeout logic
- use 'arraybuffer' instead of 'blob' for xhr requests in web platform
## 4.0.4
- Fix fetching null data in a response
## 4.0.3
- fix #1311
## 4.0.2
- Add QueuedInterceptor
- merge #1316 #1317
## 4.0.1
- merge pr #1177 #1196 #1205 #1224 #1225 #1227 #1256 #1263 #1291
- fix #1257
## 4.0.0
stable version
## 4.0.0-prev3
- fix #1091 , #1089 , #1087
## 4.0.0-prev2
- fix #1082 and # 1076
## 4.0.0-prev1
**Interceptors:** Add `handler` for Interceptor APIs which can specify
the subsequent interceptors processing logic more finely (whether to skip them or not).
## 4.0.0-beta7
- fix #1074
## 4.0.0-beta6
- fix #1070
## 4.0.0-beta5
- support ListParam
## 4.0.0-beta4
- fix #1060
## 4.0.0-beta3
- rename CollectionFormat to ListFormat
- change default value of Options.listFormat from `multiCompatible` to `multi`
- add upload_stream_test.dart
## 4.0.0-beta2
- support null-safety
- add `CollectionFormat` configuration in Options
- add `fetch` API for Dio
- rename DioErrorType enums from uppercase to camel style
- rename 'Options.merge' to 'Options.copyWith'
## 3.0.10 2020.8.7
1. fix #877 'dio.interceptors.errorLock.lock()'
2. fix #851
3. fix #641
## 3.0.9 2020.2.24
- Add test cases
## 3.0.8 2019.12.29
- Code style improvement
## 3.0.7 2019.11.25
- Merge #574 : fix upload image header error, support both oss and other server
## 3.0.6 2019.11.22
- revert #562, and fixed #566
## 3.0.5 2019.11.19
- merge #557 #531
## 3.0.4 2019.10.29
- fix #502 #515 #523
## 3.0.3 2019.10.1
- fix encode bug
## 3.0.2 2019.9.26
- fix #474 #480
## 3.0.2-dev.1 2019.9.20
- fix #470 #471
## 3.0.1 2019.9.20
- Fix #467
- Export `DioForNative` and `DioForBrowser` classes.
## 3.0.0
### New features
- Support Flutter Web.
- Extract [CookieManager](../plugins/cookie_manager) into a separate package(No need for Flutter Web).
- Provides [HTTP/2.0 HttpClientAdapter](../plugins/http2_adapter).
### Change List
- ~~Options.cookies~~
- ~~Options.connectionTimeout~~ ;We should config connection timed out in `BaseOptions`. For keep-alive reasons, not every request requires a separate connection。
- `Options.followRedirects`、`Options.maxRedirects`、`Response.redirects` don't make sense in Flutter Web,because redirection can be automatically handled by browsers.
- ~~FormData.from~~,use `FormData.fromMap` instead.
- Delete ~~Formdata.asBytes()~~、~~Formdata.asBytesAsync()~~ , use `Formdata.readAsBytes()` instead.
- Delete ~~`UploadFileInfo`~~ class, `MultipartFile` instead.
- The return type of Interceptor's callback changes from `FutureOr<dynamic>` to `Future`.
The reason is [here](https://dart.dev/guides/language/effective-dart/design#avoid-using-futureort-as-a-return-type).
- The type of `Response.headers` changes from `HttpHeaders` to `Headers`,
because `HttpHeaders` is in "dart:io" library which is not supported in Flutter Web.
## 2.1.16
Add `deleteOnError` parameter to `downloadUri`
## 2.1.14
- fix #402 #385 #422
## 2.1.13
- fix #369
## 2.1.12
- fix #367 #365
## 2.1.10
- fix #360
## 2.1.9
- support flutter version>=1.8 (fix #357)
## 2.1.8
- fix #354 #312
- Allow "delete" method with request body(#223)
## 2.1.7
- fix #321 #318
## 2.1.6
- fix #316
## 2.1.5
- fix #309
## 2.1.4
- Add `options.responseDecoder`
- Make DioError catchable by implementing Exception instead of Error
## 2.1.3
Add `statusMessage` attribute for `Response` and `ResponseBody`
## 2.1.2
First Stable version for 2.x
## 2.0
**Refactor the Interceptors**
- Support add Multiple Interceptors.
- Add Log Interceptor
- Add CookieManager Interceptor
**API**
- Support Uri
- Support `queryParameters` for all request API
- Modify the `get` API
**Options**
- Separate Options to three class: Options、BaseOptions、RequestOptions
- Add `queryParameters` and `cookies` for BaseOptions
**Adapter**
- Abstract HttpClientAdapter layer.
- Provide a DefaultHttpClientAdapter which make http requests by `dart:io:HttpClient`
## 0.1.8
- change file name "TransFormer" to "Transformer"
- change "dio.transFormer" to "dio.transformer"
- change deprecated "UTF8" to "utf8"
## 0.1.5
- add `clear` method for dio instance
## 0.1.4
- fix `download` bugs
## 0.1.3
- support upload files with Array
- support create `HttpClient` by user self in `onHttpClientCreate`
- support generic
- bug fix
## 0.0.1
- Initial version, created by Stagehand
[Migration Guide]: doc/migration_guide.md
================================================
FILE: dio/LICENSE
================================================
MIT License
Copyright (c) 2018 Wen Du (wendux)
Copyright (c) 2022 The CFUG Team
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: dio/README-ZH.md
================================================
# dio
[](https://pub.flutter-io.cn/packages/dio)
[](https://pub.flutter-io.cn/packages/dio)
文档语言: 简体中文 | [English](README.md)
dio 是一个强大的 HTTP 网络请求库,支持全局配置、Restful API、FormData、拦截器、
请求取消、Cookie 管理、文件上传/下载、超时、自定义适配器、转换器等。
> 别忘了为你发布的与 dio 相关的 package 添加
> [#dio](https://pub.flutter-io.cn/packages?q=topic%3Adio) 分类标签!
> 了解更多:https://dart.cn/tools/pub/pubspec#topics
<details>
<summary>内容列表</summary>
<!-- TOC -->
* [dio](#dio)
* [开始使用](#开始使用)
* [添加依赖](#添加依赖)
* [一个极简的示例](#一个极简的示例)
* [Awesome dio](#awesome-dio)
* [相关插件](#相关插件)
* [相关的项目](#相关的项目)
* [示例](#示例)
* [发起一个 `GET` 请求 :](#发起一个-get-请求-)
* [发起一个 `POST` 请求:](#发起一个-post-请求)
* [发起多个并发请求](#发起多个并发请求)
* [下载文件](#下载文件)
* [以流的方式接收响应数据](#以流的方式接收响应数据)
* [以二进制数组的方式接收响应数据](#以二进制数组的方式接收响应数据)
* [发送 `FormData`](#发送-formdata)
* [通过 `FormData` 上传多个文件](#通过-formdata-上传多个文件)
* [监听发送(上传)数据进度](#监听发送上传数据进度)
* [以流的形式提交二进制数据](#以流的形式提交二进制数据)
* [Dio APIs](#dio-apis)
* [创建一个Dio实例,并配置它](#创建一个dio实例并配置它)
* [请求配置](#请求配置)
* [响应数据](#响应数据)
* [拦截器](#拦截器)
* [完成和终止请求/响应](#完成和终止请求响应)
* [QueuedInterceptor](#queuedinterceptor)
* [例子](#例子)
* [日志拦截器](#日志拦截器)
* [Dart](#dart)
* [Flutter](#flutter)
* [自定义拦截器](#自定义拦截器)
* [错误处理](#错误处理)
* [DioException](#dioexception)
* [DioExceptionType](#dioexceptiontype)
* [使用 application/x-www-form-urlencoded 编码](#使用-applicationx-www-form-urlencoded-编码)
* [发送 FormData](#发送-formdata-1)
* [多文件上传](#多文件上传)
* [复用 `FormData` 和 `MultipartFile`](#复用-formdata-和-multipartfile)
* [转换器](#转换器)
* [在 Flutter 中进行设置](#在-flutter-中进行设置)
* [其它示例](#其它示例)
* [HttpClientAdapter](#httpclientadapter)
* [设置代理](#设置代理)
* [HTTPS 证书校验](#https-证书校验)
* [HTTP/2 支持](#http2-支持)
* [请求取消](#请求取消)
* [继承 Dio class](#继承-dio-class)
* [Web 平台跨域资源共享 (CORS)](#web-平台跨域资源共享-cors)
<!-- TOC -->
</details>
## 开始使用
### 添加依赖
依照文档将 `dio` 包添加为
[pubspec 的依赖](https://pub.flutter-io.cn/packages/dio/install)。
**在你更新之前:大版本和次要版本可能会包含不兼容的重大改动。<br/>
请阅读 [迁移指南][] 了解完整的重大变更内容。**
[迁移指南]: https://pub.flutter-io.cn/documentation/dio/latest/topics/Migration%20Guide-topic.html
## 一个极简的示例
```dart
import 'package:dio/dio.dart';
final dio = Dio();
void getHttp() async {
final response = await dio.get('https://dart.dev');
print(response);
}
```
## Awesome dio
🎉 以下是一个与 Dio 相关的精选清单。
### 相关插件
<!-- 使用 https://pub.flutter-io.cn 作为管理网址 -->
| 仓库 | 最新版本 | 描述 |
|--------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------|
| [dio_cookie_manager](https://github.com/cfug/dio/blob/main/plugins/cookie_manager) | [](https://pub.flutter-io.cn/packages/dio_cookie_manager) | Cookie 管理 |
| [dio_http2_adapter](https://github.com/cfug/dio/blob/main/plugins/http2_adapter) | [](https://pub.flutter-io.cn/packages/dio_http2_adapter) | 支持 HTTP/2 的自定义适配器 |
| [native_dio_adapter](https://github.com/cfug/dio/blob/main/plugins/native_dio_adapter) | [](https://pub.flutter-io.cn/packages/native_dio_adapter) | 使用 cupertino_http 和 cronet_http 以适配器代理实现的原生网络请求功能。 |
| [dio_smart_retry](https://github.com/rodion-m/dio_smart_retry) | [](https://pub.flutter-io.cn/packages/dio_smart_retry) | 支持灵活地请求重试 |
| [http_certificate_pinning](https://github.com/diefferson/http_certificate_pinning) | [](https://pub.flutter-io.cn/packages/http_certificate_pinning) | 用于 Flutter 的 HTTPS 证书锁定 |
| [dio_intercept_to_curl](https://github.com/blackflamedigital/dio_intercept_to_curl) | [](https://pub.flutter-io.cn/packages/dio_intercept_to_curl) | 用于 Flutter 的 CURL 命令生成器 |
| [dio_cache_interceptor](https://github.com/llfbandit/dio_cache_interceptor) | [](https://pub.flutter-io.cn/packages/dio_cache_interceptor) | 具有多个符合 HTTP 指令的 HTTP 缓存拦截器, |
| [dio_http_cache](https://github.com/hurshi/dio-http-cache) | [](https://pub.flutter-io.cn/packages/dio_http_cache) | 类似 Android 中的 RxCache 的缓存管理 |
| [pretty_dio_logger](https://github.com/Milad-Akarie/pretty_dio_logger) | [](https://pub.flutter-io.cn/packages/pretty_dio_logger) | 基于拦截器的简明易读的请求日志打印 |
| [dio_image_provider](https://github.com/ueman/image_provider) | [](https://pub.flutter-io.cn/packages/dio_image_provider) | 基于 Dio 的图片加载 |
| [flutter_ume_kit_dio](https://github.com/cfug/flutter_ume_kits/tree/main/packages/flutter_ume_kit_dio) | [](https://pub.flutter-io.cn/packages/flutter_ume_kit_dio) | flutter_ume 上的 dio 调试插件 |
| [talker_dio_logger](https://github.com/Frezyx/talker/tree/master/packages/talker_dio_logger) | [](https://pub.flutter-io.cn/packages/talker_dio_logger) | 基于 talker 的轻量级和可定制的 dio 记录器 |
### 相关的项目
如果您也想提供第三方组件,请移步
[这里](https://github.com/cfug/dio/issues/347)。
## 示例
### 发起一个 `GET` 请求 :
```dart
import 'package:dio/dio.dart';
final dio = Dio();
void request() async {
Response response;
response = await dio.get('/test?id=12&name=dio');
print(response.data.toString());
// The below request is the same as above.
response = await dio.get(
'/test',
queryParameters: {'id': 12, 'name': 'dio'},
);
print(response.data.toString());
}
```
### 发起一个 `POST` 请求:
```dart
response = await dio.post('/test', data: {'id': 12, 'name': 'dio'});
```
### 发起多个并发请求
```dart
List<Response> responses = await Future.wait([dio.post('/info'), dio.get('/token')]);
```
### 下载文件
```dart
response = await dio.download(
'https://www.google.com/',
'${(await getTemporaryDirectory()).path}google.html',
);
```
### 以流的方式接收响应数据
```dart
final rs = await dio.get(
url,
options: Options(responseType: ResponseType.stream), // 设置接收类型为 `stream`
);
print(rs.data.stream); // 响应流
```
### 以二进制数组的方式接收响应数据
```dart
final rs = await dio.get(
url,
options: Options(responseType: ResponseType.bytes), // 设置接收类型为 `bytes`
);
print(rs.data); // 类型: List<int>
```
### 发送 `FormData`
```dart
final formData = FormData.fromMap({
'name': 'dio',
'date': DateTime.now().toIso8601String(),
});
final response = await dio.post('/info', data: formData);
```
### 通过 `FormData` 上传多个文件
```dart
final formData = FormData.fromMap({
'name': 'dio',
'date': DateTime.now().toIso8601String(),
'file': await MultipartFile.fromFile('./text.txt', filename: 'upload.txt'),
'files': [
await MultipartFile.fromFile('./text1.txt', filename: 'text1.txt'),
await MultipartFile.fromFile('./text2.txt', filename: 'text2.txt'),
]
});
final response = await dio.post('/info', data: formData);
```
### 监听发送(上传)数据进度
```dart
final response = await dio.post(
'https://www.dtworkroom.com/doris/1/2.0.0/test',
data: {'aa': 'bb' * 22},
onSendProgress: (int sent, int total) {
print('$sent $total');
},
);
```
### 以流的形式提交二进制数据
```dart
// Binary data
final postData = <int>[0, 1, 2];
await dio.post(
url,
data: Stream.fromIterable(postData.map((e) => [e])), // 构建 Stream<List<int>>
options: Options(
headers: {
Headers.contentLengthHeader: postData.length, // 设置 content-length.
},
),
);
```
注意:如果要监听提交进度,则必须设置content-length,否则是可选的。
你可以在这里查看 [全部示例](example)。
## Dio APIs
### 创建一个Dio实例,并配置它
> 建议在项目中使用Dio单例,这样便可对同一个dio实例发起的所有请求进行一些统一的配置,
> 比如设置公共header、请求基地址、超时时间等。
> 这里有一个在[Flutter工程中使用Dio单例](../example_flutter_app)
> (定义为top level变量)的示例供开发者参考。
你可以使用默认配置或传递一个可选 `BaseOptions`参数来创建一个Dio实例 :
```dart
final dio = Dio(); // With default `Options`.
void configureDio() {
// Update default configs.
dio.options.baseUrl = 'https://api.pub.dev';
dio.options.connectTimeout = Duration(seconds: 5);
dio.options.receiveTimeout = Duration(seconds: 3);
// Or create `Dio` with a `BaseOptions` instance.
final options = BaseOptions(
baseUrl: 'https://api.pub.dev',
connectTimeout: Duration(seconds: 5),
receiveTimeout: Duration(seconds: 3),
);
final anotherDio = Dio(options);
// Or clone the existing `Dio` instance with all fields.
final clonedDio = dio.clone();
}
```
Dio 的核心 API 是:
```dart
Future<Response<T>> request<T>(
String path, {
Object? data,
Map<String, dynamic>? queryParameters,
CancelToken? cancelToken,
Options? options,
ProgressCallback? onSendProgress,
ProgressCallback? onReceiveProgress,
});
```
```dart
final response = await dio.request(
'/test',
data: {'id': 12, 'name': 'dio'},
options: Options(method: 'GET'),
);
```
### 请求配置
在 Dio 中有两种配置概念:`BaseOptions` 和 `Options`。
`BaseOptions` 描述的是 Dio 实例的一套基本配置,而 `Options` 描述了单独请求的配置信息。
以上的配置会在发起请求时进行合并。
下面是 `Options` 的配置项:
```dart
/// HTTP 请求方法。
String method;
/// 发送数据的超时设置。
///
/// 超时时会抛出类型为 [DioExceptionType.sendTimeout] 的
/// [DioException]。
///
/// `null` 或 `Duration.zero` 即不设置超时。
Duration? sendTimeout;
/// 接收数据的超时设置。
///
/// 这里的超时对应的时间是:
/// - 在建立连接和第一次收到响应数据事件之前的超时。
/// - 每个数据事件传输的间隔时间,而不是接收的总持续时间。
///
/// 超时时会抛出类型为 [DioExceptionType.receiveTimeout] 的
/// [DioException]。
///
/// `null` 或 `Duration.zero` 即不设置超时。
Duration? receiveTimeout;
/// 可以在 [Interceptor]、[Transformer] 和
/// [Response.requestOptions] 中获取到的自定义对象。
Map<String, dynamic>? extra;
/// HTTP 请求头。
///
/// 请求头的键是否相等的判断大小写不敏感的。
/// 例如:`content-type` 和 `Content-Type` 会视为同样的请求头键。
Map<String, dynamic>? headers;
/// 是否保留请求头的大小写。
///
/// 默认值为 false。
///
/// 该选项在以下场景无效:
/// - XHR 不支持直接处理。
/// - 按照 HTTP/2 的标准,只支持小写请求头键。
bool? preserveHeaderCase;
/// 表示 [Dio] 处理请求响应数据的类型。
///
/// 默认值为 [ResponseType.json]。
/// [Dio] 会在请求响应的 content-type
/// 为 [Headers.jsonContentType] 时自动将响应字符串处理为 JSON 对象。
///
/// 在以下情况时,分别使用:
/// - `plain` 将数据处理为 `String`;
/// - `bytes` 将数据处理为完整的 bytes。
/// - `stream` 将数据处理为流式返回的二进制数据;
ResponseType? responseType;
/// 请求的 content-type。
///
/// 请求默认的 `content-type` 会由 [ImplyContentTypeInterceptor]
/// 根据发送数据的类型推断。它可以通过
/// [Interceptors.removeImplyContentTypeInterceptor] 移除。
String? contentType;
/// 判断当前返回的状态码是否可以视为请求成功。
ValidateStatus? validateStatus;
/// 是否在请求失败时仍然获取返回数据内容。
///
/// 默认为 true。
bool? receiveDataWhenStatusError;
/// 参考 [HttpClientRequest.followRedirects]。
///
/// 默认为 true。
bool? followRedirects;
/// 当 [followRedirects] 为 true 时,指定的最大重定向次数。
/// 如果请求超出了重定向次数上线,会抛出 [RedirectException]。
///
/// 默认为 5。
int? maxRedirects;
/// 参考 [HttpClientRequest.persistentConnection]。
///
/// 默认为 true。
bool? persistentConnection;
/// 对请求内容进行自定义编码转换。
///
/// 默认为 [Utf8Encoder]。
RequestEncoder? requestEncoder;
/// 对请求响应内容进行自定义解码转换。
///
/// 默认为 [Utf8Decoder]。
ResponseDecoder? responseDecoder;
/// 当请求参数以 `x-www-url-encoded` 方式发送时,如何处理集合参数。
///
/// 默认为 [ListFormat.multi]。
ListFormat? listFormat;
```
此处为 [完整的代码示例](../example_dart/lib/options.dart)。
### 响应数据
当请求成功时会返回一个Response对象,它包含如下字段:
```dart
/// 响应数据。可能已经被转换了类型, 详情请参考 [ResponseType]。
T? data;
/// 响应对应的请求配置。
RequestOptions requestOptions;
/// 响应的 HTTP 状态码。
int? statusCode;
/// 响应对应状态码的详情信息。
String? statusMessage;
/// 响应是否被重定向
bool isRedirect;
/// 请求连接经过的重定向列表。如果请求未经过重定向,则列表为空。
List<RedirectRecord> redirects;
/// 在 [RequestOptions] 中构造的自定义字段。
Map<String, dynamic> extra;
/// 响应对应的头数据。
Headers headers;
```
请求成功后,你可以访问到下列字段:
```dart
final response = await dio.get('https://pub.dev');
print(response.data);
print(response.headers);
print(response.requestOptions);
print(response.statusCode);
```
注意,`Response.extra` 与 `RequestOptions.extra` 是不同的实例,互相之间无关。
### 拦截器
每个 Dio 实例都可以添加任意多个拦截器,他们会组成一个队列,拦截器队列的执行顺序是先进先出。
通过使用拦截器,你可以在请求之前、响应之后和发生异常时(未被 `then` 或 `catchError` 处理)
做一些统一的预处理操作。
```dart
dio.interceptors.add(
InterceptorsWrapper(
onRequest: (RequestOptions options, RequestInterceptorHandler handler) {
// 如果你想完成请求并返回一些自定义数据,你可以使用 `handler.resolve(response)`。
// 如果你想终止请求并触发一个错误,你可以使用 `handler.reject(error)`。
return handler.next(options);
},
onResponse: (Response response, ResponseInterceptorHandler handler) {
// 如果你想终止请求并触发一个错误,你可以使用 `handler.reject(error)`。
return handler.next(response);
},
onError: (DioException error, ErrorInterceptorHandler handler) {
// 如果你想完成请求并返回一些自定义数据,你可以使用 `handler.resolve(response)`。
return handler.next(error);
},
),
);
```
一个简单的自定义拦截器示例:
```dart
import 'package:dio/dio.dart';
class CustomInterceptors extends Interceptor {
@override
void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
print('REQUEST[${options.method}] => PATH: ${options.path}');
super.onRequest(options, handler);
}
@override
void onResponse(Response response, ResponseInterceptorHandler handler) {
print('RESPONSE[${response.statusCode}] => PATH: ${response.requestOptions.path}');
super.onResponse(response, handler);
}
@override
Future onError(DioException err, ErrorInterceptorHandler handler) async {
print('ERROR[${err.response?.statusCode}] => PATH: ${err.requestOptions.path}');
super.onError(err, handler);
}
}
```
#### 完成和终止请求/响应
在所有拦截器中,你都可以改变请求执行流,
如果你想完成请求/响应并返回自定义数据,你可以 resolve 一个 `Response` 对象
或返回 `handler.resolve(data)` 的结果。
如果你想终止(触发一个错误,上层 `catchError` 会被调用)一个请求/响应,
那么可以 reject 一个`DioException` 对象或返回 `handler.reject(errMsg)` 的结果。
```dart
dio.interceptors.add(
InterceptorsWrapper(
onRequest: (options, handler) {
return handler.resolve(
Response(requestOptions: options, data: 'fake data'),
);
},
),
);
final response = await dio.get('/test');
print(response.data); // 'fake data'
```
#### QueuedInterceptor
如果同时发起多个网络请求,则它们是可以同时进入`Interceptor` 的(并行的),
而 `QueuedInterceptor` 提供了一种串行机制:
它可以保证请求进入拦截器时是串行的(前面的执行完后后面的才会进入拦截器)。
##### 例子
假设这么一个场景:出于安全原因,我们需要给所有的请求头中添加一个 `csrfToken`,
如果 `csrfToken` 不存在,我们先去请求 `csrfToken`,获取到 `csrfToken` 后再重试。
假设刚开始的时候 `csrfToken` 为 null,如果允许请求并发,则这些并发请求并行进入拦截器时
`csrfToken` 都为 null,所以它们都需要去请求 `csrfToken`,这会导致 `csrfToken` 被请求多次。
为了避免不必要的重复请求,可以使用 `QueuedInterceptor`, 这样只需要第一个请求处理一次即可。
完整的示例代码请点击 [这里](../example_dart/lib/queued_interceptor_crsftoken.dart).
#### 日志拦截器
我们可以添加 `LogInterceptor` 拦截器来自动打印请求和响应等日志:
**注意:** `LogInterceptor` 应该保持最后一个被添加到拦截器中,
否则在它之后进行处理的拦截器修改的内容将无法体现。
#### Dart
```dart
dio.interceptors.add(LogInterceptor(responseBody: false)); // 不输出响应内容体
```
**注意:** 默认的 `logPrint` 只会在 DEBUG 模式(启用了断言)
的情况下输出日志。
你也可以使用 `dart:developer` 中的 `log` 来输出日志(在 Flutter 中也可以使用)。
#### Flutter
在 Flutter 中你应该使用 `debugPrint` 来打印日志。
这样也会让调试日志能够通过 `flutter logs` 获取到。
**注意:** `debugPrint` 的意义 **不是只在 DEBUG 模式下打印**,
而是对输出内容进行节流,从而保证输出完整。
请不要在生产模式使用,除非你有意输出相关日志。
```dart
dio.interceptors.add(
LogInterceptor(
logPrint: (o) => debugPrint(o.toString()),
),
);
```
### 自定义拦截器
开发者可以通过继承 `Interceptor/QueuedInterceptor` 类来实现自定义拦截器。
这是一个简单的 [缓存拦截器](../example_dart/lib/custom_cache_interceptor.dart)。
## 错误处理
当请求过程中发生错误时, Dio 会将 `Error/Exception` 包装成一个 `DioException`:
```dart
try {
// 404
await dio.get('https://api.pub.dev/not-exist');
} on DioException catch (e) {
// The request was made and the server responded with a status code
// that falls out of the range of 2xx and is also not 304.
if (e.response != null) {
print(e.response.data)
print(e.response.headers)
print(e.response.requestOptions)
} else {
// Something happened in setting up or sending the request that triggered an Error
print(e.requestOptions)
print(e.message)
}
}
```
### DioException
```dart
/// 错误的请求对应的配置。
RequestOptions requestOptions;
/// 错误的请求对应的响应内容。如果请求未完成,响应内容可能为空。
Response? response;
/// 错误的类型。
DioExceptionType type;
/// 实际错误的内容。
Object? error;
/// 实际错误的堆栈。
StackTrace? stackTrace;
/// 错误信息。
String? message;
```
### DioExceptionType
见 [源码](lib/src/dio_exception.dart)。
## 使用 application/x-www-form-urlencoded 编码
默认情况下, Dio 会将请求数据(除了 `String` 类型)序列化为 JSON。
如果想要以 `application/x-www-form-urlencoded` 格式编码, 你可以设置 `contentType` :
```dart
// Instance level
dio.options.contentType = Headers.formUrlEncodedContentType;
// or only works once
dio.post(
'/info',
data: {'id': 5},
options: Options(contentType: Headers.formUrlEncodedContentType),
);
```
## 发送 FormData
Dio 支持发送 `FormData`, 请求数据将会以 `multipart/form-data` 方式编码,
`FormData` 中可以包含一个或多个文件。
```dart
final formData = FormData.fromMap({
'name': 'dio',
'date': DateTime.now().toIso8601String(),
'file': await MultipartFile.fromFile('./text.txt',filename: 'upload.txt')
});
final response = await dio.post('/info', data: formData);
```
你也可以指定封边 (boundary) 的名称,
封边名称会与额外的前缀和后缀一并组装成 `FormData` 的封边。
```dart
final formDataWithBoundaryName = FormData(
boundaryName: 'my-boundary-name',
);
```
> 通常情况下只有 POST 方法支持发送 FormData。
这里有一个完整的 [示例](../example_dart/lib/formdata.dart)。
### 多文件上传
多文件上传时,通过给 key 加中括号 `[]` 方式作为文件数组的标记,大多数后台也会通过 `key[]` 来读取多个文件。
然而 RFC 标准中并没有规定多文件上传必须要使用 `[]`,关键在于后台与客户端之间保持一致。
```dart
final formData = FormData.fromMap({
'files': [
MultipartFile.fromFileSync('path/to/upload1.txt', filename: 'upload1.txt'),
MultipartFile.fromFileSync('path/to/upload2.txt', filename: 'upload2.txt'),
],
});
```
最终编码时会 key 会为 `files[]`,
**如果不想添加 `[]`**,可以通过 `Formdata` 的 `files` 来构建:
```dart
final formData = FormData();
formData.files.addAll([
MapEntry(
'files',
MultipartFile.fromFileSync('./example/upload.txt',filename: 'upload.txt'),
),
MapEntry(
'files',
MultipartFile.fromFileSync('./example/upload.txt',filename: 'upload.txt'),
),
]);
```
### 复用 `FormData` 和 `MultipartFile`
如果你在重复调用的请求中使用 `FormData` 或者 `MultipartFile`,确保你每次使用的都是新实例。
常见的错误做法是将 `FormData` 赋值给一个共享变量,在每次请求中都使用这个变量。
这样的操作会加大 **无法序列化** 的错误出现的可能性。
你可以像以下的代码一样编写你的请求以避免出现这样的错误:
```dart
Future<void> _repeatedlyRequest() async {
Future<FormData> createFormData() async {
return FormData.fromMap({
'name': 'dio',
'date': DateTime.now().toIso8601String(),
'file': await MultipartFile.fromFile('./text.txt',filename: 'upload.txt'),
});
}
await dio.post('some-url', data: await createFormData());
}
```
## 转换器
转换器 `Transformer` 用于对请求数据和响应数据进行编解码处理。
Dio 实现了一个默认转换器 `DefaultTransformer`。
如果你想对请求和响应数据进行自定义编解码处理,可以提供自定义转换器并通过 `dio.transformer` 设置。
> `Transformer.transformRequest` 只在 `PUT`/`POST`/`PATCH` 方法中生效,
> 只有这些方法可以使用请求内容体 (request body)。
> 但是 `Transformer.transformResponse` 可以用于所有请求方法的返回数据。
### 在 Flutter 中进行设置
如果你在开发 Flutter 应用,强烈建议通过 `compute` 在单独的 isolate 中进行 JSON 解码,
从而避免在解析复杂 JSON 时导致的 UI 卡顿。
```dart
///
Map<String, dynamic> _parseAndDecode(String response) {
return jsonDecode(response) as Map<String, dynamic>;
}
Future<Map<String, dynamic>> parseJson(String text) {
return compute(_parseAndDecode, text);
}
void main() {
// 自定义 `jsonDecodeCallback`
dio.transformer = DefaultTransformer()..jsonDecodeCallback = parseJson;
runApp(MyApp());
}
```
### 其它示例
这里有一个 [自定义 Transformer 的示例](../example_dart/lib/transformer.dart)。
## HttpClientAdapter
`HttpClientAdapter` 是 `Dio` 和 `HttpClient` 之间的桥梁。
`Dio` 实现了一套标准且强大的 API,而 `HttpClient` 则是真正发起 HTTP 请求的对象。
我们通过 `HttpClientAdapter` 将 `Dio` 和 `HttpClient` 解耦,
这样一来便可以自由定制 HTTP 请求的底层实现。
Dio 使用 `IOHttpClientAdapter` 作为原生平台默认的桥梁,
`BrowserHttpClientAdapter` 作为 Web 平台的桥梁。
你可以通过 `HttpClientAdapter()` 来根据平台创建它们。
```dart
dio.httpClientAdapter = HttpClientAdapter();
```
如果你需要单独使用对应平台的适配器:
- 对于 Web 平台
```dart
import 'package:dio/browser.dart';
// ...
dio.httpClientAdapter = BrowserHttpClientAdapter();
```
- 对于原生平台:
```dart
import 'package:dio/io.dart';
// ...
dio.httpClientAdapter = IOHttpClientAdapter();
```
[示例](../example_dart/lib/adapter.dart) 中包含了一个简单的自定义桥接。
### 设置代理
`IOHttpClientAdapter` 提供了一个 `createHttpClient` 回调来设置底层 `HttpClient` 的代理:
```dart
import 'package:dio/io.dart';
void initAdapter() {
dio.httpClientAdapter = IOHttpClientAdapter(
createHttpClient: () {
final client = HttpClient();
client.findProxy = (uri) {
// 将请求代理至 localhost:8888。
// 请注意,代理会在你正在运行应用的设备上生效,而不是在宿主平台生效。
return 'PROXY localhost:8888';
};
return client;
},
);
}
```
完整的示例请查看 [这里](../example_dart/lib/proxy.dart)。
Web 平台不支持设置代理。
### HTTPS 证书校验
HTTPS 证书验证(或公钥固定)是指确保端侧与服务器的 TLS 连接的证书是期望的证书,从而减少中间人攻击的机会。
[OWASP](https://owasp.org/www-community/controls/Certificate_and_Public_Key_Pinning) 中解释了该理论。
**服务器响应证书**
与其他方法不同,此方法使用服务器本身的证书。
```dart
void initAdapter() {
const String fingerprint = 'ee5ce1dfa7a53657c545c62b65802e4272878dabd65c0aadcf85783ebb0b4d5c';
dio.httpClientAdapter = IOHttpClientAdapter(
createHttpClient: () {
// Don't trust any certificate just because their root cert is trusted.
final HttpClient client = HttpClient(context: SecurityContext(withTrustedRoots: false));
// You can test the intermediate / root cert here. We just ignore it.
client.badCertificateCallback = (cert, host, port) => true;
return client;
},
validateCertificate: (cert, host, port) {
// Check that the cert fingerprint matches the one we expect.
// We definitely require _some_ certificate.
if (cert == null) {
return false;
}
// Validate it any way you want. Here we only check that
// the fingerprint matches the OpenSSL SHA256.
return fingerprint == sha256.convert(cert.der).toString();
},
);
}
```
你可以使用 OpenSSL 读取密钥的 SHA-256:
```sh
openssl s_client -servername pinning-test.badssl.com -connect pinning-test.badssl.com:443 < /dev/null 2>/dev/null \
| openssl x509 -noout -fingerprint -sha256
# SHA256 Fingerprint=EE:5C:E1:DF:A7:A5:36:57:C5:45:C6:2B:65:80:2E:42:72:87:8D:AB:D6:5C:0A:AD:CF:85:78:3E:BB:0B:4D:5C
# (remove the formatting, keep only lower case hex characters to match the `sha256` above)
```
**证书颁发机构验证**
当您的服务器具有自签名证书时,可以用下面的方法,但它们不适用于 AWS 或 Let's Encrypt 等第三方颁发的证书。
有两种方法可以校验证书,假设我们的后台服务使用的是自签名证书,证书格式是 PEM 格式,我们将证书的内容保存在本地字符串中,
那么我们的校验逻辑如下:
```dart
void initAdapter() {
String PEM = 'XXXXX'; // root certificate content
dio.httpClientAdapter = IOHttpClientAdapter(
createHttpClient: () {
final client = HttpClient();
client.badCertificateCallback = (X509Certificate cert, String host, int port) {
return cert.pem == PEM; // Verify the certificate.
};
return client;
},
);
}
```
对于自签名的证书,我们也可以将其添加到本地证书信任链中,
这样证书验证时就会自动通过,而不会再走到 `badCertificateCallback` 回调中:
```dart
void initAdapter() {
String PEM = 'XXXXX'; // root certificate content
dio.httpClientAdapter = IOHttpClientAdapter(
onHttpClientCreate: (_) {
final SecurityContext sc = SecurityContext();
sc.setTrustedCertificates(File(pathToTheCertificate));
final HttpClient client = HttpClient(context: sc);
return client;
},
);
}
```
注意,通过 `setTrustedCertificates()` 设置的证书格式必须为 PEM 或 PKCS12,
如果证书格式为 PKCS12,则需将证书密码传入,
这样则会在代码中暴露证书密码,所以客户端证书校验不建议使用 PKCS12 格式的证书。
## HTTP/2 支持
[dio_http2_adapter](../plugins/http2_adapter) 提供了一个支持 HTTP/2 的桥接 。
## 请求取消
你可以通过 `CancelToken` 来取消发起的请求。
一个 `CancelToken` 可以给多个请求共用,
在共用时调用 `cancel()` 会取消对应的所有请求:
```dart
final cancelToken = CancelToken();
dio.get(url, cancelToken: cancelToken).catchError((DioException error) {
if (CancelToken.isCancel(error)) {
print('Request canceled: ${error.message}');
} else {
// handle error.
}
});
// Cancel the requests with "cancelled" message.
token.cancel('cancelled');
```
完整的示例请参考 [取消示例](../example_dart/lib/cancel_request.dart).
## 继承 Dio class
`Dio` 是一个拥有工厂构造函数的接口类,因此不能直接继承 `Dio`,
但是可以继承 `DioForNative` 或 `DioForBrowser`:
```dart
import 'package:dio/dio.dart';
import 'package:dio/io.dart';
// 在浏览器中,导入 'package:dio/browser.dart'。
class Http extends DioForNative {
Http([BaseOptions options]) : super(options) {
// 构造函数执行
}
}
```
我们也可以直接实现 `Dio` 接口类 :
```dart
class MyDio with DioMixin implements Dio {
// ...
}
```
## Web 平台跨域资源共享 (CORS)
在 Web 平台上发送网络请求时,如果请求不是一个 [简单请求][],
浏览器会自动向服务器发送 [CORS 预检][] (Pre-flight requests),
用于检查服务器是否支持跨域资源共享。
你可以参考简单请求的定义修改你的请求,或者为你的服务加上 CORS 中间件进行跨域处理。
[简单请求]: https://developer.mozilla.org/zh-CN/docs/Web/HTTP/CORS#%E7%AE%80%E5%8D%95%E8%AF%B7%E6%B1%82
[CORS 预检]: https://developer.mozilla.org/zh-CN/docs/Glossary/Preflight_request
================================================
FILE: dio/README.md
================================================
# dio
[](https://pub.dev/packages/dio)
[](https://pub.dev/packages/dio)
Language: English | [简体中文](README-ZH.md)
A powerful HTTP networking package for Dart/Flutter,
supports Global configuration, Interceptors, FormData,
Request cancellation, File uploading/downloading,
Timeout, Custom adapters, Transformers, etc.
> Don't forget to add [#dio](https://pub.dev/packages?q=topic%3Adio)
> topic to your published dio related packages!
> See more: https://dart.dev/tools/pub/pubspec#topics
<details>
<summary>Table of content</summary>
<!-- TOC -->
* [dio](#dio)
* [Get started](#get-started)
* [Install](#install)
* [Super simple to use](#super-simple-to-use)
* [Awesome dio](#awesome-dio)
* [Plugins](#plugins)
* [Examples](#examples)
* [Performing a `GET` request](#performing-a-get-request)
* [Performing a `POST` request](#performing-a-post-request)
* [Performing multiple concurrent requests](#performing-multiple-concurrent-requests)
* [Downloading a file](#downloading-a-file)
* [Get response stream](#get-response-stream)
* [Get response with bytes](#get-response-with-bytes)
* [Sending a `FormData`](#sending-a-formdata)
* [Uploading multiple files to server by FormData](#uploading-multiple-files-to-server-by-formdata)
* [Listening the uploading progress](#listening-the-uploading-progress)
* [Post binary data with Stream](#post-binary-data-with-stream)
* [Dio APIs](#dio-apis)
* [Creating an instance and set default configs](#creating-an-instance-and-set-default-configs)
* [Request Options](#request-options)
* [Response](#response)
* [Interceptors](#interceptors)
* [Resolve and reject the request](#resolve-and-reject-the-request)
* [QueuedInterceptor](#queuedinterceptor)
* [Example](#example)
* [LogInterceptor](#loginterceptor)
* [Dart](#dart)
* [Flutter](#flutter)
* [Custom Interceptor](#custom-interceptor)
* [Handling Errors](#handling-errors)
* [DioException](#dioexception)
* [DioExceptionType](#dioexceptiontype)
* [Using application/x-www-form-urlencoded format](#using-applicationx-www-form-urlencoded-format)
* [Sending FormData](#sending-formdata)
* [Multiple files upload](#multiple-files-upload)
* [Reuse `FormData`s and `MultipartFile`s](#reuse-formdatas-and-multipartfiles)
* [Transformer](#transformer)
* [Transformer example](#transformer-example)
* [HttpClientAdapter](#httpclientadapter)
* [Using proxy](#using-proxy)
* [HTTPS certificate verification](#https-certificate-verification)
* [HTTP/2 support](#http2-support)
* [Cancellation](#cancellation)
* [Extends Dio class](#extends-dio-class)
* [Cross-Origin Resource Sharing on Web (CORS)](#cross-origin-resource-sharing-on-web-cors)
<!-- TOC -->
</details>
## Get started
### Install
Add the `dio` package to your
[pubspec dependencies](https://pub.dev/packages/dio/install).
**Before you upgrade: Breaking changes might happen in major and minor versions of packages.<br/>
See the [Migration Guide][] for the complete breaking changes list.**
[Migration Guide]: https://pub.dev/documentation/dio/latest/topics/Migration%20Guide-topic.html
### Super simple to use
```dart
import 'package:dio/dio.dart';
final dio = Dio();
void getHttp() async {
final response = await dio.get('https://dart.dev');
print(response);
}
```
## Awesome dio
🎉 A curated list of awesome things related to dio.
### Plugins
[Plugins](https://pub.dev/documentation/dio/latest/topics/Plugins-topic.html)
Welcome to submit third-party plugins and related libraries
in [here](https://github.com/cfug/dio/issues/347).
## Examples
### Performing a `GET` request
```dart
import 'package:dio/dio.dart';
final dio = Dio();
void request() async {
Response response;
response = await dio.get('/test?id=12&name=dio');
print(response.data.toString());
// The below request is the same as above.
response = await dio.get(
'/test',
queryParameters: {'id': 12, 'name': 'dio'},
);
print(response.data.toString());
}
```
### Performing a `POST` request
```dart
response = await dio.post('/test', data: {'id': 12, 'name': 'dio'});
```
### Performing multiple concurrent requests
```dart
List<Response> responses = await Future.wait([dio.post('/info'), dio.get('/token')]);
```
### Downloading a file
```dart
response = await dio.download(
'https://pub.dev/',
(await getTemporaryDirectory()).path + 'pub.html',
);
```
### Get response stream
```dart
final rs = await dio.get(
url,
options: Options(responseType: ResponseType.stream), // Set the response type to `stream`.
);
print(rs.data.stream); // Response stream.
```
### Get response with bytes
```dart
final rs = await Dio().get<List<int>>(
url,
options: Options(responseType: ResponseType.bytes), // Set the response type to `bytes`.
);
print(rs.data); // Type: List<int>.
```
### Sending a `FormData`
```dart
final formData = FormData.fromMap({
'name': 'dio',
'date': DateTime.now().toIso8601String(),
});
final response = await dio.post('/info', data: formData);
```
### Uploading multiple files to server by FormData
```dart
final formData = FormData.fromMap({
'name': 'dio',
'date': DateTime.now().toIso8601String(),
'file': await MultipartFile.fromFile('./text.txt', filename: 'upload.txt'),
'files': [
await MultipartFile.fromFile('./text1.txt', filename: 'text1.txt'),
await MultipartFile.fromFile('./text2.txt', filename: 'text2.txt'),
]
});
final response = await dio.post('/info', data: formData);
```
### Listening the uploading progress
```dart
final response = await dio.post(
'https://www.dtworkroom.com/doris/1/2.0.0/test',
data: {'aa': 'bb' * 22},
onSendProgress: (int sent, int total) {
print('$sent $total');
},
);
```
### Post binary data with Stream
```dart
// Binary data
final postData = <int>[0, 1, 2];
await dio.post(
url,
data: Stream.fromIterable(postData.map((e) => [e])), // Creates a Stream<List<int>>.
options: Options(
headers: {
Headers.contentLengthHeader: postData.length, // Set the content-length.
},
),
);
```
Note: `content-length` must be set if you want to subscribe to the sending progress.
See all examples code [here](example).
## Dio APIs
### Creating an instance and set default configs
> It is recommended to use a singleton of `Dio` in projects, which can manage configurations like headers, base urls,
> and timeouts consistently.
> Here is an [example](../example_flutter_app) that use a singleton in Flutter.
You can create instance of Dio with an optional `BaseOptions` object:
```dart
final dio = Dio(); // With default `Options`.
void configureDio() {
// Set default configs
dio.options.baseUrl = 'https://api.pub.dev';
dio.options.connectTimeout = Duration(seconds: 5);
dio.options.receiveTimeout = Duration(seconds: 3);
// Or create `Dio` with a `BaseOptions` instance.
final options = BaseOptions(
baseUrl: 'https://api.pub.dev',
connectTimeout: Duration(seconds: 5),
receiveTimeout: Duration(seconds: 3),
);
final anotherDio = Dio(options);
// Or clone the existing `Dio` instance with all fields.
final clonedDio = dio.clone();
}
```
The core API in Dio instance is:
```dart
Future<Response<T>> request<T>(
String path, {
Object? data,
Map<String, dynamic>? queryParameters,
CancelToken? cancelToken,
Options? options,
ProgressCallback? onSendProgress,
ProgressCallback? onReceiveProgress,
});
```
```dart
final response = await dio.request(
'/test',
data: {'id': 12, 'name': 'dio'},
options: Options(method: 'GET'),
);
```
### Request Options
There are two request options concepts in the Dio library:
`BaseOptions` and `Options`.
The `BaseOptions` include a set of base settings for each `Dio()`,
and the `Options` describes the configuration for a single request.
These options will be merged when making requests.
The `Options` declaration is as follows:
```dart
/// The HTTP request method.
String method;
/// Timeout when sending data.
///
/// Throws the [DioException] with
/// [DioExceptionType.sendTimeout] type when timed out.
///
/// `null` or `Duration.zero` means no timeout limit.
Duration? sendTimeout;
/// Timeout when receiving data.
///
/// The timeout represents:
/// - a timeout before the connection is established
/// and the first received response bytes.
/// - the duration during data transfer of each byte event,
/// rather than the total duration of the receiving.
///
/// Throws the [DioException] with
/// [DioExceptionType.receiveTimeout] type when timed out.
///
/// `null` or `Duration.zero` means no timeout limit.
Duration? receiveTimeout;
/// Custom field that you can retrieve it later in [Interceptor],
/// [Transformer] and the [Response.requestOptions] object.
Map<String, dynamic>? extra;
/// HTTP request headers.
///
/// The keys of the header are case-insensitive,
/// e.g.: `content-type` and `Content-Type` will be treated as the same key.
Map<String, dynamic>? headers;
/// Whether the case of header keys should be preserved.
///
/// Defaults to false.
///
/// This option WILL NOT take effect on these circumstances:
/// - XHR ([HttpRequest]) does not support handling this explicitly.
/// - The HTTP/2 standard only supports lowercase header keys.
bool? preserveHeaderCase;
/// The type of data that [Dio] handles with options.
///
/// The default value is [ResponseType.json].
/// [Dio] will parse response string to JSON object automatically
/// when the content-type of response is [Headers.jsonContentType].
///
/// See also:
/// - `plain` if you want to receive the data as `String`.
/// - `bytes` if you want to receive the data as the complete bytes.
/// - `stream` if you want to receive the data as streamed binary bytes.
ResponseType? responseType;
/// The request content-type.
///
/// The default `content-type` for requests will be implied by the
/// [ImplyContentTypeInterceptor] according to the type of the request payload.
/// The interceptor can be removed by
/// [Interceptors.removeImplyContentTypeInterceptor].
String? contentType;
/// Defines whether the request is considered to be successful
/// with the given status code.
/// The request will be treated as succeed if the callback returns true.
ValidateStatus? validateStatus;
/// Whether to retrieve the data if status code indicates a failed request.
///
/// Defaults to true.
bool? receiveDataWhenStatusError;
/// See [HttpClientRequest.followRedirects].
///
/// Defaults to true.
bool? followRedirects;
/// The maximum number of redirects when [followRedirects] is `true`.
/// [RedirectException] will be thrown if redirects exceeded the limit.
///
/// Defaults to 5.
int? maxRedirects;
/// See [HttpClientRequest.persistentConnection].
///
/// Defaults to true.
bool? persistentConnection;
/// The default request encoder is [Utf8Encoder], you can set custom
/// encoder by this option.
RequestEncoder? requestEncoder;
/// The default response decoder is [Utf8Decoder], you can set custom
/// decoder by this option, it will be used in [Transformer].
ResponseDecoder? responseDecoder;
/// Indicates the format of collection data in request query parameters and
/// `x-www-url-encoded` body data.
///
/// Defaults to [ListFormat.multi].
ListFormat? listFormat;
```
There is a complete example [here](../example_dart/lib/options.dart).
### Response
The response for a request contains the following information.
```dart
/// Response body. may have been transformed, please refer to [ResponseType].
T? data;
/// The corresponding request info.
RequestOptions requestOptions;
/// HTTP status code.
int? statusCode;
/// Returns the reason phrase associated with the status code.
/// The reason phrase must be set before the body is written
/// to. Setting the reason phrase after writing to the body.
String? statusMessage;
/// Whether this response is a redirect.
/// ** Attention **: Whether this field is available depends on whether the
/// implementation of the adapter supports it or not.
bool isRedirect;
/// The series of redirects this connection has been through. The list will be
/// empty if no redirects were followed. [redirects] will be updated both
/// in the case of an automatic and a manual redirect.
///
/// ** Attention **: Whether this field is available depends on whether the
/// implementation of the adapter supports it or not.
List<RedirectRecord> redirects;
/// Custom fields that only for the [Response].
Map<String, dynamic> extra;
/// Response headers.
Headers headers;
```
When request is succeed, you will receive the response as follows:
```dart
final response = await dio.get('https://pub.dev');
print(response.data);
print(response.headers);
print(response.requestOptions);
print(response.statusCode);
```
Be aware, the `Response.extra` is different from `RequestOptions.extra`,
they are not related to each other.
### Interceptors
For each dio instance, we can add one or more interceptors,
by which we can intercept requests, responses, and errors
before they are handled by `then` or `catchError`.
```dart
dio.interceptors.add(
InterceptorsWrapper(
onRequest: (RequestOptions options, RequestInterceptorHandler handler) {
// Do something before request is sent.
// If you want to resolve the request with custom data,
// you can resolve a `Response` using `handler.resolve(response)`.
// If you want to reject the request with a error message,
// you can reject with a `DioException` using `handler.reject(dioError)`.
return handler.next(options);
},
onResponse: (Response response, ResponseInterceptorHandler handler) {
// Do something with response data.
// If you want to reject the request with a error message,
// you can reject a `DioException` object using `handler.reject(dioError)`.
return handler.next(response);
},
onError: (DioException error, ErrorInterceptorHandler handler) {
// Do something with response error.
// If you want to resolve the request with some custom data,
// you can resolve a `Response` object using `handler.resolve(response)`.
return handler.next(error);
},
),
);
```
Simple interceptor example:
```dart
import 'package:dio/dio.dart';
class CustomInterceptors extends Interceptor {
@override
void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
print('REQUEST[${options.method}] => PATH: ${options.path}');
super.onRequest(options, handler);
}
@override
void onResponse(Response response, ResponseInterceptorHandler handler) {
print('RESPONSE[${response.statusCode}] => PATH: ${response.requestOptions.path}');
super.onResponse(response, handler);
}
@override
Future onError(DioException err, ErrorInterceptorHandler handler) async {
print('ERROR[${err.response?.statusCode}] => PATH: ${err.requestOptions.path}');
super.onError(err, handler);
}
}
```
#### Resolve and reject the request
In all interceptors, you can interfere with their execution flow.
If you want to resolve the request/response with some custom data,
you can call `handler.resolve(Response)`.
If you want to reject the request/response with a error message,
you can call `handler.reject(dioError)` .
```dart
dio.interceptors.add(
InterceptorsWrapper(
onRequest: (options, handler) {
return handler.resolve(
Response(requestOptions: options, data: 'fake data'),
);
},
),
);
final response = await dio.get('/test');
print(response.data); // 'fake data'
```
#### QueuedInterceptor
`Interceptor` can be executed concurrently, that is,
all the requests enter the interceptor at once, rather than executing sequentially.
However, in some cases we expect that requests enter the interceptor sequentially like #590.
Therefore, we need to provide a mechanism for sequential access (step by step)
to interceptors and `QueuedInterceptor` can solve this problem.
##### Example
Because of security reasons, we need all the requests to set up
a `csrfToken` in the header, if `csrfToken` does not exist,
we need to request a csrfToken first, and then perform the network request,
because the request csrfToken progress is asynchronous,
so we need to execute this async request in request interceptor.
For the complete code see [here](../example_dart/lib/queued_interceptor_crsftoken.dart).
#### LogInterceptor
You can apply the `LogInterceptor` to log requests and responses automatically.
**Note:** `LogInterceptor` should always be the last interceptor added,
otherwise modifications by following interceptors will not be logged.
#### Dart
```dart
dio.interceptors.add(LogInterceptor(responseBody: false)); // Do not output responses body.
```
**Note:** When using the default `logPrint` function, logs will only be printed
in DEBUG mode (when the assertion is enabled).
Alternatively `dart:developer`'s log can also be used to log messages (available in Flutter too).
#### Flutter
When using Flutter, Flutters own `debugPrint` function should be used.
This ensures, that debug messages are also available via `flutter logs`.
**Note:** `debugPrint` **does not mean print logs under the DEBUG mode**,
it's a throttled function which helps to print full logs without truncation.
Do not use it under any production environment unless you're intended to.
```dart
dio.interceptors.add(
LogInterceptor(
logPrint: (o) => debugPrint(o.toString()),
),
);
```
#### Custom Interceptor
You can customize interceptor by extending the `Interceptor/QueuedInterceptor` class.
There is an example that implementing a simple cache policy:
[custom cache interceptor](../example_dart/lib/custom_cache_interceptor.dart).
## Handling Errors
When an error occurs, Dio will wrap the `Error/Exception` to a `DioException`:
```dart
try {
// 404
await dio.get('https://api.pub.dev/not-exist');
} on DioException catch (e) {
// The request was made and the server responded with a status code
// that falls out of the range of 2xx and is also not 304.
if (e.response != null) {
print(e.response.data)
print(e.response.headers)
print(e.response.requestOptions)
} else {
// Something happened in setting up or sending the request that triggered an Error
print(e.requestOptions)
print(e.message)
}
}
```
### DioException
```dart
/// The request info for the request that throws exception.
RequestOptions requestOptions;
/// Response info, it may be `null` if the request can't reach to the
/// HTTP server, for example, occurring a DNS error, network is not available.
Response? response;
/// The type of the current [DioException].
DioExceptionType type;
/// The original error/exception object;
/// It's usually not null when `type` is [DioExceptionType.unknown].
Object? error;
/// The stacktrace of the original error/exception object;
/// It's usually not null when `type` is [DioExceptionType.unknown].
StackTrace? stackTrace;
/// The error message that throws a [DioException].
String? message;
```
### DioExceptionType
See [the source code](lib/src/dio_exception.dart).
## Using application/x-www-form-urlencoded format
By default, Dio serializes request data (except `String` type) to `JSON`.
To send data in the `application/x-www-form-urlencoded` format instead:
```dart
// Instance level
dio.options.contentType = Headers.formUrlEncodedContentType;
// or only works once
dio.post(
'/info',
data: {'id': 5},
options: Options(contentType: Headers.formUrlEncodedContentType),
);
```
## Sending FormData
You can also send `FormData` with Dio, which will send data in the `multipart/form-data`,
and it supports uploading files.
```dart
final formData = FormData.fromMap({
'name': 'dio',
'date': DateTime.now().toIso8601String(),
'file': await MultipartFile.fromFile('./text.txt', filename: 'upload.txt'),
});
final response = await dio.post('/info', data: formData);
```
You can also specify your desired boundary name which will be used
to construct boundaries of every `FormData` with additional prefix and suffix.
```dart
final formDataWithBoundaryName = FormData(
boundaryName: 'my-boundary-name',
);
```
> `FormData` is supported with the POST method typically.
There is a complete example [here](../example_dart/lib/formdata.dart).
### Multiple files upload
There are two ways to add multiple files to `FormData`,
the only difference is that upload keys are different for array types。
```dart
final formData = FormData.fromMap({
'files': [
MultipartFile.fromFileSync('path/to/upload1.txt', filename: 'upload1.txt'),
MultipartFile.fromFileSync('path/to/upload2.txt', filename: 'upload2.txt'),
],
});
```
The upload key eventually becomes `files[]`.
This is because many back-end services add a middle bracket to key
when they get an array of files.
**If you don't want a list literal**,
you should create FormData as follows (Don't use `FormData.fromMap`):
```dart
final formData = FormData();
formData.files.addAll([
MapEntry(
'files',
MultipartFile.fromFileSync('./example/upload.txt',filename: 'upload.txt'),
),
MapEntry(
'files',
MultipartFile.fromFileSync('./example/upload.txt',filename: 'upload.txt'),
),
]);
```
### Reuse `FormData`s and `MultipartFile`s
You should make a new `FormData` or `MultipartFile` every time in repeated requests.
A typical wrong behavior is setting the `FormData` as a variable and using it in every request.
It can be easy for the *Cannot finalize* exceptions to occur.
To avoid that, write your requests like the below code:
```dart
Future<void> _repeatedlyRequest() async {
Future<FormData> createFormData() async {
return FormData.fromMap({
'name': 'dio',
'date': DateTime.now().toIso8601String(),
'file': await MultipartFile.fromFile('./text.txt',filename: 'upload.txt'),
});
}
await dio.post('some-url', data: await createFormData());
}
```
## Transformer
`Transformer` allows changes to the request/response data
before it is sent/received to/from the server.
Dio has already implemented a `BackgroundTransformer` as default,
which calls `jsonDecode` in an isolate if the response is larger than 50 KB.
If you want to customize the transformation of request/response data,
you can provide a `Transformer` by your self,
and replace the `BackgroundTransformer` by setting the `dio.transformer`.
> `Transformer.transformRequest` only takes effect when request with `PUT`/`POST`/`PATCH`,
> they're methods that can contain the request body.
> `Transformer.transformResponse` however, can be applied to all types of responses.
### Transformer example
There is an example for [customizing Transformer](../example_dart/lib/transformer.dart).
## HttpClientAdapter
`HttpClientAdapter` is a bridge between `Dio` and `HttpClient`.
`Dio` implements standard and friendly APIs for developer.
`HttpClient` is the real object that makes Http requests.
We can use any `HttpClient` not just `dart:io:HttpClient` to make HTTP requests.
And all we need is providing a `HttpClientAdapter`.
The default `HttpClientAdapter` for Dio is `IOHttpClientAdapter` on native platforms,
and `BrowserHttpClientAdapter` on the Web platform.
They can be initiated by calling the `HttpClientAdapter()`.
```dart
dio.httpClientAdapter = HttpClientAdapter();
```
If you want to use platform adapters explicitly:
- For the Web platform:
```dart
import 'package:dio/browser.dart';
// ...
dio.httpClientAdapter = BrowserHttpClientAdapter();
```
- For native platforms:
```dart
import 'package:dio/io.dart';
// ...
dio.httpClientAdapter = IOHttpClientAdapter();
```
[Here](../example_dart/lib/adapter.dart) is a simple example to custom adapter.
### Using proxy
`IOHttpClientAdapter` provide a callback to set proxy to `dart:io:HttpClient`,
for example:
```dart
import 'package:dio/io.dart';
void initAdapter() {
dio.httpClientAdapter = IOHttpClientAdapter(
createHttpClient: () {
final client = HttpClient();
// Config the client.
client.findProxy = (uri) {
// Forward all request to proxy "localhost:8888".
// Be aware, the proxy should went through you running device,
// not the host platform.
return 'PROXY localhost:8888';
};
// You can also create a new HttpClient for Dio instead of returning,
// but a client must being returned here.
return client;
},
);
}
```
There is a complete example [here](../example_dart/lib/proxy.dart).
Web does not support to set proxy.
### HTTPS certificate verification
HTTPS certificate verification (or public key pinning) refers to the process of ensuring that
the certificates protecting the TLS connection to the server are the ones you expect them to be.
The intention is to reduce the chance of a man-in-the-middle attack.
The theory is covered by [OWASP](https://owasp.org/www-community/controls/Certificate_and_Public_Key_Pinning).
_Server Response Certificate_
Unlike other methods, this one works with the certificate of the server itself.
```dart
void initAdapter() {
const String fingerprint = 'ee5ce1dfa7a53657c545c62b65802e4272878dabd65c0aadcf85783ebb0b4d5c';
dio.httpClientAdapter = IOHttpClientAdapter(
createHttpClient: () {
// Don't trust any certificate just because their root cert is trusted.
final HttpClient client = HttpClient(context: SecurityContext(withTrustedRoots: false));
// You can test the intermediate / root cert here. We just ignore it.
client.badCertificateCallback = (cert, host, port) => true;
return client;
},
validateCertificate: (cert, host, port) {
// Check that the cert fingerprint matches the one we expect.
// We definitely require _some_ certificate.
if (cert == null) {
return false;
}
// Validate it any way you want. Here we only check that
// the fingerprint matches the OpenSSL SHA256.
return fingerprint == sha256.convert(cert.der).toString();
},
);
}
```
You can use openssl to read the SHA256 value of a certificate:
```sh
openssl s_client -servername pinning-test.badssl.com -connect pinning-test.badssl.com:443 < /dev/null 2>/dev/null \
| openssl x509 -noout -fingerprint -sha256
# SHA256 Fingerprint=EE:5C:E1:DF:A7:A5:36:57:C5:45:C6:2B:65:80:2E:42:72:87:8D:AB:D6:5C:0A:AD:CF:85:78:3E:BB:0B:4D:5C
# (remove the formatting, keep only lower case hex characters to match the `sha256` above)
```
_Certificate Authority Verification_
These methods work well when your server has a self-signed certificate,
but they don't work for certificates issued by a 3rd party like AWS or Let's Encrypt.
There are two ways to verify the root of the https certificate chain provided by the server.
Suppose the certificate format is PEM, the code like:
```dart
void initAdapter() {
String PEM = 'XXXXX'; // root certificate content
dio.httpClientAdapter = IOHttpClientAdapter(
createHttpClient: () {
final client = HttpClient();
client.badCertificateCallback = (X509Certificate cert, String host, int port) {
return cert.pem == PEM; // Verify the certificate.
};
return client;
},
);
}
```
Another way is creating a `SecurityContext` when create the `HttpClient`:
```dart
void initAdapter() {
String PEM = 'XXXXX'; // root certificate content
dio.httpClientAdapter = IOHttpClientAdapter(
onHttpClientCreate: (_) {
final SecurityContext sc = SecurityContext();
sc.setTrustedCertificates(File(pathToTheCertificate));
final HttpClient client = HttpClient(context: sc);
return client;
},
);
}
```
In this way, the format of `setTrustedCertificates()` must be PEM or PKCS12.
PKCS12 requires password to use, which will expose the password in the code,
so it's not recommended to use in common cases.
## HTTP/2 support
[dio_http2_adapter](../plugins/http2_adapter) is a Dio `HttpClientAdapter`
which supports HTTP/2.
## Cancellation
You can cancel a request using a `CancelToken`.
One token can be shared with multiple requests.
When a token's `cancel()` is invoked, all requests with this token will be cancelled.
```dart
final cancelToken = CancelToken();
dio.get(url, cancelToken: cancelToken).catchError((DioException error) {
if (CancelToken.isCancel(error)) {
print('Request canceled: ${error.message}');
} else {
// handle error.
}
});
// Cancel the requests with "cancelled" message.
token.cancel('cancelled');
```
There is a complete example [here](../example_dart/lib/cancel_request.dart).
## Extends Dio class
`Dio` is an abstract class with factory constructor,
so we don't extend `Dio` class direct.
We can extend `DioForNative` or `DioForBrowser` instead, for example:
```dart
import 'package:dio/dio.dart';
import 'package:dio/io.dart';
// If in browser, import 'package:dio/browser.dart'.
class Http extends DioForNative {
Http([BaseOptions options]) : super(options) {
// do something
}
}
```
We can also implement a custom `Dio` client:
```dart
class MyDio with DioMixin implements Dio {
// ...
}
```
## Cross-Origin Resource Sharing on Web (CORS)
If a request is not a [simple request][],
the Web browser will send a [CORS preflight request][]
that checks to see if the CORS protocol is understood
and a server is aware using specific methods and headers.
You can modify your requests to match the definition of simple request,
or add a CORS middleware for your service to handle CORS requests.
[simple request]: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple_requests
[CORS preflight request]: https://developer.mozilla.org/en-US/docs/Glossary/Preflight_request
================================================
FILE: dio/analysis_options.yaml
================================================
include: ../analysis_options.yaml
================================================
FILE: dio/dart_test.yaml
================================================
file_reporters:
json: build/reports/test-results.json
presets:
# empty placeholders required in CI scripts
all:
default:
min:
stable:
beta:
tags:
tls:
skip: "Skipping TLS test with specific setup requirements by default. Use '-P all' to run all tests."
presets:
all:
skip: false
default:
skip: true
gc: # We have that tag, but we are not skipping in any preset.
override_platforms:
chrome:
settings:
headless: true
firefox:
settings:
# headless argument has to be set explicitly for non-chrome browsers
arguments: --headless
executable:
# https://github.com/dart-lang/test/pull/2195
mac_os: '/Applications/Firefox.app/Contents/MacOS/firefox'
================================================
FILE: dio/dartdoc_options.yaml
================================================
dartdoc:
showUndocumentedCategories: true
categories:
"Migration Guide":
markdown: doc/migration_guide.md
"Plugins":
markdown: doc/plugins.md
================================================
FILE: dio/dio.iml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/.dart_tool" />
<excludeFolder url="file://$MODULE_DIR$/.pub" />
<excludeFolder url="file://$MODULE_DIR$/build" />
</content>
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Dart SDK" level="project" />
<orderEntry type="library" name="Dart Packages" level="project" />
</component>
</module>
================================================
FILE: dio/doc/migration_guide.md
================================================
# Migration Guide
This document gathered all breaking changes and migrations requirement between versions.
<!--
When new content need to be added to the migration guide, make sure they're following the format:
1. Add a version in the *Breaking versions* section, with a version anchor.
2. Use *Summary* and *Details* to introduce the migration.
-->
## Breaking versions
- [5.0.0](#500)
- [4.0.0](#400)
## 5.0.0
### Summary
- `get` and `getUri` in `Dio` has different signature.
- `DefaultHttpClientAdapter` is now named `IOHttpClientAdapter`,
and the platform independent adapter can be initiated by `HttpClientAdapter()` which is a factory method.
- Adapters that extends `HttpClientAdapter` must now `implements` instead of `extends`.
- `DioError` has separate constructors and all fields are annotated as final.
- `DioErrorType` has different values.
- Imports are split into new libraries:
- `dio/io.dart` is for natives specific classes;
- `dio/browser.dart` is for web specific classes.
- `connectTimeout`, `sendTimeout`, and `receiveTimeout` are now `Duration` instead of `int`.
### Details
#### `get` and `getUri`
```diff
Future<Response<T>> get<T>(
String path, {
+ Object? data,
Map<String, dynamic>? queryParameters,
Options? options,
CancelToken? cancelToken,
ProgressCallback? onReceiveProgress,
});
```
```diff
Future<Response<T>> getUri<T>(
Uri uri, {
+ Object? data,
Map<String, dynamic>? queryParameters,
Options? options,
CancelToken? cancelToken,
ProgressCallback? onReceiveProgress,
});
```
#### `HttpClientAdapter`
Before:
```dart
void initAdapter() {
final dio = Dio();
// For natives.
dio.httpClientAdapter = DefaultHttpClientAdapter();
// For web.
dio.httpClientAdapter = BrowserHttpClientAdapter();
}
```
After:
```dart
void initAdapter() {
final dio = Dio();
// Universal adapter that create the adapter for the corresponding platform.
dio.httpClientAdapter = HttpClientAdapter();
// For natives.
dio.httpClientAdapter = IOHttpClientAdapter();
// For web.
dio.httpClientAdapter = BrowserHttpClientAdapter();
}
```
#### Implementing `HttpClientAdapter`
Before:
```dart
class ExampleAdapter extends HttpClientAdapter { /* ... */ }
```
After:
```dart
class ExampleAdapter implements HttpClientAdapter { /* ... */ }
```
#### Const `DioError`
Before:
```dart
Never throwDioError() {
final error = DioError(request: requestOptions, error: e);
error.message = 'Custom message.';
error.stackTrace = StackTrace.current;
throw error;
}
```
After:
```dart
Never throwDioError() {
DioError error = DioError(
request: requestOptions,
error: e,
stackTrace: StackTrace.current
);
error = error.copyWith(message: 'Custom message.');
throw error;
}
```
#### `DioErrorType` values update
| Before | After |
|:---------------|:------------------|
| N/A | badCertificate |
| response | badResponse |
| connectTimeout | connectionTimeout |
| other | unknown |
#### `Duration` instead of `int` for timeouts
Before:
```dart
void request() {
final dio = Dio(
BaseOptions(
connectTimeout: 5000,
sendTimeout: 5000,
receiveTimeout: 10000,
),
);
}
```
After:
```dart
void request() {
final dio = Dio(
BaseOptions(
connectTimeout: const Duration(seconds: 5),
sendTimeout: const Duration(seconds: 5),
receiveTimeout: const Duration(seconds: 10),
),
);
}
```
## 4.0.0
### Details
1. **Null safety support** (Dart >= 2.12).
2. **The `Interceptor` APIs signature has changed**.
3. Rename `options.merge` to `options.copyWith`.
4. Rename `DioErrorType` enums from uppercase to camel style.
5. Delete `dio.resolve` and `dio.reject` APIs (use `handler` instead in interceptors).
6. Class `BaseOptions` no longer inherits from `Options` class.
7. Change `requestStream` type of `HttpClientAdapter.fetch` from `Stream<List<int>>` to `Stream<Uint8List>`.
8. Download API: Add real uri and redirect information to headers.
================================================
FILE: dio/doc/plugins.md
================================================
<!-- Use https://pub.dev for the hosted URL. -->
| Repository | Version | Description |
|--------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------|
| [dio_cookie_manager](https://github.com/cfug/dio/blob/main/plugins/cookie_manager) | [](https://pub.dev/packages/dio_cookie_manager) | A cookie manager for Dio |
| [dio_http2_adapter](https://github.com/cfug/dio/blob/main/plugins/http2_adapter) | [](https://pub.dev/packages/dio_http2_adapter) | A Dio HttpClientAdapter which support Http/2.0 |
| [native_dio_adapter](https://github.com/cfug/dio/blob/main/plugins/native_dio_adapter) | [](https://pub.dev/packages/native_dio_adapter) | An adapter for Dio which makes use of cupertino_http and cronet_http to delegate HTTP requests to the native platform. |
| [dio_smart_retry](https://github.com/rodion-m/dio_smart_retry) | [](https://pub.dev/packages/dio_smart_retry) | Flexible retry library for Dio |
| [http_certificate_pinning](https://github.com/diefferson/http_certificate_pinning) | [](https://pub.dev/packages/http_certificate_pinning) | Https Certificate pinning for Flutter |
| [dio_intercept_to_curl](https://github.com/blackflamedigital/dio_intercept_to_curl) | [](https://pub.dev/packages/dio_intercept_to_curl) | A Flutter curl-command generator for Dio. |
| [dio_cache_interceptor](https://github.com/llfbandit/dio_cache_interceptor) | [](https://pub.dev/packages/dio_cache_interceptor) | Dio HTTP cache interceptor with multiple stores respecting HTTP directives (or not) |
| [dio_http_cache](https://github.com/hurshi/dio-http-cache) | [](https://pub.dev/packages/dio_http_cache) | A simple cache library for Dio like Rxcache in Android |
| [pretty_dio_logger](https://github.com/Milad-Akarie/pretty_dio_logger) | [](https://pub.dev/packages/pretty_dio_logger) | Pretty Dio logger is a Dio interceptor that logs network calls in a pretty, easy to read format. |
| [dio_image_provider](https://github.com/ueman/image_provider) | [](https://pub.dev/packages/dio_image_provider) | An image provider which makes use of package:dio to instead of dart:io |
| [flutter_ume_kit_dio](https://github.com/cfug/flutter_ume_kits/tree/main/packages/flutter_ume_kit_dio) | [](https://pub.dev/packages/flutter_ume_kit_dio) | A debug kit of dio on flutter_ume |
| [sentry_dio](https://github.com/getsentry/sentry-dart) | [](https://pub.dev/packages/sentry_dio) | An integration which adds support for performance tracing for the Dio package. |
| [talker_dio_logger](https://github.com/Frezyx/talker/tree/master/packages/talker_dio_logger) | [](https://pub.dev/packages/talker_dio_logger) | Colorful and customizable dio logger with a lightweight design and talker additional functionality |
================================================
FILE: dio/example/dio.dart
================================================
import 'package:dio/dio.dart';
/// More examples see https://github.com/cfug/dio/tree/main/dio#examples
void main() async {
final dio = Dio();
final response = await dio.get('https://pub.dev');
print(response.data);
}
================================================
FILE: dio/lib/browser.dart
================================================
export 'src/adapters/browser_adapter.dart' show BrowserHttpClientAdapter;
export 'src/dio/dio_for_browser.dart' show DioForBrowser;
================================================
FILE: dio/lib/dio.dart
================================================
/// A powerful HTTP client for Dart and Flutter, which supports global settings,
/// [Interceptors], [FormData], aborting and canceling a request,
/// files uploading and downloading, requests timeout, custom adapters, etc.
/// {@category Migration Guide}
/// {@category Plugins}
library dio;
export 'src/adapter.dart';
export 'src/cancel_token.dart';
export 'src/dio.dart';
export 'src/dio_exception.dart';
export 'src/dio_mixin.dart' hide InterceptorState, InterceptorResultType;
export 'src/form_data.dart';
export 'src/headers.dart';
export 'src/interceptors/log.dart';
export 'src/multipart_file.dart';
export 'src/options.dart';
export 'src/parameter.dart';
export 'src/redirect_record.dart';
export 'src/response.dart';
export 'src/transformer.dart';
================================================
FILE: dio/lib/fix_data/fix.yaml
================================================
version: 1
transforms:
# Changes made in https://github.com/cfug/diox/pull/14
- title: "Migrate to 'IOHttpClientAdapter'"
date: 2022-11-07
element:
uris: ['dio.dart', 'src/adapter.dart', 'src/adapters/io_adapter.dart']
class: 'DefaultHttpClientAdapter'
changes:
- kind: 'rename'
newName: 'IOHttpClientAdapter'
# Changes made in https://github.com/cfug/diox/pull/62
- title: "Migrate to 'BackgroundTransformer'"
date: 2023-01-31
element:
uris: ['dio.dart', 'src/transformer.dart']
class: 'DefaultTransformer'
changes:
- kind: 'rename'
newName: 'BackgroundTransformer'
# Changes made in https://github.com/cfug/dio/pull/1812
- title: "Migrate to 'CreateHttpClient'"
date: 2023-05-14
element:
uris: ['dio.dart', 'src/adapters/io_adapter.dart']
typedef: 'OnHttpClientCreate'
changes:
- kind: 'rename'
newName: 'CreateHttpClient'
- kind: 'removeParameter'
index: 0
- title: "Migrate to 'createHttpClient'"
date: 2023-05-14
element:
uris: ['dio.dart', 'src/adapters/io_adapter.dart']
constructor: ''
inClass: 'IOHttpClientAdapter'
changes:
- kind: 'renameParameter'
oldName: 'onHttpClientCreate'
newName: 'createHttpClient'
# Changes made in https://github.com/cfug/dio/pull/1803
- title: "Migrate to 'DioException'"
date: 2023-05-15
element:
uris: ['dio.dart', 'src/dio_exception.dart', 'src/dio_error.dart']
class: 'DioError'
changes:
- kind: 'rename'
newName: 'DioException'
# Changes made in https://github.com/cfug/dio/pull/1803
- title: "Migrate to 'DioExceptionType'"
date: 2023-05-15
element:
uris: ['dio.dart', 'src/dio_exception.dart', 'src/dio_error.dart']
class: 'DioErrorType'
changes:
- kind: 'rename'
newName: 'DioExceptionType'
# Changes made in https://github.com/cfug/dio/pull/1903
- title: "Migrate to 'MultipartFile.fromStream'"
date: 2023-06-25
element:
uris: ['dio.dart', 'src/multipart_file.dart']
constructor: ''
inClass: 'MultipartFile'
changes:
- kind: 'rename'
newName: 'fromStream'
================================================
FILE: dio/lib/io.dart
================================================
export 'src/adapters/io_adapter.dart' hide createAdapter;
export 'src/dio/dio_for_native.dart' show DioForNative;
================================================
FILE: dio/lib/src/adapter.dart
================================================
import 'dart:convert';
import 'dart:typed_data';
import 'package:meta/meta.dart';
import 'adapters/io_adapter.dart'
if (dart.library.js_interop) 'adapters/browser_adapter.dart'
if (dart.library.html) 'adapters/browser_adapter.dart' as adapter;
import 'headers.dart';
import 'options.dart';
import 'redirect_record.dart';
/// {@template dio.HttpClientAdapter}
/// [HttpAdapter] is a bridge between [Dio] and [HttpClient].
///
/// [Dio] implements standard and friendly API for developer.
/// [HttpClient] is the real object that makes Http
/// requests.
///
/// We can use any [HttpClient]s not just "dart:io:HttpClient" to
/// make the HTTP request. All we need is to provide a [HttpClientAdapter].
///
/// If you want to customize the [HttpClientAdapter] you should instead use
/// either [IOHttpClientAdapter] on `dart:io` platforms
/// or [BrowserHttpClientAdapter] on `dart:html` platforms.
/// {@endtemplate}
abstract class HttpClientAdapter {
/// Create a [HttpClientAdapter] based on the current platform (IO/Web).
factory HttpClientAdapter() => adapter.createAdapter();
/// The key used to store the HTTP protocol version in [ResponseBody.extra].
///
/// This value is typically "1.0", "1.1", or "2.0" depending on the
/// protocol negotiated with the server.
///
/// The value may be unavailable when using some adapters (for example
/// `web_adapter` and `native_dio_adapter`), depending on whether the
/// underlying transport exposes protocol metadata.
static const extraKeyHttpVersion = 'httpVersion';
/// Implement this method to make real HTTP requests.
///
/// [options] are the request options.
///
/// [requestStream] is the request stream. It will not be null only when
/// the request body is not empty.
/// Use [requestStream] if your code rely on [RequestOptions.onSendProgress].
///
/// [cancelFuture] corresponds to [CancelToken] handling.
/// When the request is canceled, [cancelFuture] will be resolved.
/// To await if a request has been canceled:
/// ```dart
/// cancelFuture?.then((_) => print('request cancelled!'));
/// ```
Future<ResponseBody> fetch(
RequestOptions options,
Stream<Uint8List>? requestStream,
Future<void>? cancelFuture,
);
/// Close the current adapter and its inner clients or requests.
void close({bool force = false});
}
/// The response wrapper class for adapters.
///
/// This class should not be used in regular usages.
class ResponseBody {
ResponseBody(
this.stream,
this.statusCode, {
this.statusMessage,
this.isRedirect = false,
this.redirects,
void Function()? onClose,
Map<String, List<String>>? headers,
}) : headers = headers ?? {},
_onClose = onClose;
ResponseBody.fromString(
String text,
this.statusCode, {
this.statusMessage,
this.isRedirect = false,
void Function()? onClose,
Map<String, List<String>>? headers,
}) : stream = Stream.value(Uint8List.fromList(utf8.encode(text))),
headers = headers ?? {},
_onClose = onClose;
ResponseBody.fromBytes(
List<int> bytes,
this.statusCode, {
this.statusMessage,
this.isRedirect = false,
void Function()? onClose,
Map<String, List<String>>? headers,
}) : stream = Stream.value(
bytes is Uint8List ? bytes : Uint8List.fromList(bytes),
),
headers = headers ?? {},
_onClose = onClose;
/// Whether this response is a redirect.
final bool isRedirect;
/// The response stream.
Stream<Uint8List> stream;
/// HTTP status code.
int statusCode;
/// Content length of the response or -1 if not specified
int get contentLength =>
int.parse(headers[Headers.contentLengthHeader]?.first ?? '-1');
/// Returns the reason phrase corresponds to the status code.
/// The message can be [HttpRequest.statusText]
/// or [HttpClientResponse.reasonPhrase].
String? statusMessage;
/// Stores redirections during the request.
List<RedirectRecord>? redirects;
/// The response headers.
Map<String, List<String>> headers;
/// The extra field which will pass-through to the [Response.extra].
Map<String, dynamic> extra = {};
final void Function()? _onClose;
/// Closes the request & frees the underlying resources.
@internal
void close() => _onClose?.call();
}
================================================
FILE: dio/lib/src/adapters/browser_adapter.dart
================================================
export 'package:dio_web_adapter/dio_web_adapter.dart'
show createAdapter, BrowserHttpClientAdapter;
================================================
FILE: dio/lib/src/adapters/io_adapter.dart
================================================
import 'dart:async';
import 'dart:io';
import 'dart:typed_data';
import '../adapter.dart';
import '../dio_exception.dart';
import '../options.dart';
import '../redirect_record.dart';
@Deprecated('Use IOHttpClientAdapter instead. This will be removed in 6.0.0')
typedef DefaultHttpClientAdapter = IOHttpClientAdapter;
/// The signature of [IOHttpClientAdapter.onHttpClientCreate].
@Deprecated('Use CreateHttpClient instead. This will be removed in 6.0.0')
typedef OnHttpClientCreate = HttpClient? Function(HttpClient client);
/// The signature of [IOHttpClientAdapter.createHttpClient].
/// Can be used to provide a custom [HttpClient] for Dio.
typedef CreateHttpClient = HttpClient Function();
/// The signature of [IOHttpClientAdapter.validateCertificate].
typedef ValidateCertificate = bool Function(
X509Certificate? certificate,
String host,
int port,
);
/// Creates an [IOHttpClientAdapter].
HttpClientAdapter createAdapter() => IOHttpClientAdapter();
/// The default [HttpClientAdapter] for native platforms.
class IOHttpClientAdapter implements HttpClientAdapter {
IOHttpClientAdapter({
@Deprecated('Use createHttpClient instead. This will be removed in 6.0.0')
this.onHttpClientCreate,
this.createHttpClient,
this.validateCertificate,
});
/// [Dio] will create [HttpClient] when it is needed. If [onHttpClientCreate]
/// has provided, [Dio] will call it when a [HttpClient] created.
@Deprecated('Use createHttpClient instead. This will be removed in 6.0.0')
OnHttpClientCreate? onHttpClientCreate;
/// When this callback is set, [Dio] will call it every
/// time it needs a [HttpClient].
CreateHttpClient? createHttpClient;
/// Allows the user to decide if the response certificate is good.
/// If this function is missing, then the certificate is allowed.
/// This method is called only if both the [SecurityContext] and
/// [badCertificateCallback] accept the certificate chain. Those
/// methods evaluate the root or intermediate certificate, while
/// [validateCertificate] evaluates the leaf certificate.
ValidateCertificate? validateCertificate;
HttpClient? _cachedHttpClient;
bool _closed = false;
@override
Future<ResponseBody> fetch(
RequestOptions options,
Stream<Uint8List>? requestStream,
Future<void>? cancelFuture,
) async {
if (_closed) {
throw StateError(
"Can't establish connection after the adapter was closed.",
);
}
return _fetch(options, requestStream, cancelFuture);
}
Future<ResponseBody> _fetch(
RequestOptions options,
Stream<Uint8List>? requestStream,
Future<void>? cancelFuture,
) async {
final httpClient = _configHttpClient(options.connectTimeout);
final reqFuture = httpClient.openUrl(options.method, options.uri);
late HttpClientRequest request;
try {
final connectionTimeout = options.connectTimeout;
if (connectionTimeout != null && connectionTimeout > Duration.zero) {
request = await reqFuture.timeout(
connectionTimeout,
onTimeout: () {
throw DioException.connectionTimeout(
requestOptions: options,
timeout: connectionTimeout,
);
},
);
} else {
request = await reqFuture;
}
final requestWR = WeakReference<HttpClientRequest>(request);
cancelFuture?.whenComplete(() {
requestWR.target?.abort();
});
// Set Headers
options.headers.forEach((key, value) {
if (value != null) {
request.headers.set(
key,
value,
preserveHeaderCase: options.preserveHeaderCase,
);
}
});
} on SocketException catch (e) {
if (e.message.contains('timed out')) {
final Duration effectiveTimeout;
if (options.connectTimeout != null &&
options.connectTimeout! > Duration.zero) {
effectiveTimeout = options.connectTimeout!;
} else if (httpClient.connectionTimeout != null &&
httpClient.connectionTimeout! > Duration.zero) {
effectiveTimeout = httpClient.connectionTimeout!;
} else {
effectiveTimeout = Duration.zero;
}
throw DioException.connectionTimeout(
requestOptions: options,
timeout: effectiveTimeout,
error: e,
);
}
throw DioException.connectionError(
requestOptions: options,
reason: e.message,
error: e,
);
}
request.followRedirects = options.followRedirects;
request.maxRedirects = options.maxRedirects;
request.persistentConnection = options.persistentConnection;
if (requestStream != null) {
// Transform the request data.
Future<dynamic> future = request.addStream(requestStream);
final sendTimeout = options.sendTimeout;
if (sendTimeout != null && sendTimeout > Duration.zero) {
future = future.timeout(
sendTimeout,
onTimeout: () {
request.abort();
throw DioException.sendTimeout(
timeout: sendTimeout,
requestOptions: options,
);
},
);
}
await future;
}
Future<HttpClientResponse> future = request.close();
final receiveTimeout = options.receiveTimeout ?? Duration.zero;
if (receiveTimeout > Duration.zero) {
future = future.timeout(
receiveTimeout,
onTimeout: () {
request.abort();
throw DioException.receiveTimeout(
timeout: receiveTimeout,
requestOptions: options,
);
},
);
}
final responseStream = await future;
if (validateCertificate != null) {
final host = options.uri.host;
final port = options.uri.port;
final bool isCertApproved = validateCertificate!(
responseStream.certificate,
host,
port,
);
if (!isCertApproved) {
throw DioException.badCertificate(
requestOptions: options,
error: responseStream.certificate,
);
}
}
final headers = <String, List<String>>{};
responseStream.headers.forEach((key, values) {
headers[key] = values;
});
// Extract HTTP protocol version from the response headers.
// The protocolVersion is available in the internal `_HttpHeaders`
// implementation but not exposed in the public `HttpHeaders` interface,
// so we use dynamic access. This may fail in certain environments
// (e.g., tests with mocks), so we catch and omit errors.
String? httpVersion;
try {
httpVersion = (responseStream.headers as dynamic).protocolVersion;
} catch (_) {}
final responseBody = ResponseBody(
responseStream.cast(),
responseStream.statusCode,
headers: headers,
isRedirect:
responseStream.isRedirect || responseStream.redirects.isNotEmpty,
redirects: responseStream.redirects
.map((e) => RedirectRecord(e.statusCode, e.method, e.location))
.toList(),
statusMessage: responseStream.reasonPhrase,
);
if (httpVersion != null) {
responseBody.extra[HttpClientAdapter.extraKeyHttpVersion] ??= httpVersion;
}
return responseBody;
}
HttpClient _configHttpClient(Duration? connectionTimeout) {
final client = _cachedHttpClient ??= _createHttpClient();
connectionTimeout ??= Duration.zero;
if (connectionTimeout > Duration.zero) {
client.connectionTimeout = connectionTimeout;
} else {
client.connectionTimeout = null;
}
return client;
}
@override
void close({bool force = false}) {
_closed = true;
_cachedHttpClient?.close(force: force);
}
HttpClient _createHttpClient() {
if (createHttpClient != null) {
return createHttpClient!();
}
final client = HttpClient()..idleTimeout = const Duration(seconds: 3);
// ignore: deprecated_member_use, deprecated_member_use_from_same_package
return onHttpClientCreate?.call(client) ?? client;
}
}
================================================
FILE: dio/lib/src/cancel_token.dart
================================================
import 'dart:async';
import 'dio_exception.dart';
import 'options.dart';
import 'utils.dart' show warningLog;
/// {@template dio.CancelToken}
/// Controls cancellation of [Dio]'s requests.
///
/// The same token can be shared between different requests.
/// When [cancel] is invoked, requests bound to this token will be cancelled.
/// {@endtemplate}
class CancelToken {
CancelToken();
final Completer<DioException> _completer = Completer<DioException>();
/// Whether the [error] is thrown by [cancel].
static bool isCancel(DioException error) =>
error.type == DioExceptionType.cancel;
/// If request have been canceled, save the cancel error.
DioException? get cancelError => _cancelError;
DioException? _cancelError;
/// Corresponding request options for the request.
///
/// This field can be null if the request was never submitted.
RequestOptions? requestOptions;
/// Whether the token is cancelled.
bool get isCancelled => _cancelError != null;
/// When cancelled, this future will be resolved.
Future<DioException> get whenCancel => _completer.future;
/// Cancel the request with the given [reason].
void cancel([Object? reason]) {
if (_completer.isCompleted) {
if (reason != _cancelError?.error) {
final buffer = StringBuffer();
buffer.writeln(
'The CancelToken was cancelled multiple times with different reason:',
);
buffer.writeln('=> [Error ]:');
buffer.writeln(' |--- Previous:${_cancelError?.error}');
buffer.writeln(' |--- Current :$reason');
buffer.writeln('=> [Stack Trace]:');
buffer.writeln(' |--- Previous:${_cancelError?.stackTrace}');
buffer.writeln(' |--- Current :${StackTrace.current}');
warningLog(buffer.toString(), StackTrace.current);
}
return;
}
_cancelError = DioException.requestCancelled(
requestOptions: requestOptions ?? RequestOptions(),
reason: reason,
stackTrace: StackTrace.current,
);
_completer.complete(_cancelError);
}
}
================================================
FILE: dio/lib/src/compute/compute.dart
================================================
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// This file corresponds to Flutter's
// [`foundation/isolates.dart`](https://github.com/flutter/flutter/blob/stable/packages/flutter/lib/src/foundation/isolates.dart).
//
// Changes are only synced with the `stable` branch.
//
// Last synced commit:
// [3d46ab9](https://github.com/flutter/flutter/commit/3d46ab920b47a2ecb250c6f890f3559ef913cb0b)
//
// The changes are currently manually synced. If you noticed that the Flutter's
// original `compute` function (and any of the related files) have changed
// on the `stable` branch and you would like to see those changes in the `compute` package
// please open an [issue](https://github.com/dartsidedev/compute/issues),
// and I'll try my best to "merge".
//
// The file is intentionally not refactored so that it is easier to keep the
// compute package up to date with Flutter's implementation.
//
// When this library supports just Dart 3, we can delete most of this code
// an make use of `Isolate.run()`
// ignore_for_file: no_leading_underscores_for_library_prefixes
import 'dart:async';
import 'compute_io.dart'
if (dart.library.js_interop) 'compute_web.dart'
if (dart.library.html) 'compute_web.dart' as _c;
/// Signature for the callback passed to [compute].
///
/// For more information, visit Flutter documentation for the equivalent
/// [`ComputeCallback<Q, R>` type definition](https://api.flutter.dev/flutter/foundation/ComputeCallback.html)
/// in Flutter. This documentation is taken directly from
/// the Flutter source code.
///
/// {@macro flutter.foundation.compute.types}
///
/// Instances of [ComputeCallback] must be functions that can be sent to an
/// isolate.
/// {@macro flutter.foundation.compute.callback}
///
/// {@macro flutter.foundation.compute.types}
typedef ComputeCallback<Q, R> = FutureOr<R> Function(Q message);
/// The signature of [compute], which spawns an isolate, runs `callback` on
/// that isolate, passes it `message`, and (eventually) returns the value
/// returned by `callback`.
///
/// For more information, visit Flutter documentation for the equivalent
/// [`ComputeImpl` type definition](https://api.flutter.dev/flutter/foundation/ComputeImpl.html)
/// in Flutter. This documentation is taken directly from
/// the Flutter source code.
///
/// {@macro flutter.foundation.compute.usecase}
///
/// The function used as `callback` must be one that can be sent to an isolate.
/// {@macro flutter.foundation.compute.callback}
///
/// {@macro flutter.foundation.compute.types}
///
/// The `debugLabel` argument can be specified to provide a name to add to the
/// [Timeline]. This is useful when profiling an application.
typedef ComputeImpl = Future<R> Function<Q, R>(
ComputeCallback<Q, R> callback,
Q message, {
String? debugLabel,
});
/// A function that spawns an isolate and runs the provided `callback` on that
/// isolate, passes it the provided `message`, and (eventually) returns the
/// value returned by `callback`.
///
/// For more information, visit Flutter documentation for the equivalent
/// [`compute` function](https://pub.dev/documentation/compute/latest/compute/compute-constant.html)
/// in Flutter. This documentation is taken directly from
/// the Flutter source code.
///
/// {@template flutter.foundation.compute.usecase}
/// This is useful for operations that take longer than a few milliseconds, and
/// which would therefore risk skipping frames. For tasks that will only take a
/// few milliseconds, consider [SchedulerBinding.scheduleTask] instead.
/// {@endtemplate}
///
/// {@youtube 560 315 https://www.youtube.com/watch?v=5AxWC49ZMzs}
///
/// The following code uses the [compute] function to check whether a given
/// integer is a prime number.
///
/// ```dart
/// Future<bool> isPrime(int value) {
/// return compute(_calculate, value);
/// }
///
/// bool _calculate(int value) {
/// if (value == 1) {
/// return false;
/// }
/// for (int i = 2; i < value; ++i) {
/// if (value % i == 0) {
/// return false;
/// }
/// }
/// return true;
/// }
/// ```
///
/// The function used as `callback` must be one that can be sent to an isolate.
/// {@template flutter.foundation.compute.callback}
/// Qualifying functions include:
///
/// * top-level functions
/// * static methods
/// * closures that only capture objects that can be sent to an isolate
///
/// Using closures must be done with care. Due to
/// [dart-lang/sdk#36983](https://github.com/dart-lang/sdk/issues/36983) a
/// closure may captures objects that, while not directly used in the closure
/// itself, may prevent it from being sent to an isolate.
/// {@endtemplate}
///
/// {@template flutter.foundation.compute.types}
/// The [compute] method accepts the following parameters:
///
/// * `Q` is the type of the message that kicks off the computation.
/// * `R` is the type of the value returned.
///
/// There are limitations on the values that can be sent and received to and
/// from isolates. These limitations constrain the values of `Q` and `R` that
/// are possible. See the discussion at [SendPort.send].
///
/// The same limitations apply to any errors generated by the computation.
/// {@endtemplate}
///
/// See also:
///
/// * [ComputeImpl], for the [compute] function's signature.
const ComputeImpl compute = _c.compute;
================================================
FILE: dio/lib/src/compute/compute_io.dart
================================================
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// This file corresponds to Flutter's
// [`foundation/_isolates_io.dart`](https://github.com/flutter/flutter/blob/stable/packages/flutter/lib/src/foundation/_isolates_io.dart).
//
// Changes are only synced with the `stable` branch.
//
// Last synced commit:
// [3420b9c](https://github.com/flutter/flutter/commit/3420b9c50ea19489dd74b024705bb010c5763d0a)
//
// The changes are currently manually synced. If you noticed that the Flutter's
// original `compute` function (and any of the related files) have changed
// on the `stable` branch and you would like to see those changes in the `compute` package
// please open an [issue](https://github.com/dartsidedev/compute/issues),
// and I'll try my best to "merge".
//
// The file is intentionally not refactored so that it is easier to keep the
// compute package up to date with Flutter's implementation.
import 'dart:async';
import 'dart:developer';
import 'dart:isolate';
import '../utils.dart' show kReleaseMode;
import 'compute.dart' as c;
/// The dart:io implementation of [c.compute].
Future<R> compute<Q, R>(
c.ComputeCallback<Q, R> callback,
Q message, {
String? debugLabel,
}) async {
debugLabel ??= kReleaseMode ? 'compute' : callback.toString();
final Flow flow = Flow.begin();
Timeline.startSync('$debugLabel: start', flow: flow);
final RawReceivePort port = RawReceivePort();
Timeline.finishSync();
void timeEndAndCleanup() {
Timeline.startSync('$debugLabel: end', flow: Flow.end(flow.id));
port.close();
Timeline.finishSync();
}
final Completer<dynamic> completer = Completer<dynamic>();
port.handler = (dynamic msg) {
timeEndAndCleanup();
completer.complete(msg);
};
try {
await Isolate.spawn<_IsolateConfiguration<Q, R>>(
_spawn,
_IsolateConfiguration<Q, R>(
callback,
message,
port.sendPort,
debugLabel,
flow.id,
),
errorsAreFatal: true,
onExit: port.sendPort,
onError: port.sendPort,
debugName: debugLabel,
);
} on Object {
timeEndAndCleanup();
rethrow;
}
final dynamic response = await completer.future;
if (response == null) {
throw RemoteError('Isolate exited without result or error.', '');
}
assert(response is List<dynamic>);
response as List<dynamic>;
final int type = response.length;
assert(1 <= type && type <= 3);
switch (type) {
// success; see _buildSuccessResponse
case 1:
return response[0] as R;
// native error; see Isolate.addErrorListener
case 2:
await Future<Never>.error(
RemoteError(
response[0] as String,
response[1] as String,
),
);
// caught error; see _buildErrorResponse
case 3:
default:
assert(type == 3 && response[2] == null);
await Future<Never>.error(
response[0] as Object,
response[1] as StackTrace,
);
}
}
class _IsolateConfiguration<Q, R> {
const _IsolateConfiguration(
this.callback,
this.message,
this.resultPort,
this.debugLabel,
this.flowId,
);
final c.ComputeCallback<Q, R> callback;
final Q message;
final SendPort resultPort;
final String debugLabel;
final int flowId;
FutureOr<R> applyAndTime() {
return Timeline.timeSync(
debugLabel,
() => callback(message),
flow: Flow.step(flowId),
);
}
}
/// The spawn point MUST guarantee only one result event is sent through the
/// [SendPort.send] be it directly or indirectly i.e. [Isolate.exit].
///
/// In case an [Error] or [Exception] are thrown AFTER the data
/// is sent, they will NOT be handled or reported by the main [Isolate] because
/// it stops listening after the first event is received.
///
/// Also use the helpers [_buildSuccessResponse] and [_buildErrorResponse] to
/// build the response
Future<void> _spawn<Q, R>(_IsolateConfiguration<Q, R> configuration) async {
late final List<dynamic> computationResult;
try {
computationResult =
_buildSuccessResponse(await configuration.applyAndTime());
} catch (e, s) {
computationResult = _buildErrorResponse(e, s);
}
Isolate.exit(configuration.resultPort, computationResult);
}
/// Wrap in [List] to ensure our expectations in the main [Isolate] are met.
///
/// We need to wrap a success result in a [List] because the user provided type
/// [R] could also be a [List]. Meaning, a check `result is R` could return true
/// for what was an error event.
List<R> _buildSuccessResponse<R>(R result) {
return List<R>.filled(1, result);
}
/// Wrap in [List] to ensure our expectations in the main isolate are met.
///
/// We wrap a caught error in a 3 element [List]. Where the last element is
/// always null. We do this so we have a way to know if an error was one we
/// caught or one thrown by the library code.
List<dynamic> _buildErrorResponse(Object error, StackTrace stack) {
return List<dynamic>.filled(3, null)
..[0] = error
..[1] = stack;
}
================================================
FILE: dio/lib/src/compute/compute_web.dart
================================================
export 'package:dio_web_adapter/dio_web_adapter.dart' show compute;
================================================
FILE: dio/lib/src/dio/dio_for_browser.dart
================================================
export 'package:dio_web_adapter/dio_web_adapter.dart'
show createDio, DioForBrowser;
================================================
FILE: dio/lib/src/dio/dio_for_native.dart
================================================
import 'dart:async';
import 'dart:io';
import '../adapter.dart';
import '../adapters/io_adapter.dart';
import '../cancel_token.dart';
import '../dio.dart';
import '../dio_exception.dart';
import '../dio_mixin.dart';
import '../headers.dart';
import '../options.dart';
import '../response.dart';
/// Create the [Dio] instance for native platforms.
Dio createDio([BaseOptions? baseOptions]) => DioForNative(baseOptions);
/// Implements features for [Dio] on native platforms.
class DioForNative with DioMixin implements Dio {
/// Create Dio instance with default [BaseOptions].
/// It is recommended that an application use only the same DIO singleton.
DioForNative([BaseOptions? baseOptions]) {
options = baseOptions ?? BaseOptions();
httpClientAdapter = IOHttpClientAdapter();
}
/// {@macro dio.Dio.download}
@override
Future<Response> download(
String urlPath,
dynamic savePath, {
ProgressCallback? onReceiveProgress,
Map<String, dynamic>? queryParameters,
CancelToken? cancelToken,
bool deleteOnError = true,
FileAccessMode fileAccessMode = FileAccessMode.write,
String lengthHeader = Headers.contentLengthHeader,
Object? data,
Options? options,
}) async {
options ??= DioMixin.checkOptions('GET', options);
// Manually set the `responseType` to [ResponseType.stream]
// to retrieve the response stream.
// Do not modify previous options.
options = options.copyWith(responseType: ResponseType.stream);
final Response<ResponseBody> response;
try {
response = await request<ResponseBody>(
urlPath,
data: data,
options: options,
queryParameters: queryParameters,
cancelToken: cancelToken,
);
} on DioException catch (e) {
if (e.type == DioExceptionType.badResponse) {
final response = e.response!;
if (response.requestOptions.receiveDataWhenStatusError == true) {
final ResponseType implyResponseType;
final contentType = response.headers.value(Headers.contentTypeHeader);
if (contentType != null && contentType.startsWith('text/')) {
implyResponseType = ResponseType.plain;
} else {
implyResponseType = ResponseType.json;
}
final res = await transformer.transformResponse(
response.requestOptions.copyWith(responseType: implyResponseType),
response.data as ResponseBody,
);
response.data = res;
} else {
response.data = null;
}
}
rethrow;
}
final File file;
if (savePath is FutureOr<String> Function(Headers)) {
// Add real Uri and redirect information to headers.
response.headers
..add('redirects', response.redirects.length.toString())
..add('uri', response.realUri.toString());
file = File(await savePath(response.headers));
} else if (savePath is String) {
file = File(savePath);
} else {
throw ArgumentError.value(
savePath.runtimeType,
'savePath',
'The type must be `String` or `FutureOr<String> Function(Headers)`.',
);
}
// If the file already exists, the method fails.
file.createSync(recursive: true);
// Shouldn't call file.writeAsBytesSync(list, flush: flush),
// because it can write all bytes by once. Consider that the file is
// a very big size (up to 1 Gigabytes), it will be expensive in memory.
RandomAccessFile raf = file.openSync(
mode: fileAccessMode == FileAccessMode.write
? FileMode.write
: FileMode.append,
);
// Create a Completer to notify the success/error state.
final completer = Completer<Response>();
int received = 0;
// Stream<Uint8List>
final stream = response.data!.stream;
bool compressed = false;
int total = 0;
final contentEncoding = response.headers.value(
Headers.contentEncodingHeader,
);
if (contentEncoding != null) {
compressed = ['gzip', 'deflate', 'compress'].contains(contentEncoding);
}
if (lengthHeader == Headers.contentLengthHeader && compressed) {
total = -1;
} else {
total = int.parse(response.headers.value(lengthHeader) ?? '-1');
}
Future<void>? asyncWrite;
bool closed = false;
Future<void> closeAndDelete() async {
if (!closed) {
closed = true;
await asyncWrite;
await raf.close().catchError((_) => raf);
if (deleteOnError && file.existsSync()) {
await file.delete().catchError((_) => file);
}
}
}
late StreamSubscription subscription;
subscription = stream.listen(
(data) {
subscription.pause();
// Write file asynchronously
asyncWrite = raf.writeFrom(data).then((result) {
// Notify progress
received += data.length;
onReceiveProgress?.call(received, total);
raf = result;
if (cancelToken == null || !cancelToken.isCancelled) {
subscription.resume();
}
}).catchError((Object e) async {
try {
await subscription.cancel().catchError((_) {});
closed = true;
await raf.close().catchError((_) => raf);
if (deleteOnError && file.existsSync()) {
await file.delete().catchError((_) => file);
}
} finally {
completer.completeError(
DioMixin.assureDioException(e, response.requestOptions),
);
}
});
},
onDone: () async {
try {
await asyncWrite;
closed = true;
await raf.close().catchError((_) => raf);
completer.complete(response);
} catch (e) {
completer.completeError(
DioMixin.assureDioException(e, response.requestOptions),
);
}
},
onError: (e) async {
try {
await closeAndDelete();
} finally {
completer.completeError(
DioMixin.assureDioException(e, response.requestOptions),
);
}
},
cancelOnError: true,
);
cancelToken?.whenCancel.then((_) async {
await subscription.cancel();
await closeAndDelete();
});
return DioMixin.listenCancelForAsyncTask(cancelToken, completer.future);
}
}
================================================
FILE: dio/lib/src/dio.dart
================================================
import 'dart:async';
import 'adapter.dart';
import 'cancel_token.dart';
import 'dio/dio_for_native.dart'
if (dart.library.js_interop) 'dio/dio_for_browser.dart'
if (dart.library.html) 'dio/dio_for_browser.dart';
import 'dio_mixin.dart';
import 'headers.dart';
import 'options.dart';
import 'response.dart';
import 'transformer.dart';
/// Dio enables you to make HTTP requests easily.
///
/// Creating a [Dio] instance with configurations:
/// ```dart
/// final dio = Dio(
/// BaseOptions(
/// baseUrl: "https://pub.dev",
/// connectTimeout: const Duration(seconds: 5),
/// receiveTimeout: const Duration(seconds: 5),
/// headers: {
/// HttpHeaders.userAgentHeader: 'dio',
/// 'common-header': 'xx',
/// },
/// )
/// );
/// ```
///
/// The [Dio.options] can be updated in anytime:
/// ```dart
/// dio.options.baseUrl = "https://pub.dev";
/// dio.options.connectTimeout = const Duration(seconds: 5);
/// dio.options.receiveTimeout = const Duration(seconds: 5);
/// ```
abstract class Dio {
/// Create the default [Dio] instance with the default implementation
/// based on different platforms.
factory Dio([BaseOptions? options]) => createDio(options);
/// Default Request config. More see [BaseOptions] .
late BaseOptions options;
/// Return the interceptors added into the instance.
Interceptors get interceptors;
/// The adapter that the instance is using.
late HttpClientAdapter httpClientAdapter;
/// [Transformer] allows changes to the request/response data before it is
/// sent/received to/from the server.
/// This is only applicable for requests that have payload.
late Transformer transformer;
/// Shuts down the dio client.
///
/// If [force] is `false` (the default) the [Dio] will be kept alive
/// until all active connections are done. If [force] is `true` any active
/// connections will be closed to immediately release all resources. These
/// closed connections will receive an error event to indicate that the client
/// was shut down. In both cases trying to establish a new connection after
/// calling [close] will throw an exception.
void close({bool force = false});
/// Convenience method to make an HTTP HEAD request.
Future<Response<T>> head<T>(
String path, {
Object? data,
Map<String, dynamic>? queryParameters,
Options? options,
CancelToken? cancelToken,
});
/// Convenience method to make an HTTP HEAD request with [Uri].
Future<Response<T>> headUri<T>(
Uri uri, {
Object? data,
Options? options,
CancelToken? cancelToken,
});
/// Convenience method to make an HTTP GET request.
Future<Response<T>> get<T>(
String path, {
Object? data,
Map<String, dynamic>? queryParameters,
Options? options,
CancelToken? cancelToken,
ProgressCallback? onReceiveProgress,
});
/// Convenience method to make an HTTP GET request with [Uri].
Future<Response<T>> getUri<T>(
Uri uri, {
Object? data,
Options? options,
CancelToken? cancelToken,
ProgressCallback? onReceiveProgress,
});
/// Convenience method to make an HTTP POST request.
Future<Response<T>> post<T>(
String path, {
Object? data,
Map<String, dynamic>? queryParameters,
Options? options,
CancelToken? cancelToken,
ProgressCallback? onSendProgress,
ProgressCallback? onReceiveProgress,
});
/// Convenience method to make an HTTP POST request with [Uri].
Future<Response<T>> postUri<T>(
Uri uri, {
Object? data,
Options? options,
CancelToken? cancelToken,
ProgressCallback? onSendProgress,
ProgressCallback? onReceiveProgress,
});
/// Convenience method to make an HTTP PUT request.
Future<Response<T>> put<T>(
String path, {
Object? data,
Map<String, dynamic>? queryParameters,
Options? options,
CancelToken? cancelToken,
ProgressCallback? onSendProgress,
ProgressCallback? onReceiveProgress,
});
/// Convenience method to make an HTTP PUT request with [Uri].
Future<Response<T>> putUri<T>(
Uri uri, {
Object? data,
Options? options,
CancelToken? cancelToken,
ProgressCallback? onSendProgress,
ProgressCallback? onReceiveProgress,
});
/// Convenience method to make an HTTP PATCH request.
Future<Response<T>> patch<T>(
String path, {
Object? data,
Map<String, dynamic>? queryParameters,
Options? options,
CancelToken? cancelToken,
ProgressCallback? onSendProgress,
ProgressCallback? onReceiveProgress,
});
/// Convenience method to make an HTTP PATCH request with [Uri].
Future<Response<T>> patchUri<T>(
Uri uri, {
Object? data,
Options? options,
CancelToken? cancelToken,
ProgressCallback? onSendProgress,
ProgressCallback? onReceiveProgress,
});
/// Convenience method to make an HTTP DELETE request.
Future<Response<T>> delete<T>(
String path, {
Object? data,
Map<String, dynamic>? queryParameters,
Options? options,
CancelToken? cancelToken,
});
/// Convenience method to make an HTTP DELETE request with [Uri].
Future<Response<T>> deleteUri<T>(
Uri uri, {
Object? data,
Options? options,
CancelToken? cancelToken,
});
/// {@template dio.Dio.download}
/// Download the file and save it in local. The default http method is "GET",
/// you can custom it by [Options.method].
///
/// [urlPath] is the file url.
///
/// The file will be saved to the path specified by [savePath].
/// The following two types are accepted:
/// 1. `String`: A path, eg "xs.jpg"
/// 2. `FutureOr<String> Function(Headers headers)`, for example:
/// ```dart
/// await dio.download(
/// url,
/// (Headers headers) {
/// // Extra info: redirect counts
/// print(headers.value('redirects'));
/// // Extra info: real uri
/// print(headers.value('uri'));
/// // ...
/// return (await getTemporaryDirectory()).path + 'file_name';
/// },
/// );
/// ```
///
/// [onReceiveProgress] is the callback to listen downloading progress.
/// Please refer to [ProgressCallback].
///
/// [deleteOnError] whether delete the file when error occurs.
/// The default value is [true].
///
/// [fileAccessMode]
/// {@macro dio.options.FileAccessMode}
///
/// [lengthHeader] : The real size of original file (not compressed).
/// When file is compressed:
/// 1. If this value is 'content-length', the `total` argument of
/// [onReceiveProgress] will be -1.
/// 2. If this value is not 'content-length', maybe a custom header indicates
/// the original file size, the `total` argument of [onReceiveProgress]
/// will be this header value.
///
/// You can also disable the compression by specifying the 'accept-encoding'
/// header value as '*' to assure the value of `total` argument of
/// [onReceiveProgress] is not -1. For example:
///
/// ```dart
/// await dio.download(
/// url,
/// (await getTemporaryDirectory()).path + 'flutter.svg',
/// options: Options(
/// headers: {HttpHeaders.acceptEncodingHeader: '*'}, // Disable gzip
/// ),
/// onReceiveProgress: (received, total) {
/// if (total <= 0) return;
/// print('percentage: ${(received / total * 100).toStringAsFixed(0)}%');
/// },
/// );
/// ```
/// {@endtemplate}
Future<Response> download(
String urlPath,
dynamic savePath, {
ProgressCallback? onReceiveProgress,
Map<String, dynamic>? queryParameters,
CancelToken? cancelToken,
bool deleteOnError = true,
FileAccessMode fileAccessMode = FileAccessMode.write,
String lengthHeader = Headers.contentLengthHeader,
Object? data,
Options? options,
});
/// {@macro dio.Dio.download}
Future<Response> downloadUri(
Uri uri,
dynamic savePath, {
ProgressCallback? onReceiveProgress,
CancelToken? cancelToken,
bool deleteOnError = true,
FileAccessMode fileAccessMode = FileAccessMode.write,
String lengthHeader = Headers.contentLengthHeader,
Object? data,
Options? options,
}) {
return download(
uri.toString(),
savePath,
onReceiveProgress: onReceiveProgress,
lengthHeader: lengthHeader,
deleteOnError: deleteOnError,
cancelToken: cancelToken,
data: data,
fileAccessMode: fileAccessMode,
options: options,
);
}
/// Make HTTP request with options.
Future<Response<T>> request<T>(
String url, {
Object? data,
Map<String, dynamic>? queryParameters,
CancelToken? cancelToken,
Options? options,
ProgressCallback? onSendProgress,
ProgressCallback? onReceiveProgress,
});
/// Make http request with options with [Uri].
Future<Response<T>> requestUri<T>(
Uri uri, {
Object? data,
CancelToken? cancelToken,
Options? options,
ProgressCallback? onSendProgress,
ProgressCallback? onReceiveProgress,
});
/// The eventual method to submit requests. All callers for requests should
/// eventually go through this method.
Future<Response<T>> fetch<T>(RequestOptions requestOptions);
/// Clones a new [Dio] instance with override fields or reuses current fields.
Dio clone({
BaseOptions? options,
Interceptors? interceptors,
HttpClientAdapter? httpClientAdapter,
Transformer? transformer,
});
}
================================================
FILE: dio/lib/src/dio_exception.dart
================================================
import 'options.dart';
import 'response.dart';
import 'utils.dart' show warningLog;
/// Deprecated in favor of [DioExceptionType] and will be removed in future major versions.
@Deprecated('Use DioExceptionType instead. This will be removed in 6.0.0')
typedef DioErrorType = DioExceptionType;
/// [DioError] describes the exception info when a request failed.
@Deprecated('Use DioException instead. This will be removed in 6.0.0')
typedef DioError = DioException;
/// The exception enumeration indicates what type of exception
/// has happened during requests.
enum DioExceptionType {
/// Caused by a connection timeout.
connectionTimeout,
/// It occurs when url is sent timeout.
sendTimeout,
/// It occurs when receiving timeout.
receiveTimeout,
/// Caused by an incorrect certificate as configured by [ValidateCertificate].
badCertificate,
/// The [DioException] was caused by an incorrect status code as configured by
/// [ValidateStatus].
badResponse,
/// When the request is cancelled, dio will throw a error with this type.
cancel,
/// Caused for example by a `xhr.onError` or SocketExceptions.
connectionError,
/// Default error type, Some other [Error]. In this case, you can use the
/// [DioException.error] if it is not null.
unknown,
}
extension _DioExceptionTypeExtension on DioExceptionType {
String toPrettyDescription() {
switch (this) {
case DioExceptionType.connectionTimeout:
return 'connection timeout';
case DioExceptionType.sendTimeout:
return 'send timeout';
case DioExceptionType.receiveTimeout:
return 'receive timeout';
case DioExceptionType.badCertificate:
return 'bad certificate';
case DioExceptionType.badResponse:
return 'bad response';
case DioExceptionType.cancel:
return 'request cancelled';
case DioExceptionType.connectionError:
return 'connection error';
case DioExceptionType.unknown:
return 'unknown';
}
}
}
/// [DioException] describes the exception info when a request failed.
class DioException implements Exception {
/// Prefer using one of the other constructors.
/// They're most likely better fitting.
DioException({
required this.requestOptions,
this.response,
this.type = DioExceptionType.unknown,
this.error,
StackTrace? stackTrace,
this.message,
}) : stackTrace = identical(stackTrace, StackTrace.empty)
? requestOptions.sourceStackTrace ?? StackTrace.current
: stackTrace ??
requestOptions.sourceStackTrace ??
StackTrace.current;
factory DioException.badResponse({
required int statusCode,
required RequestOptions requestOptions,
required Response response,
}) =>
DioException(
type: DioExceptionType.badResponse,
requestOptions: requestOptions,
response: response,
error: null,
message: _badResponseExceptionMessage(statusCode),
);
factory DioException.connectionTimeout({
required Duration timeout,
required RequestOptions requestOptions,
Object? error,
}) =>
DioException(
type: DioExceptionType.connectionTimeout,
requestOptions: requestOptions,
response: null,
error: error,
message: 'The request connection took longer than $timeout '
'and it was aborted. '
'To get rid of this exception, try raising the '
'RequestOptions.connectTimeout above the duration of $timeout or '
'improve the response time of the server.',
);
factory DioException.sendTimeout({
required Duration timeout,
required RequestOptions requestOptions,
}) =>
DioException(
type: DioExceptionType.sendTimeout,
requestOptions: requestOptions,
response: null,
error: null,
message: 'The request took longer than $timeout to send data. '
'It was aborted. '
'To get rid of this exception, try raising the '
'RequestOptions.sendTimeout above the duration of $timeout or '
'improve the response time of the server.',
);
factory DioException.receiveTimeout({
required Duration timeout,
required RequestOptions requestOptions,
Object? error,
}) =>
DioException(
type: DioExceptionType.receiveTimeout,
requestOptions: requestOptions,
response: null,
error: error,
message: 'The request took longer than $timeout to receive data. '
'It was aborted. '
'To get rid of this exception, try raising the '
'RequestOptions.receiveTimeout above the duration of $timeout or '
'improve the response time of the server.',
);
factory DioException.badCertificate({
required RequestOptions requestOptions,
Object? error,
}) =>
DioException(
type: DioExceptionType.badCertificate,
requestOptions: requestOptions,
response: null,
error: error,
message: 'The certificate of the response is not approved.',
);
factory DioException.requestCancelled({
required RequestOptions requestOptions,
required Object? reason,
StackTrace? stackTrace,
}) =>
DioException(
type: DioExceptionType.cancel,
requestOptions: requestOptions,
response: null,
error: reason,
stackTrace: stackTrace,
message: 'The request was manually cancelled by the user.',
);
factory DioException.connectionError({
required RequestOptions requestOptions,
required String reason,
Object? error,
}) =>
DioException(
type: DioExceptionType.connectionError,
message: 'The connection errored: $reason '
'This indicates an error which most likely cannot be solved by the library.',
requestOptions: requestOptions,
response: null,
error: error,
);
/// The request info for the request that throws exception.
///
/// The info can be empty (e.g. `uri` equals to "")
/// if the request was never submitted.
final RequestOptions requestOptions;
/// Response info, it may be `null` if the request can't reach to the
/// HTTP server, for example, occurring a DNS error, network is not available.
final Response? response;
final DioExceptionType type;
/// The original error/exception object;
/// It's usually not null when `type` is [DioExceptionType.unknown].
final Object? error;
/// The stacktrace of the original error/exception object;
/// It's usually not null when `type` is [DioExceptionType.unknown].
final StackTrace stackTrace;
/// The error message that throws a [DioException].
final String? message;
/// Users can customize the content of [toString] when thrown.
static DioExceptionReadableStringBuilder readableStringBuilder =
defaultDioExceptionReadableStringBuilder;
/// Each exception can be override with a customized builder or fallback to
/// the default [DioException.readableStringBuilder].
DioExceptionReadableStringBuilder? stringBuilder;
/// Generate a new [DioException] by combining given values and original values.
DioException copyWith({
RequestOptions? requestOptions,
Response? response,
DioExceptionType? type,
Object? error,
StackTrace? stackTrace,
String? message,
}) {
return DioException(
requestOptions: requestOptions ?? this.requestOptions,
response: response ?? this.response,
type: type ?? this.type,
error: error ?? this.error,
stackTrace: stackTrace ?? this.stackTrace,
message: message ?? this.message,
);
}
@override
String toString() {
try {
return stringBuilder?.call(this) ?? readableStringBuilder(this);
} catch (e, s) {
warningLog(e, s);
return defaultDioExceptionReadableStringBuilder(this);
}
}
/// Because of [ValidateStatus] we need to consider all status codes when
/// creating a [DioException.badResponse].
static String _badResponseExceptionMessage(int statusCode) {
final String message;
if (statusCode >= 100 && statusCode < 200) {
message =
'This is an informational response - the request was received, continuing processing';
} else if (statusCode >= 200 && statusCode < 300) {
message =
'The request was successfully received, understood, and accepted';
} else if (statusCode >= 300 && statusCode < 400) {
message =
'Redirection: further action needs to be taken in order to complete the request';
} else if (statusCode >= 400 && statusCode < 500) {
message =
'Client error - the request contains bad syntax or cannot be fulfilled';
} else if (statusCode >= 500 && statusCode < 600) {
message =
'Server error - the server failed to fulfil an apparently valid request';
} else {
message =
'A response with a status code that is not within the range of inclusive 100 to exclusive 600'
'is a non-standard response, possibly due to the server\'s software';
}
final buffer = StringBuffer();
buffer.writeln(
'This exception was thrown because the response has a status code of $statusCode '
'and RequestOptions.validateStatus was configured to throw for this status code.',
);
buffer.writeln(
'The status code of $statusCode has the following meaning: "$message"',
);
buffer.writeln(
'Read more about status codes at https://developer.mozilla.org/en-US/docs/Web/HTTP/Status',
);
buffer.writeln(
'In order to resolve this exception you typically have either to verify '
'and fix your request code or you have to fix the server code.',
);
return buffer.toString();
}
}
/// The readable string builder's signature of
/// [DioException.readableStringBuilder].
typedef DioExceptionReadableStringBuilder = String Function(DioException e);
/// The default implementation of building a readable string of [DioException].
String defaultDioExceptionReadableStringBuilder(DioException e) {
final buffer = StringBuffer(
'DioException [${e.type.toPrettyDescription()}]: '
'${e.message}',
);
if (e.error != null) {
buffer.writeln();
buffer.write('Error: ${e.error}');
}
return buffer.toString();
}
================================================
FILE: dio/lib/src/dio_mixin.dart
================================================
import 'dart:async';
import 'dart:collection';
import 'dart:convert';
import 'dart:math' as math;
import 'dart:typed_data';
import 'package:async/async.dart';
import 'package:meta/meta.dart';
import 'adapter.dart';
import 'cancel_token.dart';
import 'dio.dart';
import 'dio_exception.dart';
import 'form_data.dart';
import 'headers.dart';
import 'interceptors/imply_content_type.dart';
import 'options.dart';
import 'progress_stream/io_progress_stream.dart'
if (dart.library.js_interop) 'progress_stream/browser_progress_stream.dart'
if (dart.library.html) 'progress_stream/browser_progress_stream.dart';
import 'response.dart';
import 'response/response_stream_handler.dart';
import 'transformer.dart';
part 'interceptor.dart';
// TODO(EVERYONE): Use `mixin class` when the lower bound of SDK is raised to 3.0.0.
abstract class DioMixin implements Dio {
/// The base request config for the instance.
@override
late BaseOptions options;
/// Each Dio instance has a interceptor group by which you can
/// intercept requests or responses before they are ended.
@override
Interceptors get interceptors => _interceptors;
final Interceptors _interceptors = Interceptors();
@override
late HttpClientAdapter httpClientAdapter;
/// The default [Transformer] that transfers requests and responses
/// into corresponding content to send.
/// For response bodies greater than 50KB, a new Isolate will be spawned to
/// decode the response body to JSON.
/// Taken from https://github.com/flutter/flutter/blob/135454af32477f815a7525073027a3ff9eff1bfd/packages/flutter/lib/src/services/asset_bundle.dart#L87-L93
/// 50 KB of data should take 2-3 ms to parse on a Moto G4, and about 400 μs
/// on a Pixel 4.
@override
Transformer transformer = FusedTransformer(
contentLengthIsolateThreshold: 50 * 1024,
);
bool _closed = false;
@override
void close({bool force = false}) {
_closed = true;
httpClientAdapter.close(force: force);
}
@override
Future<Response<T>> get<T>(
String path, {
Map<String, dynamic>? queryParameters,
Object? data,
Options? options,
CancelToken? cancelToken,
ProgressCallback? onReceiveProgress,
}) {
return request<T>(
path,
data: data,
queryParameters: queryParameters,
options: checkOptions('GET', options),
onReceiveProgress: onReceiveProgress,
cancelToken: cancelToken,
);
}
@override
Future<Response<T>> getUri<T>(
Uri uri, {
Object? data,
Options? options,
CancelToken? cancelToken,
ProgressCallback? onReceiveProgress,
}) {
return requestUri<T>(
uri,
data: data,
options: checkOptions('GET', options),
onReceiveProgress: onReceiveProgress,
cancelToken: cancelToken,
);
}
@override
Future<Response<T>> post<T>(
String path, {
Object? data,
Map<String, dynamic>? queryParameters,
Options? options,
CancelToken? cancelToken,
ProgressCallback? onSendProgress,
ProgressCallback? onReceiveProgress,
}) {
return request<T>(
path,
data: data,
options: checkOptions('POST', options),
queryParameters: queryParameters,
cancelToken: cancelToken,
onSendProgress: onSendProgress,
onReceiveProgress: onReceiveProgress,
);
}
@override
Future<Response<T>> postUri<T>(
Uri uri, {
Object? data,
Options? options,
CancelToken? cancelToken,
ProgressCallback? onSendProgress,
ProgressCallback? onReceiveProgress,
}) {
return requestUri<T>(
uri,
data: data,
options: checkOptions('POST', options),
cancelToken: cancelToken,
onSendProgress: onSendProgress,
onReceiveProgress: onReceiveProgress,
);
}
@override
Future<Response<T>> put<T>(
String path, {
Object? data,
Map<String, dynamic>? queryParameters,
Options? options,
CancelToken? cancelToken,
ProgressCallback? onSendProgress,
ProgressCallback? onReceiveProgress,
}) {
return request<T>(
path,
data: data,
queryParameters: queryParameters,
options: checkOptions('PUT', options),
cancelToken: cancelToken,
onSendProgress: onSendProgress,
onReceiveProgress: onReceiveProgress,
);
}
@override
Future<Response<T>> putUri<T>(
Uri uri, {
Object? data,
Options? options,
CancelToken? cancelToken,
ProgressCallback? onSendProgress,
ProgressCallback? onReceiveProgress,
}) {
return requestUri<T>(
uri,
data: data,
options: checkOptions('PUT', options),
cancelToken: cancelToken,
onSendProgress: onSendProgress,
onReceiveProgress: onReceiveProgress,
);
}
@override
Future<Response<T>> head<T>(
String path, {
Object? data,
Map<String, dynamic>? queryParameters,
Options? options,
CancelToken? cancelToken,
}) {
return request<T>(
path,
data: data,
queryParameters: queryParameters,
options: checkOptions('HEAD', options),
cancelToken: cancelToken,
);
}
@override
Future<Response<T>> headUri<T>(
Uri uri, {
Object? data,
Options? options,
CancelToken? cancelToken,
}) {
return requestUri<T>(
uri,
data: data,
options: checkOptions('HEAD', options),
cancelToken: cancelToken,
);
}
@override
Future<Response<T>> delete<T>(
String path, {
Object? data,
Map<String, dynamic>? queryParameters,
Options? options,
CancelToken? cancelToken,
}) {
return request<T>(
path,
data: data,
queryParameters: queryParameters,
options: checkOptions('DELETE', options),
cancelToken: cancelToken,
);
}
@override
Future<Response<T>> deleteUri<T>(
Uri uri, {
Object? data,
Options? options,
CancelToken? cancelToken,
}) {
return requestUri<T>(
uri,
data: data,
options: checkOptions('DELETE', options),
cancelToken: cancelToken,
);
}
@override
Future<Response<T>> patch<T>(
String path, {
Object? data,
Map<String, dynamic>? queryParameters,
Options? options,
CancelToken? cancelToken,
ProgressCallback? onSendProgress,
ProgressCallback? onReceiveProgress,
}) {
return request<T>(
path,
data: data,
queryParameters: queryParameters,
options: checkOptions('PATCH', options),
cancelToken: cancelToken,
onSendProgress: onSendProgress,
onReceiveProgress: onReceiveProgress,
);
}
@override
Future<Response<T>> patchUri<T>(
Uri uri, {
Object? data,
Options? options,
CancelToken? cancelToken,
ProgressCallback? onSendProgress,
ProgressCallback? onReceiveProgress,
}) {
return requestUri<T>(
uri,
data: data,
options: checkOptions('PATCH', options),
cancelToken: cancelToken,
onSendProgress: onSendProgress,
onReceiveProgress: onReceiveProgress,
);
}
@override
Future<Response> downloadUri(
Uri uri,
dynamic savePath, {
ProgressCallback? onReceiveProgress,
CancelToken? cancelToken,
bool deleteOnError = true,
FileAccessMode fileAccessMode = FileAccessMode.write,
String lengthHeader = Headers.contentLengthHeader,
Object? data,
Options? options,
}) {
return download(
uri.toString(),
savePath,
onReceiveProgress: onReceiveProgress,
lengthHeader: lengthHeader,
deleteOnError: deleteOnError,
cancelToken: cancelToken,
data: data,
fileAccessMode: fileAccessMode,
options: options,
);
}
@override
Future<Response> download(
String urlPath,
dynamic savePath, {
ProgressCallback? onReceiveProgress,
Map<String, dynamic>? queryParameters,
CancelToken? cancelToken,
bool deleteOnError = true,
FileAccessMode fileAccessMode = FileAccessMode.write,
String lengthHeader = Headers.contentLengthHeader,
Object? data,
Options? options,
}) {
throw UnimplementedError();
}
@override
Future<Response<T>> requestUri<T>(
Uri uri, {
Object? data,
CancelToken? cancelToken,
Options? options,
ProgressCallback? onSendProgress,
ProgressCallback? onReceiveProgress,
}) {
return request(
uri.toString(),
data: data,
cancelToken: cancelToken,
options: options,
onSendProgress: onSendProgress,
onReceiveProgress: onReceiveProgress,
);
}
@override
Future<Response<T>> request<T>(
String path, {
Object? data,
Map<String, dynamic>? queryParameters,
CancelToken? cancelToken,
Options? options,
ProgressCallback? onSendProgress,
ProgressCallback? onReceiveProgress,
}) async {
if (cancelToken != null && cancelToken.isCancelled) {
throw cancelToken.cancelError!;
}
final requestOptions = (options ?? Options()).compose(
this.options,
path,
data: data,
queryParameters: queryParameters,
onReceiveProgress: onReceiveProgress,
onSendProgress: onSendProgress,
cancelToken: cancelToken,
sourceStackTrace: StackTrace.current,
);
if (_closed) {
throw DioException.connectionError(
reason: "Dio can't establish a new connection after it was closed.",
requestOptions: requestOptions,
);
}
return fetch<T>(requestOptions);
}
@override
Future<Response<T>> fetch<T>(RequestOptions requestOptions) async {
if (T != dynamic &&
!(requestOptions.responseType == ResponseType.bytes ||
requestOptions.responseType == ResponseType.stream)) {
if (T == String) {
requestOptions.responseType = ResponseType.plain;
} else {
requestOptions.responseType = ResponseType.json;
}
}
// Convert the request interceptor to a functional callback in which
// we can handle the return value of interceptor callback.
FutureOr Function(dynamic) requestInterceptorWrapper(
InterceptorSendCallback cb,
) {
return (dynamic incomingState) {
final state = incomingState as InterceptorState;
if (state.type == InterceptorResultType.next) {
return listenCancelForAsyncTask(
requestOptions.cancelToken,
Future(() async {
final handler = RequestInterceptorHandler();
cb(state.data as RequestOptions, handler);
return handler.future;
}),
);
}
return state;
};
}
// Convert the response interceptor to a functional callback in which
// we can handle the return value of interceptor callback.
FutureOr<dynamic> Function(dynamic) responseInterceptorWrapper(
InterceptorSuccessCallback cb,
) {
return (dynamic incomingState) {
final state = incomingState as InterceptorState;
if (state.type == InterceptorResultType.next ||
state.type == InterceptorResultType.resolveCallFollowing) {
return listenCancelForAsyncTask(
requestOptions.cancelToken,
Future(() async {
final handler = ResponseInterceptorHandler();
cb(state.data as Response, handler);
return handler.future;
}),
);
}
return state;
};
}
// Convert the error interceptor to a functional callback in which
// we can handle the return value of interceptor callback.
FutureOr<dynamic> Function(Object) errorInterceptorWrapper(
InterceptorErrorCallback cb,
) {
return (dynamic error) {
final state = error is InterceptorState
? error
: InterceptorState(assureDioException(error, requestOptions));
Future<InterceptorState> handleError() async {
final handler = ErrorInterceptorHandler();
cb(state.data, handler);
return handler.future;
}
// The request has already been cancelled,
// there is no need to listen for another cancellation.
if (state.data is DioException &&
state.data.type == DioExceptionType.cancel) {
return handleError();
}
if (state.type == InterceptorResultType.next ||
state.type == InterceptorResultType.rejectCallFollowing) {
return listenCancelForAsyncTask(
requestOptions.cancelToken,
Future(handleError),
);
}
throw error;
};
}
// Build a request flow in which the processors(interceptors)
// execute in FIFO order.
Future<dynamic> future = Future<dynamic>(
() => InterceptorState(requestOptions),
);
// Add request interceptors into the request flow.
for (final interceptor in interceptors) {
final fun = interceptor is QueuedInterceptor
? interceptor._handleRequest
: interceptor.onRequest;
future = future.then(requestInterceptorWrapper(fun));
}
// Add dispatching callback into the request flow.
future = future.then(
requestInterceptorWrapper((
RequestOptions reqOpt,
RequestInterceptorHandler handler,
) async {
requestOptions = reqOpt;
try {
final value = await _dispatchRequest<T>(reqOpt);
handler.resolve(value, true);
} on DioException catch (e) {
handler.reject(e, true);
}
}),
);
// Add response interceptors into the request flow
for (final interceptor in interceptors) {
final fun = interceptor is QueuedInterceptor
? interceptor._handleResponse
: interceptor.onResponse;
future = future.then(responseInterceptorWrapper(fun));
}
// Add error handlers into the request flow.
for (final interceptor in interceptors) {
final fun = interceptor is QueuedInterceptor
? interceptor._handleError
: interceptor.onError;
future = future.catchError(errorInterceptorWrapper(fun));
}
// Normalize errors, converts errors to [DioException].
try {
final data = await future;
return assureResponse<T>(
data is InterceptorState ? data.data : data,
requestOptions,
);
} catch (e) {
final isState = e is InterceptorState;
if (isState) {
if (e.type == InterceptorResultType.resolve) {
return assureResponse<T>(e.data, requestOptions);
}
}
throw assureDioException(isState ? e.data : e, requestOptions);
}
}
Future<Response<dynamic>> _dispatchRequest<T>(RequestOptions reqOpt) async {
final cancelToken = reqOpt.cancelToken;
try {
final stream = await _transformData(reqOpt);
final operation = CancelableOperation.fromFuture(
httpClientAdapter.fetch(
reqOpt,
stream,
cancelToken?.whenCancel,
),
);
final operationWeakReference = WeakReference(operation);
cancelToken?.whenCancel.whenComplete(() {
operationWeakReference.target?.cancel();
});
final responseBody = await operation.value;
final headers = Headers.fromMap(
responseBody.headers,
preserveHeaderCase: reqOpt.preserveHeaderCase,
);
// Make sure headers and [ResponseBody.headers] are the same instance.
responseBody.headers = headers.map;
final ret = Response<dynamic>(
headers: headers,
requestOptions: reqOpt,
redirects: responseBody.redirects ?? [],
isRedirect: responseBody.isRedirect,
statusCode: responseBody.statusCode,
statusMessage: responseBody.statusMessage,
extra: responseBody.extra,
);
final statusOk = reqOpt.validateStatus(responseBody.statusCode);
if (statusOk || reqOpt.receiveDataWhenStatusError == true) {
responseBody.stream = handleResponseStream(reqOpt, responseBody);
Object? data = await transformer.transformResponse(
reqOpt,
responseBody,
);
// Make the response as null before returned as JSON.
if (data is String &&
data.isEmpty &&
T != dynamic &&
T != String &&
reqOpt.responseType == ResponseType.json) {
data = null;
}
ret.data = data;
} else {
responseBody.close();
}
checkCancelled(cancelToken);
if (statusOk) {
return ret;
} else {
throw DioException.badResponse(
statusCode: responseBody.statusCode,
requestOptions: reqOpt,
response: ret,
);
}
} catch (e) {
throw assureDioException(e, reqOpt);
}
}
bool _isValidToken(String token) {
_checkNotNullable(token, 'token');
// from https://www.rfc-editor.org/rfc/rfc2616#page-15
//
// CTL = <any US-ASCII control character
// (octets 0 - 31) and DEL (127)>
// separators = "(" | ")" | "<" | ">" | "@"
// | "," | ";" | ":" | "\" | <">
// | "/" | "[" | "]" | "?" | "="
// | "{" | "}" | SP | HT
// token = 1*<any CHAR except CTLs or separators>
const String validChars = r' '
r" ! #$%&' *+ -. 0123456789 "
r' ABCDEFGHIJKLMNOPQRSTUVWXYZ ^_'
r'`abcdefghijklmnopqrstuvwxyz | ~ ';
for (final int codeUnit in token.codeUnits) {
if (codeUnit >= validChars.length ||
validChars.codeUnitAt(codeUnit) == 0x20) {
return false;
}
}
return true;
}
Future<Stream<Uint8List>?> _transformData(RequestOptions options) async {
if (!_isValidToken(options.method)) {
throw ArgumentError.value(options.method, 'method');
}
final data = options.data;
if (data != null) {
final Stream<List<int>> stream;
// Handle the FormData.
int? length;
if (data is Stream) {
if (data is! Stream<List<int>>) {
throw ArgumentError.value(
data.runtimeType,
'data',
'Stream type must be `Stream<List<int>>`',
);
}
stream = data;
options.headers.keys.any((String key) {
if (key.toLowerCase() == Headers.contentLengthHeader) {
length = int.parse(options.headers[key].toString());
return true;
}
return false;
});
} else if (data is FormData) {
options.headers[Headers.contentTypeHeader] =
'${Headers.multipartFormDataContentType}; '
'boundary=${data.boundary}';
stream = data.finalize();
length = data.length;
options.headers[Headers.contentLengthHeader] = length.toString();
} else {
final List<int> bytes;
if (data is Uint8List) {
// Handle binary data which does not need to be transformed.
bytes = data;
} else {
// Call the request transformer.
final transformed = await transformer.transformRequest(options);
if (options.requestEncoder != null) {
final encoded = options.requestEncoder!(transformed, options);
if (encoded is Future) {
bytes = await encoded;
} else {
bytes
gitextract_7_0du2a0/
├── .github/
│ ├── FUNDING.yml
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug.yml
│ │ ├── config.yaml
│ │ ├── feature.yml
│ │ └── infra.yml
│ ├── PULL_REQUEST_TEMPLATE.md
│ ├── dependabot.yaml
│ └── workflows/
│ ├── check_issues_access.yml
│ ├── coverage_base.yml
│ ├── coverage_comment.yml
│ ├── publish.yml
│ └── tests.yml
├── .gitignore
├── .idea/
│ └── modules.xml
├── CODEOWNERS
├── CODE_OF_CONDUCT.md
├── COMPATIBILITY_POLICY.md
├── CONTRIBUTING-ZH.md
├── CONTRIBUTING.md
├── LICENSE
├── README-ZH.md
├── README.md
├── SECURITY.md
├── analysis_options.yaml
├── dio/
│ ├── .gitignore
│ ├── CHANGELOG.md
│ ├── LICENSE
│ ├── README-ZH.md
│ ├── README.md
│ ├── analysis_options.yaml
│ ├── dart_test.yaml
│ ├── dartdoc_options.yaml
│ ├── dio.iml
│ ├── doc/
│ │ ├── migration_guide.md
│ │ └── plugins.md
│ ├── example/
│ │ └── dio.dart
│ ├── lib/
│ │ ├── browser.dart
│ │ ├── dio.dart
│ │ ├── fix_data/
│ │ │ └── fix.yaml
│ │ ├── io.dart
│ │ └── src/
│ │ ├── adapter.dart
│ │ ├── adapters/
│ │ │ ├── browser_adapter.dart
│ │ │ └── io_adapter.dart
│ │ ├── cancel_token.dart
│ │ ├── compute/
│ │ │ ├── compute.dart
│ │ │ ├── compute_io.dart
│ │ │ └── compute_web.dart
│ │ ├── dio/
│ │ │ ├── dio_for_browser.dart
│ │ │ └── dio_for_native.dart
│ │ ├── dio.dart
│ │ ├── dio_exception.dart
│ │ ├── dio_mixin.dart
│ │ ├── form_data.dart
│ │ ├── headers.dart
│ │ ├── interceptor.dart
│ │ ├── interceptors/
│ │ │ ├── imply_content_type.dart
│ │ │ └── log.dart
│ │ ├── multipart_file/
│ │ │ ├── browser_multipart_file.dart
│ │ │ └── io_multipart_file.dart
│ │ ├── multipart_file.dart
│ │ ├── options.dart
│ │ ├── parameter.dart
│ │ ├── progress_stream/
│ │ │ ├── browser_progress_stream.dart
│ │ │ └── io_progress_stream.dart
│ │ ├── redirect_record.dart
│ │ ├── response/
│ │ │ └── response_stream_handler.dart
│ │ ├── response.dart
│ │ ├── transformer.dart
│ │ ├── transformers/
│ │ │ ├── background_transformer.dart
│ │ │ ├── fused_transformer.dart
│ │ │ ├── sync_transformer.dart
│ │ │ └── util/
│ │ │ ├── consolidate_bytes.dart
│ │ │ └── transform_empty_to_null.dart
│ │ └── utils.dart
│ ├── pubspec.yaml
│ └── test/
│ ├── adapters_test.dart
│ ├── cancel_token_test.dart
│ ├── connect_timeout_integration_test.dart
│ ├── dio_mixin_test.dart
│ ├── encoding_test.dart
│ ├── exception_test.dart
│ ├── formdata_test.dart
│ ├── headers_test.dart
│ ├── interceptor_test.dart
│ ├── mimetype_test.dart
│ ├── mock/
│ │ ├── _formdata
│ │ ├── _testfile
│ │ ├── adapters.dart
│ │ ├── http_mock.dart
│ │ └── http_mock.mocks.dart
│ ├── multipart_file_test.dart
│ ├── options_test.dart
│ ├── options_timeout_integration_test.dart
│ ├── parameter_test.dart
│ ├── pinning_test.dart
│ ├── queued_interceptor_test.dart
│ ├── response/
│ │ └── response_stream_test.dart
│ ├── stacktrace_test.dart
│ ├── test_suite_test.dart
│ ├── timeout_test.dart
│ ├── transformer_test.dart
│ └── utils.dart
├── dio_test/
│ ├── LICENSE
│ ├── README.md
│ ├── analysis_options.yaml
│ ├── dio_test.iml
│ ├── lib/
│ │ ├── src/
│ │ │ ├── httpbun.dart
│ │ │ ├── matcher.dart
│ │ │ ├── test/
│ │ │ │ ├── basic_tests.dart
│ │ │ │ ├── cancellation_tests.dart
│ │ │ │ ├── cors_tests.dart
│ │ │ │ ├── download_tests.dart
│ │ │ │ ├── headers_tests.dart
│ │ │ │ ├── http_method_tests.dart
│ │ │ │ ├── parameter_tests.dart
│ │ │ │ ├── redirect_tests.dart
│ │ │ │ ├── status_code_tests.dart
│ │ │ │ ├── suite.dart
│ │ │ │ ├── timeout_tests.dart
│ │ │ │ ├── upload_tests.dart
│ │ │ │ └── url_encoded_tests.dart
│ │ │ └── utils.dart
│ │ ├── tests.dart
│ │ └── util.dart
│ └── pubspec.yaml
├── dio_workspace.iml
├── example_dart/
│ ├── .gitignore
│ ├── analysis_options.yaml
│ ├── dart_test.yaml
│ ├── dio_example.iml
│ ├── lib/
│ │ ├── adapter.dart
│ │ ├── cancel_request.dart
│ │ ├── certificate_pinning.dart
│ │ ├── cookie_mgr.dart
│ │ ├── custom_cache_interceptor.dart
│ │ ├── dio.dart
│ │ ├── download.dart
│ │ ├── download_with_trunks.dart
│ │ ├── extend_dio.dart
│ │ ├── formdata.dart
│ │ ├── generic.dart
│ │ ├── http2_adapter.dart
│ │ ├── options.dart
│ │ ├── post_stream_and_bytes.dart
│ │ ├── proxy.dart
│ │ ├── queue_interceptors.dart
│ │ ├── queued_interceptor_crsftoken.dart
│ │ ├── request_interceptors.dart
│ │ ├── response_interceptor.dart
│ │ ├── test.dart
│ │ ├── transformer.dart
│ │ └── upload.txt
│ └── pubspec.yaml
├── example_flutter_app/
│ ├── .gitignore
│ ├── .metadata
│ ├── README.md
│ ├── analysis_options.yaml
│ ├── android/
│ │ ├── .gitignore
│ │ ├── app/
│ │ │ ├── build.gradle.kts
│ │ │ └── src/
│ │ │ └── main/
│ │ │ ├── AndroidManifest.xml
│ │ │ ├── kotlin/
│ │ │ │ └── cn/
│ │ │ │ └── flutter/
│ │ │ │ └── dio_flutter_example/
│ │ │ │ └── MainActivity.kt
│ │ │ └── res/
│ │ │ ├── drawable/
│ │ │ │ └── launch_background.xml
│ │ │ ├── drawable-v21/
│ │ │ │ └── launch_background.xml
│ │ │ ├── values/
│ │ │ │ └── styles.xml
│ │ │ └── values-night/
│ │ │ └── styles.xml
│ │ ├── build.gradle.kts
│ │ ├── dio_flutter_example_android.iml
│ │ ├── gradle/
│ │ │ └── wrapper/
│ │ │ └── gradle-wrapper.properties
│ │ ├── gradle.properties
│ │ └── settings.gradle.kts
│ ├── dio_flutter_example.iml
│ ├── example_flutter_app.iml
│ ├── ios/
│ │ ├── .gitignore
│ │ ├── Flutter/
│ │ │ ├── AppFrameworkInfo.plist
│ │ │ ├── Debug.xcconfig
│ │ │ └── Release.xcconfig
│ │ ├── Runner/
│ │ │ ├── AppDelegate.swift
│ │ │ ├── Assets.xcassets/
│ │ │ │ ├── AppIcon.appiconset/
│ │ │ │ │ └── Contents.json
│ │ │ │ └── LaunchImage.imageset/
│ │ │ │ ├── Contents.json
│ │ │ │ └── README.md
│ │ │ ├── Base.lproj/
│ │ │ │ ├── LaunchScreen.storyboard
│ │ │ │ └── Main.storyboard
│ │ │ ├── Info.plist
│ │ │ └── Runner-Bridging-Header.h
│ │ ├── Runner.xcodeproj/
│ │ │ ├── project.pbxproj
│ │ │ ├── project.xcworkspace/
│ │ │ │ ├── contents.xcworkspacedata
│ │ │ │ └── xcshareddata/
│ │ │ │ ├── IDEWorkspaceChecks.plist
│ │ │ │ └── WorkspaceSettings.xcsettings
│ │ │ └── xcshareddata/
│ │ │ └── xcschemes/
│ │ │ └── Runner.xcscheme
│ │ ├── Runner.xcworkspace/
│ │ │ ├── contents.xcworkspacedata
│ │ │ └── xcshareddata/
│ │ │ ├── IDEWorkspaceChecks.plist
│ │ │ └── WorkspaceSettings.xcsettings
│ │ └── RunnerTests/
│ │ └── RunnerTests.swift
│ ├── lib/
│ │ ├── http.dart
│ │ ├── main.dart
│ │ └── routes/
│ │ └── request.dart
│ ├── linux/
│ │ ├── .gitignore
│ │ ├── CMakeLists.txt
│ │ ├── flutter/
│ │ │ ├── CMakeLists.txt
│ │ │ ├── generated_plugin_registrant.cc
│ │ │ ├── generated_plugin_registrant.h
│ │ │ └── generated_plugins.cmake
│ │ └── runner/
│ │ ├── CMakeLists.txt
│ │ ├── main.cc
│ │ ├── my_application.cc
│ │ └── my_application.h
│ ├── macos/
│ │ ├── .gitignore
│ │ ├── Flutter/
│ │ │ ├── Flutter-Debug.xcconfig
│ │ │ ├── Flutter-Release.xcconfig
│ │ │ └── GeneratedPluginRegistrant.swift
│ │ ├── Runner/
│ │ │ ├── AppDelegate.swift
│ │ │ ├── Assets.xcassets/
│ │ │ │ └── AppIcon.appiconset/
│ │ │ │ └── Contents.json
│ │ │ ├── Base.lproj/
│ │ │ │ └── MainMenu.xib
│ │ │ ├── Configs/
│ │ │ │ ├── AppInfo.xcconfig
│ │ │ │ ├── Debug.xcconfig
│ │ │ │ ├── Release.xcconfig
│ │ │ │ └── Warnings.xcconfig
│ │ │ ├── DebugProfile.entitlements
│ │ │ ├── Info.plist
│ │ │ ├── MainFlutterWindow.swift
│ │ │ └── Release.entitlements
│ │ ├── Runner.xcodeproj/
│ │ │ ├── project.pbxproj
│ │ │ ├── project.xcworkspace/
│ │ │ │ └── xcshareddata/
│ │ │ │ └── IDEWorkspaceChecks.plist
│ │ │ └── xcshareddata/
│ │ │ └── xcschemes/
│ │ │ └── Runner.xcscheme
│ │ ├── Runner.xcworkspace/
│ │ │ ├── contents.xcworkspacedata
│ │ │ └── xcshareddata/
│ │ │ └── IDEWorkspaceChecks.plist
│ │ └── RunnerTests/
│ │ └── RunnerTests.swift
│ ├── pubspec.yaml
│ ├── web/
│ │ ├── index.html
│ │ └── manifest.json
│ └── windows/
│ ├── .gitignore
│ ├── CMakeLists.txt
│ ├── flutter/
│ │ ├── CMakeLists.txt
│ │ ├── generated_plugin_registrant.cc
│ │ ├── generated_plugin_registrant.h
│ │ └── generated_plugins.cmake
│ └── runner/
│ ├── CMakeLists.txt
│ ├── Runner.rc
│ ├── flutter_window.cpp
│ ├── flutter_window.h
│ ├── main.cpp
│ ├── resource.h
│ ├── runner.exe.manifest
│ ├── utils.cpp
│ ├── utils.h
│ ├── win32_window.cpp
│ └── win32_window.h
├── melos.yaml
├── plugins/
│ ├── compatibility_layer/
│ │ ├── .gitignore
│ │ ├── CHANGELOG.md
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── analysis_options.yaml
│ │ ├── dart_test.yaml
│ │ ├── dio_compatibility_layer.iml
│ │ ├── example/
│ │ │ └── conversion_layer_example.dart
│ │ ├── lib/
│ │ │ ├── dio_compatibility_layer.dart
│ │ │ └── src/
│ │ │ └── conversion_layer_adapter.dart
│ │ ├── pubspec.yaml
│ │ └── test/
│ │ ├── client_mock.dart
│ │ └── conversion_layer_adapter_test.dart
│ ├── cookie_manager/
│ │ ├── .gitignore
│ │ ├── .metadata
│ │ ├── CHANGELOG.md
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── analysis_options.yaml
│ │ ├── dart_test.yaml
│ │ ├── dio_cookie_manager.iml
│ │ ├── example/
│ │ │ └── example.dart
│ │ ├── lib/
│ │ │ ├── dio_cookie_manager.dart
│ │ │ └── src/
│ │ │ ├── cookie_mgr.dart
│ │ │ └── exception.dart
│ │ ├── pubspec.yaml
│ │ └── test/
│ │ ├── basic_test.dart
│ │ ├── cookies_persistance_test.dart
│ │ └── cookies_test.dart
│ ├── http2_adapter/
│ │ ├── .gitignore
│ │ ├── .metadata
│ │ ├── CHANGELOG.md
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── analysis_options.yaml
│ │ ├── dart_test.yaml
│ │ ├── dio_http2_adapter.iml
│ │ ├── doc/
│ │ │ └── migration_guide.md
│ │ ├── example/
│ │ │ └── example.dart
│ │ ├── lib/
│ │ │ ├── dio_http2_adapter.dart
│ │ │ └── src/
│ │ │ ├── client_setting.dart
│ │ │ ├── connection_manager.dart
│ │ │ ├── connection_manager_imp.dart
│ │ │ └── http2_adapter.dart
│ │ ├── pubspec.yaml
│ │ └── test/
│ │ ├── http2_test.dart
│ │ ├── pinning_test.dart
│ │ ├── redirect_test.dart
│ │ └── test_suite_test.dart
│ ├── native_dio_adapter/
│ │ ├── .gitignore
│ │ ├── CHANGELOG.md
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── analysis_options.yaml
│ │ ├── example/
│ │ │ ├── .gitignore
│ │ │ ├── analysis_options.yaml
│ │ │ ├── android/
│ │ │ │ ├── .gitignore
│ │ │ │ ├── app/
│ │ │ │ │ ├── build.gradle
│ │ │ │ │ └── src/
│ │ │ │ │ ├── debug/
│ │ │ │ │ │ └── AndroidManifest.xml
│ │ │ │ │ ├── main/
│ │ │ │ │ │ ├── AndroidManifest.xml
│ │ │ │ │ │ ├── kotlin/
│ │ │ │ │ │ │ └── com/
│ │ │ │ │ │ │ └── example/
│ │ │ │ │ │ │ └── example/
│ │ │ │ │ │ │ └── MainActivity.kt
│ │ │ │ │ │ └── res/
│ │ │ │ │ │ ├── drawable/
│ │ │ │ │ │ │ └── launch_background.xml
│ │ │ │ │ │ ├── drawable-v21/
│ │ │ │ │ │ │ └── launch_background.xml
│ │ │ │ │ │ ├── values/
│ │ │ │ │ │ │ └── styles.xml
│ │ │ │ │ │ └── values-night/
│ │ │ │ │ │ └── styles.xml
│ │ │ │ │ └── profile/
│ │ │ │ │ └── AndroidManifest.xml
│ │ │ │ ├── build.gradle
│ │ │ │ ├── gradle/
│ │ │ │ │ └── wrapper/
│ │ │ │ │ └── gradle-wrapper.properties
│ │ │ │ ├── gradle.properties
│ │ │ │ └── settings.gradle
│ │ │ ├── ios/
│ │ │ │ ├── .gitignore
│ │ │ │ ├── Flutter/
│ │ │ │ │ ├── AppFrameworkInfo.plist
│ │ │ │ │ ├── Debug.xcconfig
│ │ │ │ │ └── Release.xcconfig
│ │ │ │ ├── Podfile
│ │ │ │ ├── Runner/
│ │ │ │ │ ├── AppDelegate.swift
│ │ │ │ │ ├── Assets.xcassets/
│ │ │ │ │ │ ├── AppIcon.appiconset/
│ │ │ │ │ │ │ └── Contents.json
│ │ │ │ │ │ └── LaunchImage.imageset/
│ │ │ │ │ │ ├── Contents.json
│ │ │ │ │ │ └── README.md
│ │ │ │ │ ├── Base.lproj/
│ │ │ │ │ │ ├── LaunchScreen.storyboard
│ │ │ │ │ │ └── Main.storyboard
│ │ │ │ │ ├── Info.plist
│ │ │ │ │ └── Runner-Bridging-Header.h
│ │ │ │ ├── Runner.xcodeproj/
│ │ │ │ │ ├── project.pbxproj
│ │ │ │ │ ├── project.xcworkspace/
│ │ │ │ │ │ ├── contents.xcworkspacedata
│ │ │ │ │ │ └── xcshareddata/
│ │ │ │ │ │ ├── IDEWorkspaceChecks.plist
│ │ │ │ │ │ └── WorkspaceSettings.xcsettings
│ │ │ │ │ └── xcshareddata/
│ │ │ │ │ └── xcschemes/
│ │ │ │ │ └── Runner.xcscheme
│ │ │ │ └── Runner.xcworkspace/
│ │ │ │ ├── contents.xcworkspacedata
│ │ │ │ └── xcshareddata/
│ │ │ │ ├── IDEWorkspaceChecks.plist
│ │ │ │ └── WorkspaceSettings.xcsettings
│ │ │ ├── lib/
│ │ │ │ └── main.dart
│ │ │ ├── linux/
│ │ │ │ ├── .gitignore
│ │ │ │ ├── CMakeLists.txt
│ │ │ │ ├── flutter/
│ │ │ │ │ ├── CMakeLists.txt
│ │ │ │ │ ├── generated_plugin_registrant.cc
│ │ │ │ │ ├── generated_plugin_registrant.h
│ │ │ │ │ └── generated_plugins.cmake
│ │ │ │ ├── main.cc
│ │ │ │ ├── my_application.cc
│ │ │ │ └── my_application.h
│ │ │ ├── macos/
│ │ │ │ ├── .gitignore
│ │ │ │ ├── Flutter/
│ │ │ │ │ ├── Flutter-Debug.xcconfig
│ │ │ │ │ ├── Flutter-Release.xcconfig
│ │ │ │ │ └── GeneratedPluginRegistrant.swift
│ │ │ │ ├── Podfile
│ │ │ │ ├── Runner/
│ │ │ │ │ ├── AppDelegate.swift
│ │ │ │ │ ├── Assets.xcassets/
│ │ │ │ │ │ └── AppIcon.appiconset/
│ │ │ │ │ │ └── Contents.json
│ │ │ │ │ ├── Base.lproj/
│ │ │ │ │ │ └── MainMenu.xib
│ │ │ │ │ ├── Configs/
│ │ │ │ │ │ ├── AppInfo.xcconfig
│ │ │ │ │ │ ├── Debug.xcconfig
│ │ │ │ │ │ ├── Release.xcconfig
│ │ │ │ │ │ └── Warnings.xcconfig
│ │ │ │ │ ├── DebugProfile.entitlements
│ │ │ │ │ ├── Info.plist
│ │ │ │ │ ├── MainFlutterWindow.swift
│ │ │ │ │ └── Release.entitlements
│ │ │ │ ├── Runner.xcodeproj/
│ │ │ │ │ ├── project.pbxproj
│ │ │ │ │ ├── project.xcworkspace/
│ │ │ │ │ │ └── xcshareddata/
│ │ │ │ │ │ └── IDEWorkspaceChecks.plist
│ │ │ │ │ └── xcshareddata/
│ │ │ │ │ └── xcschemes/
│ │ │ │ │ └── Runner.xcscheme
│ │ │ │ └── Runner.xcworkspace/
│ │ │ │ ├── contents.xcworkspacedata
│ │ │ │ └── xcshareddata/
│ │ │ │ └── IDEWorkspaceChecks.plist
│ │ │ ├── pubspec.yaml
│ │ │ ├── web/
│ │ │ │ ├── index.html
│ │ │ │ └── manifest.json
│ │ │ └── windows/
│ │ │ ├── .gitignore
│ │ │ ├── CMakeLists.txt
│ │ │ ├── flutter/
│ │ │ │ ├── CMakeLists.txt
│ │ │ │ ├── generated_plugin_registrant.cc
│ │ │ │ ├── generated_plugin_registrant.h
│ │ │ │ └── generated_plugins.cmake
│ │ │ └── runner/
│ │ │ ├── CMakeLists.txt
│ │ │ ├── Runner.rc
│ │ │ ├── flutter_window.cpp
│ │ │ ├── flutter_window.h
│ │ │ ├── main.cpp
│ │ │ ├── resource.h
│ │ │ ├── runner.exe.manifest
│ │ │ ├── utils.cpp
│ │ │ ├── utils.h
│ │ │ ├── win32_window.cpp
│ │ │ └── win32_window.h
│ │ ├── lib/
│ │ │ ├── fix_data/
│ │ │ │ └── fix.yaml
│ │ │ ├── native_dio_adapter.dart
│ │ │ └── src/
│ │ │ ├── conversion_layer_adapter.dart
│ │ │ ├── cronet_adapter.dart
│ │ │ ├── cupertino_adapter.dart
│ │ │ └── native_adapter.dart
│ │ ├── native_dio_adapter.iml
│ │ ├── pubspec.yaml
│ │ └── test/
│ │ ├── client_mock.dart
│ │ └── conversion_layer_adapter_test.dart
│ └── web_adapter/
│ ├── .gitignore
│ ├── CHANGELOG.md
│ ├── LICENSE
│ ├── README.md
│ ├── analysis_options.yaml
│ ├── dart_test.yaml
│ ├── dio_web_adapter.iml
│ ├── example/
│ │ └── main.dart
│ ├── lib/
│ │ ├── dio_web_adapter.dart
│ │ └── src/
│ │ ├── adapter.dart
│ │ ├── adapter_impl.dart
│ │ ├── compute.dart
│ │ ├── compute_impl.dart
│ │ ├── dio_impl.dart
│ │ ├── multipart_file.dart
│ │ ├── multipart_file_impl.dart
│ │ ├── progress_stream.dart
│ │ └── progress_stream_impl.dart
│ ├── pubspec.yaml
│ └── test/
│ └── browser_test.dart
├── pubspec.yaml
└── scripts/
├── melos_packages.dart
└── prepare_pinning_certs.sh
SYMBOL INDEX (674 symbols across 147 files)
FILE: dio/example/dio.dart
function main (line 4) | void main()
FILE: dio/lib/src/adapter.dart
class HttpClientAdapter (line 27) | abstract class HttpClientAdapter {
method fetch (line 55) | Future<ResponseBody> fetch(
method close (line 62) | void close({bool force = false})
class ResponseBody (line 68) | class ResponseBody {
method close (line 135) | void close()
FILE: dio/lib/src/adapters/io_adapter.dart
type DefaultHttpClientAdapter (line 10) | @Deprecated('Use IOHttpClientAdapter instead. This will be removed in 6....
type OnHttpClientCreate (line 14) | @Deprecated('Use CreateHttpClient instead. This will be removed in 6.0.0')
type CreateHttpClient (line 19) | typedef CreateHttpClient = HttpClient Function();
type ValidateCertificate (line 22) | typedef ValidateCertificate = bool Function(
function createAdapter (line 29) | HttpClientAdapter createAdapter()
class IOHttpClientAdapter (line 32) | class IOHttpClientAdapter implements HttpClientAdapter {
method fetch (line 61) | Future<ResponseBody> fetch(
method _fetch (line 74) | Future<ResponseBody> _fetch(
method _configHttpClient (line 225) | HttpClient _configHttpClient(Duration? connectionTimeout)
method close (line 237) | void close({bool force = false})
method _createHttpClient (line 242) | HttpClient _createHttpClient()
FILE: dio/lib/src/cancel_token.dart
class CancelToken (line 13) | class CancelToken {
method isCancel (line 19) | bool isCancel(DioException error)
method cancel (line 38) | void cancel([Object? reason])
FILE: dio/lib/src/compute/compute.dart
type ComputeCallback (line 46) | typedef ComputeCallback<Q, R> = FutureOr<R> Function(Q message);
type ComputeImpl (line 66) | typedef ComputeImpl = Future<R> Function<Q, R>(
FILE: dio/lib/src/compute/compute_io.dart
function compute (line 29) | Future<R> compute<Q, R>(
function timeEndAndCleanup (line 41) | void timeEndAndCleanup()
class _IsolateConfiguration (line 110) | class _IsolateConfiguration<Q, R> {
method applyAndTime (line 125) | FutureOr<R> applyAndTime()
function _spawn (line 143) | Future<void> _spawn<Q, R>(_IsolateConfiguration<Q, R> configuration)
function _buildSuccessResponse (line 161) | List<R> _buildSuccessResponse<R>(R result)
function _buildErrorResponse (line 170) | List<dynamic> _buildErrorResponse(Object error, StackTrace stack)
FILE: dio/lib/src/dio.dart
class Dio (line 37) | abstract class Dio {
method close (line 64) | void close({bool force = false})
method head (line 67) | Future<Response<T>> head<T>(
method headUri (line 76) | Future<Response<T>> headUri<T>(
method get (line 84) | Future<Response<T>> get<T>(
method getUri (line 94) | Future<Response<T>> getUri<T>(
method post (line 103) | Future<Response<T>> post<T>(
method postUri (line 114) | Future<Response<T>> postUri<T>(
method put (line 124) | Future<Response<T>> put<T>(
method putUri (line 135) | Future<Response<T>> putUri<T>(
method patch (line 145) | Future<Response<T>> patch<T>(
method patchUri (line 156) | Future<Response<T>> patchUri<T>(
method delete (line 166) | Future<Response<T>> delete<T>(
method deleteUri (line 175) | Future<Response<T>> deleteUri<T>(
method download (line 241) | Future<Response> download(
method downloadUri (line 255) | Future<Response> downloadUri(
method request (line 280) | Future<Response<T>> request<T>(
method requestUri (line 291) | Future<Response<T>> requestUri<T>(
method fetch (line 302) | Future<Response<T>> fetch<T>(RequestOptions requestOptions)
method clone (line 305) | Dio clone({
FILE: dio/lib/src/dio/dio_for_native.dart
function createDio (line 15) | Dio createDio([BaseOptions? baseOptions])
class DioForNative (line 18) | class DioForNative with DioMixin implements Dio {
method download (line 28) | Future<Response> download(
method closeAndDelete (line 127) | Future<void> closeAndDelete()
FILE: dio/lib/src/dio_exception.dart
type DioErrorType (line 6) | @Deprecated('Use DioExceptionType instead. This will be removed in 6.0.0')
type DioError (line 10) | @Deprecated('Use DioException instead. This will be removed in 6.0.0')
type DioExceptionType (line 15) | enum DioExceptionType {
function toPrettyDescription (line 44) | String toPrettyDescription()
class DioException (line 67) | class DioException implements Exception {
method copyWith (line 218) | DioException copyWith({
method toString (line 237) | String toString()
method _badResponseExceptionMessage (line 248) | String _badResponseExceptionMessage(int statusCode)
type DioExceptionReadableStringBuilder (line 294) | typedef DioExceptionReadableStringBuilder = String Function(DioException...
function defaultDioExceptionReadableStringBuilder (line 297) | String defaultDioExceptionReadableStringBuilder(DioException e)
FILE: dio/lib/src/dio_mixin.dart
class DioMixin (line 28) | abstract class DioMixin implements Dio {
method close (line 57) | void close({bool force = false})
method get (line 63) | Future<Response<T>> get<T>(
method getUri (line 82) | Future<Response<T>> getUri<T>(
method post (line 99) | Future<Response<T>> post<T>(
method postUri (line 120) | Future<Response<T>> postUri<T>(
method put (line 139) | Future<Response<T>> put<T>(
method putUri (line 160) | Future<Response<T>> putUri<T>(
method head (line 179) | Future<Response<T>> head<T>(
method headUri (line 196) | Future<Response<T>> headUri<T>(
method delete (line 211) | Future<Response<T>> delete<T>(
method deleteUri (line 228) | Future<Response<T>> deleteUri<T>(
method patch (line 243) | Future<Response<T>> patch<T>(
method patchUri (line 264) | Future<Response<T>> patchUri<T>(
method downloadUri (line 283) | Future<Response> downloadUri(
method download (line 308) | Future<Response> download(
method requestUri (line 324) | Future<Response<T>> requestUri<T>(
method request (line 343) | Future<Response<T>> request<T>(
method fetch (line 378) | Future<Response<T>> fetch<T>(RequestOptions requestOptions)
method requestInterceptorWrapper (line 391) | FutureOr Function(dynamic) requestInterceptorWrapper(
method responseInterceptorWrapper (line 412) | FutureOr<dynamic> Function(dynamic) responseInterceptorWrapper(
method errorInterceptorWrapper (line 434) | FutureOr<dynamic> Function(Object) errorInterceptorWrapper(
method handleError (line 441) | Future<InterceptorState> handleError()
method _dispatchRequest (line 527) | Future<Response<dynamic>> _dispatchRequest<T>(RequestOptions reqOpt)
method _isValidToken (line 593) | bool _isValidToken(String token)
method _transformData (line 617) | Future<Stream<Uint8List>?> _transformData(RequestOptions options)
method checkCancelled (line 691) | void checkCancelled(CancelToken? cancelToken)
method listenCancelForAsyncTask (line 699) | Future<T> listenCancelForAsyncTask<T>(
method checkOptions (line 710) | Options checkOptions(String method, Options? options)
method assureDioException (line 717) | DioException assureDioException(
method assureResponse (line 731) | Response<T> assureResponse<T>(
method clone (line 766) | Dio clone({
function _checkNotNullable (line 790) | T _checkNotNullable<T extends Object>(T value, String name)
class NotNullableError (line 798) | class NotNullableError<T> extends Error implements TypeError {
method toString (line 804) | String toString()
FILE: dio/lib/src/form_data.dart
class FormData (line 22) | class FormData {
method _init (line 47) | void _init({
method _headerForField (line 94) | String _headerForField(String name, String value)
method _headerForFile (line 102) | String _headerForFile(MapEntry<String, MultipartFile> entry)
method _browserEncode (line 132) | String? _browserEncode(String? value)
method finalize (line 164) | Stream<Uint8List> finalize()
method writeLine (line 176) | void writeLine()
method writeUtf8 (line 177) | void writeUtf8(String s)
method readAsBytes (line 204) | Future<Uint8List> readAsBytes()
method clone (line 211) | FormData clone()
function _effectiveU8Encoding (line 222) | Uint8List _effectiveU8Encoding(List<int> encoded)
FILE: dio/lib/src/headers.dart
type HeaderForEachCallback (line 6) | typedef HeaderForEachCallback = void Function(String name, List<String> ...
class Headers (line 9) | class Headers {
method value (line 54) | String? value(String name)
method add (line 69) | void add(String name, String value)
method set (line 79) | void set(String name, dynamic value)
method remove (line 92) | void remove(String name, String value)
method removeAll (line 101) | void removeAll(String name)
method clear (line 106) | void clear()
method forEach (line 116) | void forEach(HeaderForEachCallback f)
method toString (line 123) | String toString()
FILE: dio/lib/src/interceptor.dart
type InterceptorResultType (line 4) | enum InterceptorResultType {
class InterceptorState (line 13) | class InterceptorState<T> {
method toString (line 20) | String toString()
class _BaseHandler (line 23) | abstract class _BaseHandler {
method _throwIfCompleted (line 32) | void _throwIfCompleted()
class RequestInterceptorHandler (line 43) | class RequestInterceptorHandler extends _BaseHandler {
method next (line 48) | void next(RequestOptions requestOptions)
method resolve (line 61) | void resolve(
method reject (line 84) | void reject(
class ResponseInterceptorHandler (line 103) | class ResponseInterceptorHandler extends _BaseHandler {
method next (line 108) | void next(Response response)
method resolve (line 117) | void resolve(Response response)
method reject (line 135) | void reject(
class ErrorInterceptorHandler (line 154) | class ErrorInterceptorHandler extends _BaseHandler {
method next (line 159) | void next(DioException error)
method resolve (line 169) | void resolve(Response response)
method reject (line 181) | void reject(DioException error)
class Interceptor (line 203) | class Interceptor {
method onRequest (line 209) | void onRequest(
method onResponse (line 217) | void onResponse(
method onError (line 225) | void onError(
type InterceptorSendCallback (line 234) | typedef InterceptorSendCallback = void Function(
type InterceptorSuccessCallback (line 240) | typedef InterceptorSuccessCallback = void Function(
type InterceptorErrorCallback (line 246) | typedef InterceptorErrorCallback = void Function(
function onRequest (line 257) | void onRequest(
function onResponse (line 269) | void onResponse(
function onError (line 281) | void onError(
class InterceptorsWrapper (line 297) | class InterceptorsWrapper extends Interceptor with _InterceptorWrapperMi...
class Interceptors (line 322) | class Interceptors extends ListMixin<Interceptor> {
method clear (line 355) | void clear({bool keepImplyContentTypeInterceptor = true})
method removeImplyContentTypeInterceptor (line 364) | void removeImplyContentTypeInterceptor()
class _InterceptorParams (line 369) | class _InterceptorParams<T, V extends _BaseHandler> {
class _TaskQueue (line 376) | class _TaskQueue<T, V extends _BaseHandler> {
class QueuedInterceptor (line 386) | class QueuedInterceptor extends Interceptor {
method _handleRequest (line 391) | void _handleRequest(
method _handleResponse (line 407) | void _handleResponse(
method _handleError (line 423) | void _handleError(
method _handleQueue (line 439) | void _handleQueue<T, V extends _BaseHandler>(
class QueuedInterceptorsWrapper (line 476) | class QueuedInterceptorsWrapper extends QueuedInterceptor
FILE: dio/lib/src/interceptors/imply_content_type.dart
class ImplyContentTypeInterceptor (line 13) | class ImplyContentTypeInterceptor extends Interceptor {
method onRequest (line 17) | void onRequest(
FILE: dio/lib/src/interceptors/log.dart
class LogInterceptor (line 22) | class LogInterceptor extends Interceptor {
method onRequest (line 72) | void onRequest(
method onResponse (line 81) | void onResponse(Response response, ResponseInterceptorHandler handler)
method onError (line 87) | void onError(DioException err, ErrorInterceptorHandler handler)
method _printRequest (line 101) | void _printRequest(RequestOptions options)
method _printResponse (line 139) | void _printResponse(Response response)
method _printKV (line 170) | void _printKV(String key, Object? v)
method _printAll (line 174) | void _printAll(Object? msg)
function _debugPrint (line 179) | void _debugPrint(Object? object)
FILE: dio/lib/src/multipart_file.dart
type DioMediaType (line 13) | typedef DioMediaType = MediaType;
class MultipartFile (line 17) | class MultipartFile {
method fromFile (line 133) | Future<MultipartFile> fromFile(
method fromFileSync (line 147) | MultipartFile fromFileSync(
method lookupMediaType (line 162) | DioMediaType? lookupMediaType(String? filenameOrPath)
method finalize (line 178) | Stream<Uint8List> finalize()
method clone (line 197) | MultipartFile clone()
FILE: dio/lib/src/multipart_file/io_multipart_file.dart
function multipartFileFromPath (line 8) | Future<MultipartFile> multipartFileFromPath(
function multipartFileFromPathSync (line 26) | MultipartFile multipartFileFromPathSync(
function _getStreamFromFilepath (line 44) | Stream<List<int>> _getStreamFromFilepath(File file)
FILE: dio/lib/src/options.dart
type ProgressCallback (line 21) | typedef ProgressCallback = void Function(int count, int total);
type ResponseType (line 24) | enum ResponseType {
type ListFormat (line 51) | enum ListFormat {
type ValidateStatus (line 78) | typedef ValidateStatus = bool Function(int? status);
type ResponseDecoder (line 81) | typedef ResponseDecoder = FutureOr<String?> Function(
type RequestEncoder (line 88) | typedef RequestEncoder = FutureOr<List<int>> Function(
class BaseOptions (line 141) | class BaseOptions extends _RequestConfig with OptionsMixin {
method copyWith (line 169) | BaseOptions copyWith({
class Options (line 218) | class Options {
method copyWith (line 245) | Options copyWith({
method compose (line 307) | RequestOptions compose(
class RequestOptions (line 509) | class RequestOptions extends _RequestConfig with OptionsMixin {
method copyWith (line 545) | RequestOptions copyWith({
function _defaultValidateStatus (line 663) | bool _defaultValidateStatus(int? status)
class _RequestConfig (line 667) | class _RequestConfig {
type FileAccessMode (line 782) | enum FileAccessMode {
FILE: dio/lib/src/parameter.dart
class ListParam (line 7) | class ListParam<T> {
method copyWith (line 17) | ListParam<T> copyWith({List<T>? value, ListFormat? format})
method toString (line 22) | String toString()
FILE: dio/lib/src/progress_stream/io_progress_stream.dart
function addProgress (line 6) | Stream<Uint8List> addProgress(
function _transform (line 17) | StreamTransformer<S, Uint8List> _transform<S extends List<int>>(
FILE: dio/lib/src/redirect_record.dart
class RedirectRecord (line 3) | class RedirectRecord {
method toString (line 16) | String toString()
FILE: dio/lib/src/response.dart
class Response (line 12) | class Response<T> {
method toString (line 70) | String toString()
FILE: dio/lib/src/response/response_stream_handler.dart
function handleResponseStream (line 18) | Stream<Uint8List> handleResponseStream(
function stopWatchReceiveTimeout (line 37) | void stopWatchReceiveTimeout()
function watchReceiveTimeout (line 46) | void watchReceiveTimeout()
function addErrorAndClose (line 105) | void addErrorAndClose(Object error, [StackTrace? stackTrace])
FILE: dio/lib/src/transformer.dart
type JsonDecodeCallback (line 13) | typedef JsonDecodeCallback = FutureOr<dynamic> Function(String);
type JsonEncodeCallback (line 16) | typedef JsonEncodeCallback = FutureOr<String> Function(Object);
class Transformer (line 25) | abstract class Transformer {
method transformRequest (line 30) | Future<String> transformRequest(RequestOptions options)
method transformResponse (line 38) | Future transformResponse(RequestOptions options, ResponseBody response...
method urlEncodeMap (line 42) | String urlEncodeMap(
method urlEncodeQueryMap (line 59) | String urlEncodeQueryMap(
method isJsonMimeType (line 77) | bool isJsonMimeType(String? contentType)
method defaultTransformRequest (line 96) | FutureOr<String> defaultTransformRequest(
FILE: dio/lib/src/transformers/background_transformer.dart
class BackgroundTransformer (line 11) | class BackgroundTransformer extends SyncTransformer {
function _decodeJson (line 15) | FutureOr<dynamic> _decodeJson(String text)
FILE: dio/lib/src/transformers/fused_transformer.dart
class FusedTransformer (line 24) | class FusedTransformer extends Transformer {
method transformRequest (line 41) | Future<String> transformRequest(RequestOptions options)
method transformResponse (line 46) | Future<dynamic> transformResponse(
method _fastUtf8JsonDecode (line 109) | Future<Object?> _fastUtf8JsonDecode(
method _decodeUtf8ToJson (line 176) | Future<Object?> _decodeUtf8ToJson(Uint8List data)
FILE: dio/lib/src/transformers/sync_transformer.dart
type DefaultTransformer (line 10) | @Deprecated('Use BackgroundTransformer instead')
class SyncTransformer (line 16) | class SyncTransformer extends Transformer {
method transformRequest (line 26) | Future<String> transformRequest(RequestOptions options)
method transformResponse (line 31) | Future<dynamic> transformResponse(
FILE: dio/lib/src/transformers/util/consolidate_bytes.dart
function consolidateBytes (line 4) | Future<Uint8List> consolidateBytes(Stream<Uint8List> stream)
FILE: dio/lib/src/transformers/util/transform_empty_to_null.dart
class DefaultNullIfEmptyStreamTransformer (line 8) | class DefaultNullIfEmptyStreamTransformer
method bind (line 13) | Stream<Uint8List> bind(Stream<Uint8List> stream)
class _DefaultIfEmptyStreamSink (line 21) | class _DefaultIfEmptyStreamSink implements EventSink<Uint8List> {
method add (line 32) | void add(Uint8List data)
method addError (line 38) | void addError(e, [st])
method close (line 41) | void close()
FILE: dio/lib/src/utils.dart
function writeStreamToSink (line 24) | Future<void> writeStreamToSink<T>(Stream<T> stream, EventSink<T> sink)
function encodingForCharset (line 37) | Encoding encodingForCharset(String? charset, [Encoding fallback = latin1])
type DioEncodeHandler (line 45) | typedef DioEncodeHandler = String? Function(String key, Object? value);
function encodeMap (line 47) | String encodeMap(
function maybeEncode (line 64) | Object? maybeEncode(Object? value)
function urlEncode (line 71) | void urlEncode(Object? sub, String path)
function _getSeparatorChar (line 130) | String _getSeparatorChar(ListFormat collectionFormat, bool isQuery)
function caseInsensitiveKeyMap (line 145) | Map<String, V> caseInsensitiveKeyMap<V>([Map<String, V>? value])
function warningLog (line 157) | void warningLog(Object message, StackTrace stackTrace)
FILE: dio/test/adapters_test.dart
function main (line 7) | void main()
FILE: dio/test/cancel_token_test.dart
function main (line 11) | void main()
FILE: dio/test/connect_timeout_integration_test.dart
function main (line 4) | void main()
FILE: dio/test/dio_mixin_test.dart
function main (line 6) | void main()
class _TestDioMixin (line 55) | class _TestDioMixin with DioMixin implements Dio {}
class _TestDioMixinExtends (line 57) | class _TestDioMixinExtends extends DioMixin implements Dio {}
class _TestAdapter (line 59) | class _TestAdapter implements HttpClientAdapter {
method fetch (line 61) | Future<ResponseBody> fetch(
method close (line 70) | void close({bool force = false})
FILE: dio/test/encoding_test.dart
function main (line 4) | void main()
FILE: dio/test/exception_test.dart
function main (line 8) | void main()
FILE: dio/test/formdata_test.dart
function main (line 9) | void main()
FILE: dio/test/headers_test.dart
function main (line 6) | void main()
FILE: dio/test/interceptor_test.dart
class MyInterceptor (line 10) | class MyInterceptor extends Interceptor {
method onRequest (line 14) | void onRequest(RequestOptions options, RequestInterceptorHandler handler)
function main (line 20) | void main()
function createDio (line 430) | Dio createDio()
function onResult (line 683) | void onResult(d)
function onResult (line 752) | void onResult(d)
FILE: dio/test/mimetype_test.dart
function main (line 4) | void main()
FILE: dio/test/mock/adapters.dart
class MockAdapter (line 9) | class MockAdapter implements HttpClientAdapter {
method fetch (line 15) | Future<ResponseBody> fetch(
method close (line 104) | void close({bool force = false})
class EchoAdapter (line 111) | class EchoAdapter implements HttpClientAdapter {
method fetch (line 118) | Future<ResponseBody> fetch(
method close (line 136) | void close({bool force = false})
FILE: dio/test/mock/http_mock.dart
class MockHttpOverrides (line 10) | @GenerateMocks(
method createHttpClient (line 22) | HttpClient createHttpClient(SecurityContext? context)
FILE: dio/test/mock/http_mock.mocks.dart
class _FakeDuration_0 (line 24) | class _FakeDuration_0 extends _i1.Fake implements Duration {}
class _FakeHttpClientRequest_1 (line 26) | class _FakeHttpClientRequest_1 extends _i1.Fake
class _FakeUri_2 (line 29) | class _FakeUri_2 extends _i1.Fake implements Uri {}
class _FakeHttpHeaders_3 (line 31) | class _FakeHttpHeaders_3 extends _i1.Fake implements _i2.HttpHeaders {}
class _FakeHttpClientResponse_4 (line 33) | class _FakeHttpClientResponse_4 extends _i1.Fake
class _FakeEncoding_5 (line 36) | class _FakeEncoding_5 extends _i1.Fake implements _i3.Encoding {}
class _FakeSocket_6 (line 38) | class _FakeSocket_6 extends _i1.Fake implements _i2.Socket {}
class _FakeStreamSubscription_7 (line 40) | class _FakeStreamSubscription_7<T> extends _i1.Fake
class MockHttpClient (line 46) | class MockHttpClient extends _i1.Mock implements _i2.HttpClient {
method open (line 98) | _i4.Future<_i2.HttpClientRequest> open(
method openUrl (line 105) | _i4.Future<_i2.HttpClientRequest> openUrl(String? method, Uri? url)
method get (line 111) | _i4.Future<_i2.HttpClientRequest> get(
method getUrl (line 118) | _i4.Future<_i2.HttpClientRequest> getUrl(Uri? url)
method post (line 124) | _i4.Future<_i2.HttpClientRequest> post(
method postUrl (line 131) | _i4.Future<_i2.HttpClientRequest> postUrl(Uri? url)
method put (line 137) | _i4.Future<_i2.HttpClientRequest> put(
method putUrl (line 144) | _i4.Future<_i2.HttpClientRequest> putUrl(Uri? url)
method delete (line 150) | _i4.Future<_i2.HttpClientRequest> delete(
method deleteUrl (line 157) | _i4.Future<_i2.HttpClientRequest> deleteUrl(Uri? url)
method patch (line 163) | _i4.Future<_i2.HttpClientRequest> patch(
method patchUrl (line 170) | _i4.Future<_i2.HttpClientRequest> patchUrl(Uri? url)
method head (line 176) | _i4.Future<_i2.HttpClientRequest> head(
method headUrl (line 183) | _i4.Future<_i2.HttpClientRequest> headUrl(Uri? url)
method addCredentials (line 189) | void addCredentials(
method addProxyCredentials (line 195) | void addProxyCredentials(String? host, int? port, String? realm,
method close (line 202) | void close({bool? force = false})
class MockHttpClientRequest (line 210) | class MockHttpClientRequest extends _i1.Mock implements _i2.HttpClientRe...
method close (line 285) | _i4.Future<_i2.HttpClientResponse> close()
method abort (line 291) | void abort([Object? exception, StackTrace? stackTrace])
method add (line 295) | void add(List<int>? data)
method write (line 299) | void write(Object? object)
method writeAll (line 303) | void writeAll(Iterable<dynamic>? objects, [String? separator = r''])
method writeln (line 307) | void writeln([Object? object = r''])
method writeCharCode (line 311) | void writeCharCode(int? charCode)
method addError (line 315) | void addError(Object? error, [StackTrace? stackTrace])
method addStream (line 319) | _i4.Future<dynamic> addStream(_i4.Stream<List<int>>? stream)
method flush (line 323) | _i4.Future<dynamic> flush()
class MockHttpClientResponse (line 331) | class MockHttpClientResponse extends _i1.Mock
method redirect (line 398) | _i4.Future<_i2.HttpClientResponse> redirect(
method detachSocket (line 406) | _i4.Future<_i2.Socket> detachSocket()
method asBroadcastStream (line 411) | _i4.Stream<List<int>> asBroadcastStream(
method listen (line 419) | _i4.StreamSubscription<List<int>> listen(void Function(List<int>)? onD...
method where (line 432) | _i4.Stream<List<int>> where(bool Function(List<int>)? test)
method map (line 436) | _i4.Stream<S> map<S>(S Function(List<int>)? convert)
method asyncMap (line 440) | _i4.Stream<E> asyncMap<E>(_i4.FutureOr<E> Function(List<int>)? convert)
method asyncExpand (line 444) | _i4.Stream<E> asyncExpand<E>(_i4.Stream<E>? Function(List<int>)? convert)
method handleError (line 448) | _i4.Stream<List<int>> handleError(Function? onError,
method expand (line 454) | _i4.Stream<S> expand<S>(Iterable<S> Function(List<int>)? convert)
method pipe (line 458) | _i4.Future<dynamic> pipe(_i4.StreamConsumer<List<int>>? streamConsumer)
method transform (line 462) | _i4.Stream<S> transform<S>(
method reduce (line 467) | _i4.Future<List<int>> reduce(
method fold (line 473) | _i4.Future<S> fold<S>(S? initialValue, S Function(S, List<int>)? combine)
method join (line 477) | _i4.Future<String> join([String? separator = r''])
method contains (line 481) | _i4.Future<bool> contains(Object? needle)
method forEach (line 485) | _i4.Future<dynamic> forEach(void Function(List<int>)? action)
method every (line 489) | _i4.Future<bool> every(bool Function(List<int>)? test)
method any (line 493) | _i4.Future<bool> any(bool Function(List<int>)? test)
method cast (line 497) | _i4.Stream<R> cast<R>()
method toList (line 500) | _i4.Future<List<List<int>>> toList()
method toSet (line 505) | _i4.Future<Set<List<int>>> toSet()
method drain (line 510) | _i4.Future<E> drain<E>([E? futureValue])
method take (line 514) | _i4.Stream<List<int>> take(int? count)
method takeWhile (line 518) | _i4.Stream<List<int>> takeWhile(bool Function(List<int>)? test)
method skip (line 522) | _i4.Stream<List<int>> skip(int? count)
method skipWhile (line 526) | _i4.Stream<List<int>> skipWhile(bool Function(List<int>)? test)
method distinct (line 530) | _i4.Stream<List<int>> distinct(
method firstWhere (line 535) | _i4.Future<List<int>> firstWhere(bool Function(List<int>)? test,
method lastWhere (line 542) | _i4.Future<List<int>> lastWhere(bool Function(List<int>)? test,
method singleWhere (line 549) | _i4.Future<List<int>> singleWhere(bool Function(List<int>)? test,
method elementAt (line 556) | _i4.Future<List<int>> elementAt(int? index)
method timeout (line 560) | _i4.Stream<List<int>> timeout(Duration? timeLimit,
class MockHttpHeaders (line 570) | class MockHttpHeaders extends _i1.Mock implements _i2.HttpHeaders {
method value (line 626) | String? value(String? name)
method add (line 629) | void add(String? name, Object? value, {bool? preserveHeaderCase = false})
method set (line 635) | void set(String? name, Object? value, {bool? preserveHeaderCase = false})
method remove (line 641) | void remove(String? name, Object? value)
method removeAll (line 645) | void removeAll(String? name)
method forEach (line 649) | void forEach(void Function(String, List<String>)? action)
method noFolding (line 653) | void noFolding(String? name)
method clear (line 657) | void clear()
class MockTransformer (line 664) | class MockTransformer extends _i1.Mock implements _i5.Transformer {
method transformRequest (line 670) | _i4.Future<String> transformRequest(_i6.RequestOptions? options)
method transformResponse (line 674) | _i4.Future<dynamic> transformResponse(
FILE: dio/test/multipart_file_test.dart
function main (line 6) | void main()
FILE: dio/test/options_test.dart
function main (line 14) | void main()
function testInvalidArgumentException (line 398) | Future<void> testInvalidArgumentException(String method)
FILE: dio/test/options_timeout_integration_test.dart
function main (line 4) | void main()
FILE: dio/test/parameter_test.dart
function main (line 4) | void main()
FILE: dio/test/pinning_test.dart
function main (line 9) | void main()
function fingerprint (line 15) | String fingerprint()
FILE: dio/test/queued_interceptor_test.dart
function main (line 5) | void main()
class _MockAdapter (line 96) | class _MockAdapter implements HttpClientAdapter {
method fetch (line 98) | Future<ResponseBody> fetch(
method close (line 113) | void close({bool force = false})
class _FailingMockAdapter (line 116) | class _FailingMockAdapter implements HttpClientAdapter {
method fetch (line 118) | Future<ResponseBody> fetch(
method close (line 130) | void close({bool force = false})
class _QueuedInterceptorWithError (line 133) | class _QueuedInterceptorWithError extends QueuedInterceptor {
method onRequest (line 135) | void onRequest(
method onResponse (line 143) | void onResponse(
method onError (line 151) | void onError(
FILE: dio/test/response/response_stream_test.dart
function main (line 9) | void main()
FILE: dio/test/stacktrace_test.dart
function main (line 14) | void main()
FILE: dio/test/test_suite_test.dart
function main (line 4) | void main()
FILE: dio/test/timeout_test.dart
function main (line 8) | void main()
FILE: dio/test/transformer_test.dart
function main (line 8) | void main()
FILE: dio/test/utils.dart
function requiredEncodingForCharset (line 12) | Encoding requiredEncodingForCharset(String charset)
function startServer (line 20) | Future<void> startServer()
function stopServer (line 159) | void stopServer()
class ByteStream (line 179) | class ByteStream extends StreamView<List<int>> {
method toBytes (line 188) | Future<Uint8List> toBytes()
method bytesToString (line 204) | Future<String> bytesToString([Encoding encoding = utf8])
method toStringStream (line 207) | Stream<String> toStringStream([Encoding encoding = utf8])
FILE: dio_test/lib/src/matcher.dart
function throwsDioException (line 6) | Matcher throwsDioException(
function matchesDioException (line 21) | Matcher matchesDioException(
FILE: dio_test/lib/src/test/basic_tests.dart
function basicTests (line 8) | void basicTests(
FILE: dio_test/lib/src/test/cancellation_tests.dart
function cancellationTests (line 8) | void cancellationTests(
FILE: dio_test/lib/src/test/cors_tests.dart
function corsTests (line 9) | void corsTests(
FILE: dio_test/lib/src/test/download_tests.dart
function downloadTests (line 11) | void downloadTests(
FILE: dio_test/lib/src/test/headers_tests.dart
function headerTests (line 6) | void headerTests(
FILE: dio_test/lib/src/test/http_method_tests.dart
function httpMethodTests (line 6) | void httpMethodTests(
FILE: dio_test/lib/src/test/parameter_tests.dart
function parameterTests (line 6) | void parameterTests(
FILE: dio_test/lib/src/test/redirect_tests.dart
function redirectTests (line 6) | void redirectTests(
FILE: dio_test/lib/src/test/status_code_tests.dart
function statusCodeTests (line 6) | void statusCodeTests(
FILE: dio_test/lib/src/test/suite.dart
type TestSuiteFunction (line 4) | typedef TestSuiteFunction = void Function(
function dioAdapterTestSuite (line 23) | void dioAdapterTestSuite(
FILE: dio_test/lib/src/test/timeout_tests.dart
function timeoutTests (line 8) | void timeoutTests(
FILE: dio_test/lib/src/test/upload_tests.dart
function uploadTests (line 12) | void uploadTests(
class _TestTransformer (line 144) | class _TestTransformer extends BackgroundTransformer {
method transformRequest (line 148) | Future<String> transformRequest(RequestOptions options)
FILE: dio_test/lib/src/test/url_encoded_tests.dart
function urlEncodedTests (line 6) | void urlEncodedTests(
FILE: dio_test/lib/src/utils.dart
function produceGarbage (line 8) | void produceGarbage()
FILE: example_dart/lib/adapter.dart
class MyAdapter (line 6) | class MyAdapter implements HttpClientAdapter {
method fetch (line 10) | Future<ResponseBody> fetch(
method close (line 24) | void close({bool force = false})
function main (line 29) | void main()
FILE: example_dart/lib/cancel_request.dart
function main (line 5) | void main()
FILE: example_dart/lib/certificate_pinning.dart
function main (line 7) | void main()
FILE: example_dart/lib/cookie_mgr.dart
function main (line 5) | void main()
FILE: example_dart/lib/custom_cache_interceptor.dart
class CacheInterceptor (line 3) | class CacheInterceptor extends Interceptor {
method onRequest (line 9) | void onRequest(RequestOptions options, RequestInterceptorHandler handler)
method onResponse (line 22) | void onResponse(Response response, ResponseInterceptorHandler handler)
method onError (line 28) | void onError(DioException err, ErrorInterceptorHandler handler)
function main (line 34) | void main()
FILE: example_dart/lib/dio.dart
function main (line 5) | void main()
FILE: example_dart/lib/download.dart
function main (line 7) | void main()
function download1 (line 18) | Future download1(Dio dio, String url, savePath)
function download2 (line 33) | Future download2(Dio dio, String url, String savePath)
function showDownloadProgress (line 56) | void showDownloadProgress(int received, int total)
FILE: example_dart/lib/download_with_trunks.dart
function main (line 6) | void main()
function downloadWithChunks (line 23) | Future downloadWithChunks(
function createCallback (line 35) | void Function(int, int) createCallback(no)
function downloadChunk (line 44) | Future<Response> downloadChunk(url, start, end, no)
function mergeTempFiles (line 57) | Future mergeTempFiles(chunk)
FILE: example_dart/lib/extend_dio.dart
class HttpService (line 4) | class HttpService extends DioForNative {
method echo (line 11) | Future<String> echo(String data)
function main (line 16) | void main()
FILE: example_dart/lib/formdata.dart
function formData1 (line 7) | Future<FormData> formData1()
function formData2 (line 28) | Future<FormData> formData2()
function formData3 (line 74) | Future<FormData> formData3()
function main (line 85) | void main()
FILE: example_dart/lib/generic.dart
function main (line 3) | void main()
FILE: example_dart/lib/http2_adapter.dart
function main (line 4) | void main()
FILE: example_dart/lib/options.dart
function main (line 5) | void main()
FILE: example_dart/lib/post_stream_and_bytes.dart
function main (line 7) | void main()
FILE: example_dart/lib/proxy.dart
function main (line 6) | void main()
FILE: example_dart/lib/queue_interceptors.dart
function main (line 3) | void main()
function makeRequests (line 44) | Future makeRequests(Dio dio)
FILE: example_dart/lib/queued_interceptor_crsftoken.dart
function main (line 6) | void main()
type TokenHistory (line 120) | typedef TokenHistory = ({
class AuthenticationServer (line 128) | class AuthenticationServer {
method generate (line 129) | Map<String, String> generate()
method _generateUuid (line 134) | String _generateUuid()
class TokenManager (line 141) | class TokenManager {
method printHistory (line 148) | void printHistory()
method setAccessToken (line 160) | void setAccessToken(String? token, int instanceId)
FILE: example_dart/lib/request_interceptors.dart
function main (line 3) | void main()
FILE: example_dart/lib/response_interceptor.dart
function main (line 5) | void main()
FILE: example_dart/lib/test.dart
function main (line 23) | void main()
class ProblemInterceptor (line 28) | class ProblemInterceptor extends Interceptor {
method onResponse (line 30) | void onResponse(Response response, ResponseInterceptorHandler handler)
FILE: example_dart/lib/transformer.dart
class MyTransformer (line 10) | class MyTransformer extends BackgroundTransformer {
method transformRequest (line 12) | Future<String> transformRequest(RequestOptions options)
method transformResponse (line 27) | Future transformResponse(
function main (line 36) | void main()
FILE: example_flutter_app/lib/main.dart
function main (line 7) | void main()
class MyApp (line 12) | class MyApp extends StatelessWidget {
method build (line 15) | Widget build(BuildContext context)
class MyHomePage (line 26) | class MyHomePage extends StatefulWidget {
method createState (line 35) | State<MyHomePage> createState()
class _MyHomePageState (line 38) | class _MyHomePageState extends State<MyHomePage> {
method build (line 42) | Widget build(BuildContext context)
FILE: example_flutter_app/lib/routes/request.dart
class RequestRoute (line 6) | class RequestRoute extends StatefulWidget {
method createState (line 8) | State<RequestRoute> createState()
class _RequestRouteState (line 11) | class _RequestRouteState extends State<RequestRoute> {
method build (line 15) | Widget build(BuildContext context)
FILE: example_flutter_app/linux/flutter/generated_plugin_registrant.cc
function fl_register_plugins (line 10) | void fl_register_plugins(FlPluginRegistry* registry) {
FILE: example_flutter_app/linux/runner/main.cc
function main (line 3) | int main(int argc, char** argv) {
FILE: example_flutter_app/linux/runner/my_application.cc
type _MyApplication (line 10) | struct _MyApplication {
function my_application_activate (line 18) | static void my_application_activate(GApplication* application) {
function gboolean (line 66) | static gboolean my_application_local_command_line(GApplication* applicat...
function my_application_startup (line 85) | static void my_application_startup(GApplication* application) {
function my_application_shutdown (line 94) | static void my_application_shutdown(GApplication* application) {
function my_application_dispose (line 103) | static void my_application_dispose(GObject* object) {
function my_application_class_init (line 109) | static void my_application_class_init(MyApplicationClass* klass) {
function my_application_init (line 117) | static void my_application_init(MyApplication* self) {}
function MyApplication (line 119) | MyApplication* my_application_new() {
FILE: example_flutter_app/windows/flutter/generated_plugin_registrant.cc
function RegisterPlugins (line 10) | void RegisterPlugins(flutter::PluginRegistry* registry) {
FILE: example_flutter_app/windows/runner/flutter_window.cpp
function LRESULT (line 50) | LRESULT
FILE: example_flutter_app/windows/runner/flutter_window.h
function class (line 12) | class FlutterWindow : public Win32Window {
FILE: example_flutter_app/windows/runner/main.cpp
function wWinMain (line 8) | int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev,
FILE: example_flutter_app/windows/runner/utils.cpp
function CreateAndAttachConsole (line 10) | void CreateAndAttachConsole() {
function GetCommandLineArguments (line 24) | std::vector<std::string> GetCommandLineArguments() {
function Utf8FromUtf16 (line 44) | std::string Utf8FromUtf16(const wchar_t* utf16_string) {
FILE: example_flutter_app/windows/runner/win32_window.cpp
function Scale (line 36) | int Scale(int source, double scale_factor) {
function EnableFullDpiSupportIfAvailable (line 42) | void EnableFullDpiSupportIfAvailable(HWND hwnd) {
class WindowClassRegistrar (line 59) | class WindowClassRegistrar {
method WindowClassRegistrar (line 64) | static WindowClassRegistrar* GetInstance() {
method WindowClassRegistrar (line 80) | WindowClassRegistrar() = default;
function wchar_t (line 89) | const wchar_t* WindowClassRegistrar::GetWindowClass() {
function LRESULT (line 157) | LRESULT CALLBACK Win32Window::WndProc(HWND const window,
function LRESULT (line 176) | LRESULT
function Win32Window (line 236) | Win32Window* Win32Window::GetThisFromHandle(HWND const window) noexcept {
function RECT (line 252) | RECT Win32Window::GetClientArea() {
function HWND (line 258) | HWND Win32Window::GetHandle() {
FILE: example_flutter_app/windows/runner/win32_window.h
type Size (line 21) | struct Size {
FILE: plugins/compatibility_layer/example/conversion_layer_example.dart
function main (line 5) | void main()
FILE: plugins/compatibility_layer/lib/src/conversion_layer_adapter.dart
class ConversionLayerAdapter (line 18) | class ConversionLayerAdapter implements HttpClientAdapter {
method fetch (line 25) | Future<ResponseBody> fetch(
method close (line 44) | void close({bool force = false})
method _fromOptionsAndStream (line 46) | Future<http.BaseRequest> _fromOptionsAndStream(
FILE: plugins/compatibility_layer/test/client_mock.dart
class CloseClientMock (line 3) | class CloseClientMock implements Client {
method close (line 7) | void close()
method noSuchMethod (line 12) | dynamic noSuchMethod(Invocation i)
class ClientMock (line 15) | class ClientMock implements Client {
method send (line 20) | Future<StreamedResponse> send(BaseRequest request)
method noSuchMethod (line 26) | dynamic noSuchMethod(Invocation i)
FILE: plugins/compatibility_layer/test/conversion_layer_adapter_test.dart
function main (line 10) | void main()
FILE: plugins/cookie_manager/example/example.dart
function main (line 5) | void main()
FILE: plugins/cookie_manager/lib/src/cookie_mgr.dart
class CookieManager (line 25) | class CookieManager extends Interceptor {
method getCookies (line 43) | String getCookies(List<Cookie> cookies)
method onRequest (line 60) | Future<void> onRequest(
method onResponse (line 81) | Future<void> onResponse(
method onError (line 106) | Future<void> onError(
method _fromSetCookieValue (line 136) | Cookie? _fromSetCookieValue(String value)
method loadCookies (line 148) | Future<String> loadCookies(RequestOptions options)
method saveCookies (line 164) | Future<void> saveCookies(Response response)
FILE: plugins/cookie_manager/lib/src/exception.dart
class CookieManagerLoadException (line 4) | class CookieManagerLoadException implements Exception {
method toString (line 14) | String toString()
class CookieManagerSaveException (line 18) | class CookieManagerSaveException implements Exception {
method toString (line 32) | String toString()
FILE: plugins/cookie_manager/test/basic_test.dart
function main (line 7) | void main()
FILE: plugins/cookie_manager/test/cookies_persistance_test.dart
type _FetchCallback (line 14) | typedef _FetchCallback = Future<ResponseBody> Function(
class _TestAdapter (line 20) | class _TestAdapter implements HttpClientAdapter {
method fetch (line 27) | Future<ResponseBody> fetch(
method close (line 35) | void close({bool force = false})
class _SaveCall (line 40) | class _SaveCall {
method toString (line 58) | String toString()
class _FakeCookieJar (line 63) | class _FakeCookieJar extends Fake implements CookieJar {
method loadForRequest (line 69) | Future<List<Cookie>> loadForRequest(Uri uri)
method saveFromResponse (line 74) | Future<void> saveFromResponse(Uri uri, List<Cookie> cookies)
function main (line 84) | void main()
FILE: plugins/cookie_manager/test/cookies_test.dart
class MockRequestInterceptorHandler (line 11) | class MockRequestInterceptorHandler extends RequestInterceptorHandler {
method next (line 17) | void next(RequestOptions requestOptions)
class MockResponseInterceptorHandler (line 24) | class MockResponseInterceptorHandler extends ResponseInterceptorHandler {}
class _MockRejectRequestInterceptorHandler (line 26) | class _MockRejectRequestInterceptorHandler extends RequestInterceptorHan...
method reject (line 32) | void reject(
class _MockRejectResponseInterceptorHandler (line 40) | class _MockRejectResponseInterceptorHandler extends ResponseInterceptorH...
method reject (line 46) | void reject(
class _MockRejectErrorInterceptorHandler (line 54) | class _MockRejectErrorInterceptorHandler extends ErrorInterceptorHandler {
method next (line 60) | void next(DioException error)
class _MockNextErrorInterceptorHandler (line 65) | class _MockNextErrorInterceptorHandler extends ErrorInterceptorHandler {
method next (line 71) | void next(DioException error)
class _OverrideCookieManager (line 76) | class _OverrideCookieManager extends CookieManager {
method loadCookies (line 80) | Future<String> loadCookies(RequestOptions options)
method saveCookies (line 86) | Future<void> saveCookies(Response response)
function main (line 92) | void main()
class _RedirectAdapter (line 430) | class _RedirectAdapter implements HttpClientAdapter {
method fetch (line 440) | Future<ResponseBody> fetch(
method close (line 492) | void close({bool force = false})
FILE: plugins/http2_adapter/example/example.dart
function main (line 4) | void main()
FILE: plugins/http2_adapter/lib/src/client_setting.dart
type ValidateCertificate (line 3) | typedef ValidateCertificate = bool Function(
class ClientSetting (line 9) | class ClientSetting {
FILE: plugins/http2_adapter/lib/src/connection_manager.dart
class ConnectionManager (line 7) | abstract class ConnectionManager {
method getConnection (line 23) | Future<ClientTransportConnection> getConnection(
method removeConnection (line 28) | void removeConnection(ClientTransportConnection transport)
method close (line 30) | void close({bool force = false})
type ProxyConnectedPredicate (line 43) | typedef ProxyConnectedPredicate = bool Function(String protocol, String ...
function defaultProxyConnectedPredicate (line 46) | bool defaultProxyConnectedPredicate(String protocol, String status)
FILE: plugins/http2_adapter/lib/src/connection_manager_imp.dart
class _ConnectionManager (line 4) | class _ConnectionManager implements ConnectionManager {
method _getCacheKey (line 51) | String _getCacheKey(Uri uri)
method getConnection (line 54) | Future<ClientTransportConnection> getConnection(
method _connect (line 102) | Future<_ClientTransportConnectionState> _connect(
method _createSocket (line 172) | Future<Socket> _createSocket(
method onProxyError (line 231) | Never onProxyError(Object? error, StackTrace stackTrace)
method removeConnection (line 283) | void removeConnection(ClientTransportConnection transport)
method close (line 296) | void close({bool force = false})
method _throwIfH2NotSelected (line 304) | void _throwIfH2NotSelected(Uri target, SecureSocket socket)
class _ClientTransportConnectionState (line 311) | class _ClientTransportConnectionState {
method delayClose (line 326) | void delayClose(Duration idleTimeout, void Function() callback)
method dispose (line 332) | void dispose()
method _startTimer (line 337) | void _startTimer(
FILE: plugins/http2_adapter/lib/src/http2_adapter.dart
type H2NotSupportedCallback (line 18) | typedef H2NotSupportedCallback = Future<ResponseBody> Function(
class Http2Adapter (line 26) | class Http2Adapter implements HttpClientAdapter {
method fetch (line 44) | Future<ResponseBody> fetch(
method _fetch (line 54) | Future<ResponseBody> _fetch(
method _needRedirect (line 283) | bool _needRedirect(RequestOptions options, int status)
method resolveRedirectUri (line 290) | Uri resolveRedirectUri(Uri currentUri, Uri redirectUri)
method close (line 302) | void close({bool force = false})
class DioH2NotSupportedException (line 308) | class DioH2NotSupportedException extends SocketException {
method toString (line 318) | String toString()
FILE: plugins/http2_adapter/test/http2_test.dart
function main (line 8) | void main()
FILE: plugins/http2_adapter/test/pinning_test.dart
function main (line 8) | void main()
function fingerprint (line 11) | String fingerprint()
FILE: plugins/http2_adapter/test/redirect_test.dart
function main (line 4) | void main()
FILE: plugins/http2_adapter/test/test_suite_test.dart
function main (line 5) | void main()
FILE: plugins/native_dio_adapter/example/lib/main.dart
function main (line 9) | void main()
class MyApp (line 13) | class MyApp extends StatelessWidget {
method build (line 17) | Widget build(BuildContext context)
class MyHomePage (line 28) | class MyHomePage extends StatefulWidget {
method createState (line 34) | State<MyHomePage> createState()
class _MyHomePageState (line 37) | class _MyHomePageState extends State<MyHomePage> {
method build (line 39) | Widget build(BuildContext context)
method _doGetRequest (line 69) | void _doGetRequest()
method _doPostRequest (line 100) | void _doPostRequest()
method _doHttpClientRequest (line 136) | void _doHttpClientRequest()
method _doHttpClientPostRequest (line 162) | void _doHttpClientPostRequest()
FILE: plugins/native_dio_adapter/example/linux/flutter/generated_plugin_registrant.cc
function fl_register_plugins (line 10) | void fl_register_plugins(FlPluginRegistry* registry) {
FILE: plugins/native_dio_adapter/example/linux/main.cc
function main (line 3) | int main(int argc, char** argv) {
FILE: plugins/native_dio_adapter/example/linux/my_application.cc
type _MyApplication (line 10) | struct _MyApplication {
function my_application_activate (line 18) | static void my_application_activate(GApplication* application) {
function gboolean (line 66) | static gboolean my_application_local_command_line(GApplication* applicat...
function my_application_dispose (line 85) | static void my_application_dispose(GObject* object) {
function my_application_class_init (line 91) | static void my_application_class_init(MyApplicationClass* klass) {
function my_application_init (line 97) | static void my_application_init(MyApplication* self) {}
function MyApplication (line 99) | MyApplication* my_application_new() {
FILE: plugins/native_dio_adapter/example/windows/flutter/generated_plugin_registrant.cc
function RegisterPlugins (line 10) | void RegisterPlugins(flutter::PluginRegistry* registry) {
FILE: plugins/native_dio_adapter/example/windows/runner/flutter_window.cpp
function LRESULT (line 40) | LRESULT
FILE: plugins/native_dio_adapter/example/windows/runner/flutter_window.h
function class (line 12) | class FlutterWindow : public Win32Window {
FILE: plugins/native_dio_adapter/example/windows/runner/main.cpp
function wWinMain (line 8) | int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev,
FILE: plugins/native_dio_adapter/example/windows/runner/utils.cpp
function CreateAndAttachConsole (line 10) | void CreateAndAttachConsole() {
function GetCommandLineArguments (line 24) | std::vector<std::string> GetCommandLineArguments() {
function Utf8FromUtf16 (line 44) | std::string Utf8FromUtf16(const wchar_t* utf16_string) {
FILE: plugins/native_dio_adapter/example/windows/runner/win32_window.cpp
function Scale (line 18) | int Scale(int source, double scale_factor) {
function EnableFullDpiSupportIfAvailable (line 24) | void EnableFullDpiSupportIfAvailable(HWND hwnd) {
class WindowClassRegistrar (line 41) | class WindowClassRegistrar {
method WindowClassRegistrar (line 46) | static WindowClassRegistrar* GetInstance() {
method WindowClassRegistrar (line 62) | WindowClassRegistrar() = default;
function wchar_t (line 71) | const wchar_t* WindowClassRegistrar::GetWindowClass() {
function LRESULT (line 133) | LRESULT CALLBACK Win32Window::WndProc(HWND const window,
function LRESULT (line 152) | LRESULT
function Win32Window (line 208) | Win32Window* Win32Window::GetThisFromHandle(HWND const window) noexcept {
function RECT (line 224) | RECT Win32Window::GetClientArea() {
function HWND (line 230) | HWND Win32Window::GetHandle() {
FILE: plugins/native_dio_adapter/example/windows/runner/win32_window.h
type Size (line 21) | struct Size {
FILE: plugins/native_dio_adapter/lib/src/conversion_layer_adapter.dart
class ConversionLayerAdapter (line 14) | class ConversionLayerAdapter implements HttpClientAdapter {
method fetch (line 21) | Future<ResponseBody> fetch(
method close (line 79) | void close({bool force = false})
method _fromOptionsAndStream (line 81) | Future<BaseRequest> _fromOptionsAndStream(
function toDioResponseBody (line 127) | ResponseBody toDioResponseBody(RequestOptions options)
FILE: plugins/native_dio_adapter/lib/src/cronet_adapter.dart
class CronetAdapter (line 10) | class CronetAdapter implements HttpClientAdapter {
method close (line 26) | void close({bool force = false})
method fetch (line 29) | Future<ResponseBody> fetch(
FILE: plugins/native_dio_adapter/lib/src/cupertino_adapter.dart
class CupertinoAdapter (line 10) | class CupertinoAdapter implements HttpClientAdapter {
method close (line 23) | void close({bool force = false})
method fetch (line 26) | Future<ResponseBody> fetch(
FILE: plugins/native_dio_adapter/lib/src/native_adapter.dart
class NativeAdapter (line 19) | class NativeAdapter implements HttpClientAdapter {
method close (line 57) | void close({bool force = false})
method fetch (line 60) | Future<ResponseBody> fetch(
FILE: plugins/native_dio_adapter/test/client_mock.dart
class CloseClientMock (line 4) | class CloseClientMock implements Client {
method close (line 8) | void close()
method noSuchMethod (line 13) | void noSuchMethod(Invocation invocation)
class ClientMock (line 18) | class ClientMock implements Client {
method send (line 24) | Future<StreamedResponse> send(BaseRequest request)
method noSuchMethod (line 30) | void noSuchMethod(Invocation invocation)
class AbortClientMock (line 35) | class AbortClientMock implements Client {
method send (line 39) | Future<StreamedResponse> send(BaseRequest request)
method noSuchMethod (line 63) | void noSuchMethod(Invocation invocation)
class AbortedError (line 68) | class AbortedError extends Error {}
class DelayedClientMock (line 70) | class DelayedClientMock implements Client {
method send (line 78) | Future<StreamedResponse> send(BaseRequest request)
method noSuchMethod (line 88) | void noSuchMethod(Invocation invocation)
FILE: plugins/native_dio_adapter/test/conversion_layer_adapter_test.dart
function main (line 10) | void main()
FILE: plugins/web_adapter/example/main.dart
function main (line 4) | void main()
FILE: plugins/web_adapter/lib/src/adapter_impl.dart
function createAdapter (line 11) | BrowserHttpClientAdapter createAdapter()
class BrowserHttpClientAdapter (line 14) | class BrowserHttpClientAdapter implements HttpClientAdapter {
method fetch (line 31) | Future<ResponseBody> fetch(
method stopWatchReceiveTimeout (line 173) | void stopWatchReceiveTimeout()
method watchReceiveTimeout (line 179) | void watchReceiveTimeout()
method close (line 309) | void close({bool force = false})
function getResponseHeaders (line 320) | Map<String, List<String>> getResponseHeaders()
FILE: plugins/web_adapter/lib/src/compute_impl.dart
function compute (line 25) | Future<R> compute<Q, R>(
FILE: plugins/web_adapter/lib/src/dio_impl.dart
function createDio (line 6) | Dio createDio([BaseOptions? options])
class DioForBrowser (line 9) | class DioForBrowser with DioMixin implements Dio {
method download (line 18) | Future<Response> download(
FILE: plugins/web_adapter/lib/src/multipart_file_impl.dart
function multipartFileFromPath (line 7) | Never multipartFileFromPath(
function multipartFileFromPathSync (line 15) | Never multipartFileFromPathSync(
FILE: plugins/web_adapter/lib/src/progress_stream_impl.dart
function addProgress (line 6) | Stream<Uint8List> addProgress(
function _transform (line 18) | StreamTransformer<S, Uint8List> _transform<S extends List<int>>(
FILE: plugins/web_adapter/test/browser_test.dart
function main (line 8) | void main()
FILE: scripts/melos_packages.dart
function main (line 20) | void main()
function toPlainObject (line 83) | Object? toPlainObject()
Condensed preview — 423 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,128K chars).
[
{
"path": ".github/FUNDING.yml",
"chars": 30,
"preview": "github: [AlexV525, kuhnroyal]\n"
},
{
"path": ".github/ISSUE_TEMPLATE/bug.yml",
"chars": 3034,
"preview": "name: 🐞 Bug Report\ndescription: Tell us about something that's not working the way we (probably) intend.\nlabels: [\"s: bu"
},
{
"path": ".github/ISSUE_TEMPLATE/config.yaml",
"chars": 26,
"preview": "blank_issues_enabled: true"
},
{
"path": ".github/ISSUE_TEMPLATE/feature.yml",
"chars": 510,
"preview": "name: 💡 Feature Request\ndescription: Tell us about a problem dio could solve but doesn't.\nlabels: [\"s: feature\"]\nbody:\n "
},
{
"path": ".github/ISSUE_TEMPLATE/infra.yml",
"chars": 229,
"preview": "name: 👷 Infra\ndescription: Something is wrong with the CI setup or could be improved\nlabels: [\"infra\"]\nbody:\n - type: t"
},
{
"path": ".github/PULL_REQUEST_TEMPLATE.md",
"chars": 735,
"preview": "<!-- Write down your pull request descriptions. -->\n\n### New Pull Request Checklist\n\n- [ ] I have read the [Documentatio"
},
{
"path": ".github/dependabot.yaml",
"chars": 171,
"preview": "version: 2\nupdates:\n - package-ecosystem: \"github-actions\"\n directory: \"/\"\n schedule:\n interval: \"weekly\"\n "
},
{
"path": ".github/workflows/check_issues_access.yml",
"chars": 1440,
"preview": "# Not allow users without write access to create \"infra\" or blank issues.\nname: Check issues access\n\non:\n issues:\n t"
},
{
"path": ".github/workflows/coverage_base.yml",
"chars": 3002,
"preview": "name: 'coverage_baseline'\n\n# The code-coverage-report-action uses workflow artifacts to store the coverage report.\n# The"
},
{
"path": ".github/workflows/coverage_comment.yml",
"chars": 1231,
"preview": "name: 'coverage_comment'\n\n# This workflow runs after the 'Verify packages abilities' workflow is completed for a pull re"
},
{
"path": ".github/workflows/publish.yml",
"chars": 528,
"preview": "name: Publish from comments\n\non:\n issue_comment:\n types: [created]\n\njobs:\n publish:\n # https://github.com/cfug/d"
},
{
"path": ".github/workflows/tests.yml",
"chars": 4567,
"preview": "name: Verify packages abilities\n\non:\n push:\n branches:\n - main\n - '6.0.0'\n paths-ignore:\n - \"**.md"
},
{
"path": ".gitignore",
"chars": 492,
"preview": "# Files and directories created by pub\n.packages\n.dart_tool/\n.pub/\n.example/flutter.png\nbuild/\n# Remove the following pa"
},
{
"path": ".idea/modules.xml",
"chars": 1814,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n <component name=\"ProjectModuleManager\">\n <modules>\n "
},
{
"path": "CODEOWNERS",
"chars": 17,
"preview": "* @cfug/dio-core\n"
},
{
"path": "CODE_OF_CONDUCT.md",
"chars": 5256,
"preview": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nWe as members, contributors, and leaders pledge to participate in"
},
{
"path": "COMPATIBILITY_POLICY.md",
"chars": 920,
"preview": "# Compatibility Policy\n\nAs an open-source project, all activities happened when the maintainers have spare time and ener"
},
{
"path": "CONTRIBUTING-ZH.md",
"chars": 1607,
"preview": "# 贡献指南\n\nLanguage: [English](CONTRIBUTING.md) | 简体中文\n\n首先,感谢您考虑为 `dio` 项目做出贡献!像这样的开源项目得以成长和繁荣,多亏了像您这样的贡献者。无论您是在修复错误、添加新功能、"
},
{
"path": "CONTRIBUTING.md",
"chars": 3732,
"preview": "# Contributing Guidelines\n\nLanguage: English | [简体中文](CONTRIBUTING-ZH.md)\n\nFirst of all, thank you for considering contr"
},
{
"path": "LICENSE",
"chars": 1104,
"preview": "MIT License\n\nCopyright (c) 2018 Wen Du (wendux)\nCopyright (c) 2022 The CFUG Team\n\nPermission is hereby granted, free of "
},
{
"path": "README-ZH.md",
"chars": 1897,
"preview": "# dio\n\nLanguage: [English](README.md) | 简体中文\n\n此处是 **dio** 项目的基础仓库。请前往项目各自的路径查看指引。\n\n> 别忘了为你发布的与 dio 相关的 package 添加\n> [#di"
},
{
"path": "README.md",
"chars": 2750,
"preview": "# dio\n\nLanguage: English | [简体中文](README-ZH.md)\n\nThis is the base repo of the **dio** project.\nPlease move specific path"
},
{
"path": "SECURITY.md",
"chars": 236,
"preview": "# Security Policy\n\n## Supported Versions\n\n| Version | Supported |\n|---------|-----------|\n| >=5.0 | ✅ |\n| < 5."
},
{
"path": "analysis_options.yaml",
"chars": 1304,
"preview": "include: package:lints/recommended.yaml\n\nanalyzer:\n errors:\n always_declare_return_types: error\n always_put_contr"
},
{
"path": "dio/.gitignore",
"chars": 575,
"preview": "# Miscellaneous\n*.class\n*.log\n*.pyc\n*.swp\n.DS_Store\n.atom/\n.buildlog/\n.history\n.svn/\n\n# IntelliJ related\n*.ipr\n*.iws\n.id"
},
{
"path": "dio/CHANGELOG.md",
"chars": 13730,
"preview": "# CHANGELOG\n\n**Before you upgrade: Breaking changes might happen in major and minor versions of packages.<br/>\nSee the ["
},
{
"path": "dio/LICENSE",
"chars": 1104,
"preview": "MIT License\n\nCopyright (c) 2018 Wen Du (wendux)\nCopyright (c) 2022 The CFUG Team\n\nPermission is hereby granted, free of "
},
{
"path": "dio/README-ZH.md",
"chars": 25690,
"preview": "# dio\n\n[](https://pub.flutter-io.cn/packages/dio)\n[](https://pub.dev/packages/dio)\n[ asy"
},
{
"path": "dio/lib/browser.dart",
"chars": 132,
"preview": "export 'src/adapters/browser_adapter.dart' show BrowserHttpClientAdapter;\nexport 'src/dio/dio_for_browser.dart' show Dio"
},
{
"path": "dio/lib/dio.dart",
"chars": 759,
"preview": "/// A powerful HTTP client for Dart and Flutter, which supports global settings,\n/// [Interceptors], [FormData], abortin"
},
{
"path": "dio/lib/fix_data/fix.yaml",
"chars": 2236,
"preview": "version: 1\n\ntransforms:\n # Changes made in https://github.com/cfug/diox/pull/14\n - title: \"Migrate to 'IOHttpClientAda"
},
{
"path": "dio/lib/io.dart",
"chars": 114,
"preview": "export 'src/adapters/io_adapter.dart' hide createAdapter;\nexport 'src/dio/dio_for_native.dart' show DioForNative;\n"
},
{
"path": "dio/lib/src/adapter.dart",
"chars": 4338,
"preview": "import 'dart:convert';\nimport 'dart:typed_data';\n\nimport 'package:meta/meta.dart';\n\nimport 'adapters/io_adapter.dart'\n "
},
{
"path": "dio/lib/src/adapters/browser_adapter.dart",
"chars": 104,
"preview": "export 'package:dio_web_adapter/dio_web_adapter.dart'\n show createAdapter, BrowserHttpClientAdapter;\n"
},
{
"path": "dio/lib/src/adapters/io_adapter.dart",
"chars": 8103,
"preview": "import 'dart:async';\nimport 'dart:io';\nimport 'dart:typed_data';\n\nimport '../adapter.dart';\nimport '../dio_exception.dar"
},
{
"path": "dio/lib/src/cancel_token.dart",
"chars": 2074,
"preview": "import 'dart:async';\n\nimport 'dio_exception.dart';\nimport 'options.dart';\nimport 'utils.dart' show warningLog;\n\n/// {@te"
},
{
"path": "dio/lib/src/compute/compute.dart",
"chars": 5454,
"preview": "// Copyright 2014 The Flutter Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style licens"
},
{
"path": "dio/lib/src/compute/compute_io.dart",
"chars": 5142,
"preview": "// Copyright 2014 The Flutter Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style licens"
},
{
"path": "dio/lib/src/compute/compute_web.dart",
"chars": 68,
"preview": "export 'package:dio_web_adapter/dio_web_adapter.dart' show compute;\n"
},
{
"path": "dio/lib/src/dio/dio_for_browser.dart",
"chars": 89,
"preview": "export 'package:dio_web_adapter/dio_web_adapter.dart'\n show createDio, DioForBrowser;\n"
},
{
"path": "dio/lib/src/dio/dio_for_native.dart",
"chars": 6396,
"preview": "import 'dart:async';\nimport 'dart:io';\n\nimport '../adapter.dart';\nimport '../adapters/io_adapter.dart';\nimport '../cance"
},
{
"path": "dio/lib/src/dio.dart",
"chars": 9426,
"preview": "import 'dart:async';\n\nimport 'adapter.dart';\nimport 'cancel_token.dart';\nimport 'dio/dio_for_native.dart'\n if (dart.l"
},
{
"path": "dio/lib/src/dio_exception.dart",
"chars": 10416,
"preview": "import 'options.dart';\nimport 'response.dart';\nimport 'utils.dart' show warningLog;\n\n/// Deprecated in favor of [DioExce"
},
{
"path": "dio/lib/src/dio_mixin.dart",
"chars": 23395,
"preview": "import 'dart:async';\nimport 'dart:collection';\nimport 'dart:convert';\nimport 'dart:math' as math;\nimport 'dart:typed_dat"
},
{
"path": "dio/lib/src/form_data.dart",
"chars": 6810,
"preview": "import 'dart:async';\nimport 'dart:convert';\nimport 'dart:math' as math;\nimport 'dart:typed_data' show Uint8List;\n\nimport"
},
{
"path": "dio/lib/src/headers.dart",
"chars": 3764,
"preview": "import 'package:http_parser/http_parser.dart';\n\nimport 'utils.dart';\n\n/// The signature that iterates header fields.\ntyp"
},
{
"path": "dio/lib/src/interceptor.dart",
"chars": 13839,
"preview": "part of 'dio_mixin.dart';\n\n/// The result type after handled by the interceptor.\nenum InterceptorResultType {\n next,\n "
},
{
"path": "dio/lib/src/interceptors/imply_content_type.dart",
"chars": 1334,
"preview": "import '../dio_mixin.dart';\nimport '../form_data.dart';\nimport '../headers.dart';\nimport '../options.dart';\nimport '../u"
},
{
"path": "dio/lib/src/interceptors/log.dart",
"chars": 4595,
"preview": "import '../dio_exception.dart';\nimport '../dio_mixin.dart';\nimport '../options.dart';\nimport '../response.dart';\n\n/// [L"
},
{
"path": "dio/lib/src/multipart_file/browser_multipart_file.dart",
"chars": 113,
"preview": "export 'package:dio_web_adapter/dio_web_adapter.dart'\n show multipartFileFromPath, multipartFileFromPathSync;\n"
},
{
"path": "dio/lib/src/multipart_file/io_multipart_file.dart",
"chars": 1135,
"preview": "import 'dart:async';\nimport 'dart:io';\n\nimport 'package:path/path.dart' as p;\n\nimport '../multipart_file.dart' show Mult"
},
{
"path": "dio/lib/src/multipart_file.dart",
"chars": 6817,
"preview": "import 'dart:convert' show utf8;\nimport 'dart:typed_data' show Uint8List;\n\nimport 'package:http_parser/http_parser.dart'"
},
{
"path": "dio/lib/src/options.dart",
"chars": 26050,
"preview": "import 'dart:async';\n\nimport 'package:meta/meta.dart';\n\nimport 'adapter.dart';\nimport 'cancel_token.dart';\nimport 'heade"
},
{
"path": "dio/lib/src/parameter.dart",
"chars": 1040,
"preview": "import 'package:collection/collection.dart';\n\nimport 'options.dart';\n\n/// Indicates a param being used as queries or for"
},
{
"path": "dio/lib/src/progress_stream/browser_progress_stream.dart",
"chars": 72,
"preview": "export 'package:dio_web_adapter/dio_web_adapter.dart' show addProgress;\n"
},
{
"path": "dio/lib/src/progress_stream/io_progress_stream.dart",
"chars": 1237,
"preview": "import 'dart:async';\nimport 'dart:typed_data';\n\nimport '../options.dart';\n\nStream<Uint8List> addProgress(\n Stream<List<"
},
{
"path": "dio/lib/src/redirect_record.dart",
"chars": 582,
"preview": "/// A record that records the redirection happens during requests,\n/// including status code, request method, and the lo"
},
{
"path": "dio/lib/src/response/response_stream_handler.dart",
"chars": 3102,
"preview": "import 'dart:async';\nimport 'dart:typed_data';\n\nimport 'package:meta/meta.dart';\n\nimport '../adapter.dart';\nimport '../d"
},
{
"path": "dio/lib/src/response.dart",
"chars": 2263,
"preview": "import 'dart:convert';\n\nimport 'headers.dart';\nimport 'options.dart';\nimport 'redirect_record.dart';\n\n/// The [Response]"
},
{
"path": "dio/lib/src/transformer.dart",
"chars": 3936,
"preview": "import 'dart:async';\nimport 'package:http_parser/http_parser.dart';\n\nimport 'adapter.dart';\nimport 'options.dart';\nimpor"
},
{
"path": "dio/lib/src/transformers/background_transformer.dart",
"chars": 926,
"preview": "import 'dart:async';\nimport 'dart:convert';\n\nimport '../compute/compute.dart';\nimport '../transformers/sync_transformer."
},
{
"path": "dio/lib/src/transformers/fused_transformer.dart",
"chars": 6710,
"preview": "import 'dart:async';\nimport 'dart:convert';\nimport 'dart:typed_data';\n\nimport '../adapter.dart';\nimport '../compute/comp"
},
{
"path": "dio/lib/src/transformers/sync_transformer.dart",
"chars": 2248,
"preview": "import 'dart:async';\nimport 'dart:convert';\n\nimport '../adapter.dart';\nimport '../headers.dart';\nimport '../options.dart"
},
{
"path": "dio/lib/src/transformers/util/consolidate_bytes.dart",
"chars": 308,
"preview": "import 'dart:typed_data';\n\n/// Consolidates a stream of [Uint8List] into a single [Uint8List]\nFuture<Uint8List> consolid"
},
{
"path": "dio/lib/src/transformers/util/transform_empty_to_null.dart",
"chars": 1314,
"preview": "import 'dart:async';\nimport 'dart:typed_data';\n\n/// A [StreamTransformer] that replaces an empty stream of Uint8List wit"
},
{
"path": "dio/lib/src/utils.dart",
"chars": 5167,
"preview": "import 'dart:async';\nimport 'dart:collection';\nimport 'dart:convert';\nimport 'dart:developer' as dev;\n\nimport 'options.d"
},
{
"path": "dio/pubspec.yaml",
"chars": 822,
"preview": "name: dio\nversion: 5.9.2\n\ndescription: |\n A powerful HTTP networking package,\n supports Interceptors,\n Aborting and c"
},
{
"path": "dio/test/adapters_test.dart",
"chars": 1545,
"preview": "import 'dart:io';\n\nimport 'package:dio/dio.dart';\nimport 'package:dio/io.dart';\nimport 'package:test/test.dart';\n\nvoid m"
},
{
"path": "dio/test/cancel_token_test.dart",
"chars": 5512,
"preview": "import 'dart:typed_data' show Uint8List;\n\nimport 'package:dio/dio.dart';\nimport 'package:dio/src/adapters/io_adapter.dar"
},
{
"path": "dio/test/connect_timeout_integration_test.dart",
"chars": 1151,
"preview": "import 'package:dio/dio.dart';\nimport 'package:test/test.dart';\n\nvoid main() {\n test('connectTimeout can be set through"
},
{
"path": "dio/test/dio_mixin_test.dart",
"chars": 2163,
"preview": "import 'dart:typed_data';\n\nimport 'package:dio/dio.dart';\nimport 'package:test/test.dart';\n\nvoid main() {\n test('not th"
},
{
"path": "dio/test/encoding_test.dart",
"chars": 5070,
"preview": "import 'package:dio/dio.dart';\nimport 'package:test/test.dart';\n\nvoid main() {\n group(Transformer.urlEncodeMap, () {\n "
},
{
"path": "dio/test/exception_test.dart",
"chars": 2549,
"preview": "@TestOn('vm')\nimport 'dart:io';\n\nimport 'package:dio/dio.dart';\nimport 'package:dio/io.dart';\nimport 'package:test/test."
},
{
"path": "dio/test/formdata_test.dart",
"chars": 9897,
"preview": "import 'dart:convert';\nimport 'dart:io';\n\nimport 'package:dio/dio.dart';\nimport 'package:test/test.dart';\n\nimport 'mock/"
},
{
"path": "dio/test/headers_test.dart",
"chars": 1800,
"preview": "import 'dart:async';\n\nimport 'package:dio/dio.dart';\nimport 'package:test/test.dart';\n\nvoid main() {\n group(Headers, ()"
},
{
"path": "dio/test/interceptor_test.dart",
"chars": 31825,
"preview": "import 'dart:async';\n\nimport 'package:dio/dio.dart';\nimport 'package:dio/src/dio_mixin.dart';\nimport 'package:dio/src/in"
},
{
"path": "dio/test/mimetype_test.dart",
"chars": 438,
"preview": "import 'package:dio/dio.dart';\nimport 'package:test/test.dart';\n\nvoid main() {\n test('application/json', () {\n expec"
},
{
"path": "dio/test/mock/_formdata",
"chars": 835,
"preview": "----dio-boundary-3788753558\ncontent-disposition: form-data; name=\"name\"\n\nwendux\n----dio-boundary-3788753558\ncontent-disp"
},
{
"path": "dio/test/mock/_testfile",
"chars": 19,
"preview": "你好世界,\n我很好人类\n哈哈哈哈哈😆\n"
},
{
"path": "dio/test/mock/adapters.dart",
"chars": 4122,
"preview": "import 'dart:async';\nimport 'dart:convert';\nimport 'dart:io';\nimport 'dart:typed_data';\n\nimport 'package:dio/dio.dart';\n"
},
{
"path": "dio/test/mock/http_mock.dart",
"chars": 522,
"preview": "import 'dart:io';\n\nimport 'package:dio/dio.dart';\nimport 'package:mockito/annotations.dart';\n\nimport 'http_mock.mocks.da"
},
{
"path": "dio/test/mock/http_mock.mocks.dart",
"chars": 29389,
"preview": "// Mocks generated by Mockito 5.2.0 from annotations\n// in dio/test/mock/http_mock.dart.\n// Do not manually edit this fi"
},
{
"path": "dio/test/multipart_file_test.dart",
"chars": 5832,
"preview": "import 'dart:convert';\n\nimport 'package:dio/dio.dart';\nimport 'package:test/test.dart';\n\nvoid main() async {\n test('loo"
},
{
"path": "dio/test/options_test.dart",
"chars": 14998,
"preview": "@TestOn('vm')\nimport 'dart:convert';\nimport 'dart:typed_data';\n\nimport 'package:dio/dio.dart';\nimport 'package:dio/io.da"
},
{
"path": "dio/test/options_timeout_integration_test.dart",
"chars": 4157,
"preview": "import 'package:dio/dio.dart';\nimport 'package:test/test.dart';\n\nvoid main() {\n group('Options timeout overrides', () {"
},
{
"path": "dio/test/parameter_test.dart",
"chars": 903,
"preview": "import 'package:dio/dio.dart';\nimport 'package:test/test.dart';\n\nvoid main() {\n group('ListParam', () {\n test('param"
},
{
"path": "dio/test/pinning_test.dart",
"chars": 5643,
"preview": "@TestOn('vm')\nimport 'dart:io';\n\nimport 'package:crypto/crypto.dart';\nimport 'package:dio/dio.dart';\nimport 'package:dio"
},
{
"path": "dio/test/queued_interceptor_test.dart",
"chars": 3941,
"preview": "import 'dart:async';\nimport 'package:dio/dio.dart';\nimport 'package:test/test.dart';\n\nvoid main() {\n test(\n 'Queue"
},
{
"path": "dio/test/response/response_stream_test.dart",
"chars": 6746,
"preview": "import 'dart:async';\nimport 'dart:typed_data';\n\nimport 'package:dio/dio.dart';\nimport 'package:dio/src/response/response"
},
{
"path": "dio/test/stacktrace_test.dart",
"chars": 12009,
"preview": "import 'dart:convert';\nimport 'dart:io';\n\nimport 'package:dio/dio.dart';\nimport 'package:dio/io.dart';\nimport 'package:d"
},
{
"path": "dio/test/test_suite_test.dart",
"chars": 167,
"preview": "import 'package:dio/dio.dart';\nimport 'package:dio_test/tests.dart';\n\nvoid main() {\n dioAdapterTestSuite(\n (baseUrl)"
},
{
"path": "dio/test/timeout_test.dart",
"chars": 1216,
"preview": "import 'dart:io';\n\nimport 'package:dio/dio.dart';\nimport 'package:dio/io.dart';\nimport 'package:dio_test/util.dart';\nimp"
},
{
"path": "dio/test/transformer_test.dart",
"chars": 11892,
"preview": "import 'dart:convert';\nimport 'dart:typed_data';\n\nimport 'package:dio/dio.dart';\nimport 'package:dio/src/transformers/ut"
},
{
"path": "dio/test/utils.dart",
"chars": 6232,
"preview": "import 'dart:async';\nimport 'dart:convert';\nimport 'dart:io';\nimport 'dart:typed_data';\n\nimport 'package:dio/dio.dart';\n"
},
{
"path": "dio_test/LICENSE",
"chars": 1070,
"preview": "MIT License\n\nCopyright (c) 2024 The CFUG Team\n\nPermission is hereby granted, free of charge, to any person obtaining a c"
},
{
"path": "dio_test/README.md",
"chars": 673,
"preview": "# Dio shared test package\n\nThe package gathered shared tests between Dio's packages,\nsuch as `dio` and `http2_adapter`.\n"
},
{
"path": "dio_test/analysis_options.yaml",
"chars": 93,
"preview": "include: ../analysis_options.yaml\n\nlinter:\n rules:\n depend_on_referenced_packages: false\n"
},
{
"path": "dio_test/dio_test.iml",
"chars": 762,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<module type=\"WEB_MODULE\" version=\"4\">\n <component name=\"NewModuleRootManager\" i"
},
{
"path": "dio_test/lib/src/httpbun.dart",
"chars": 46,
"preview": "const httpbunBaseUrl = 'https://httpbun.com';\n"
},
{
"path": "dio_test/lib/src/matcher.dart",
"chars": 1173,
"preview": "import 'package:dio/dio.dart';\nimport 'package:test/test.dart';\n\n/// A matcher for functions that throw [DioException] o"
},
{
"path": "dio_test/lib/src/test/basic_tests.dart",
"chars": 1908,
"preview": "import 'dart:io';\n\nimport 'package:dio/dio.dart';\nimport 'package:test/test.dart';\n\nimport '../../util.dart';\n\nvoid basi"
},
{
"path": "dio_test/lib/src/test/cancellation_tests.dart",
"chars": 3468,
"preview": "import 'dart:async';\n\nimport 'package:dio/dio.dart';\nimport 'package:test/test.dart';\n\nimport '../../util.dart';\n\nvoid c"
},
{
"path": "dio_test/lib/src/test/cors_tests.dart",
"chars": 3716,
"preview": "import 'package:dio/dio.dart';\nimport 'package:test/test.dart';\n\nimport '../../util.dart';\n\n/// Test that browsers can c"
},
{
"path": "dio_test/lib/src/test/download_tests.dart",
"chars": 12835,
"preview": "import 'dart:async';\nimport 'dart:convert';\nimport 'dart:io';\n\nimport 'package:dio/dio.dart';\nimport 'package:path/path."
},
{
"path": "dio_test/lib/src/test/headers_tests.dart",
"chars": 5287,
"preview": "import 'package:dio/dio.dart';\nimport 'package:test/test.dart';\n\nimport '../../util.dart';\n\nvoid headerTests(\n Dio Func"
},
{
"path": "dio_test/lib/src/test/http_method_tests.dart",
"chars": 7008,
"preview": "import 'package:dio/dio.dart';\nimport 'package:test/test.dart';\n\nimport '../../util.dart';\n\nvoid httpMethodTests(\n Dio "
},
{
"path": "dio_test/lib/src/test/parameter_tests.dart",
"chars": 1130,
"preview": "import 'package:dio/dio.dart';\nimport 'package:test/test.dart';\n\nimport '../../util.dart';\n\nvoid parameterTests(\n Dio F"
},
{
"path": "dio_test/lib/src/test/redirect_tests.dart",
"chars": 1987,
"preview": "import 'package:dio/dio.dart';\nimport 'package:test/test.dart';\n\nimport '../../util.dart';\n\nvoid redirectTests(\n Dio Fu"
},
{
"path": "dio_test/lib/src/test/status_code_tests.dart",
"chars": 1639,
"preview": "import 'package:dio/dio.dart';\nimport 'package:test/test.dart';\n\nimport '../../util.dart';\n\nvoid statusCodeTests(\n Dio "
},
{
"path": "dio_test/lib/src/test/suite.dart",
"chars": 537,
"preview": "import 'package:dio/dio.dart';\nimport '../../tests.dart';\n\ntypedef TestSuiteFunction = void Function(\n Dio Function(Str"
},
{
"path": "dio_test/lib/src/test/timeout_tests.dart",
"chars": 3373,
"preview": "import 'dart:async';\n\nimport 'package:dio/dio.dart';\nimport 'package:test/test.dart';\n\nimport '../../util.dart';\n\nvoid t"
},
{
"path": "dio_test/lib/src/test/upload_tests.dart",
"chars": 6194,
"preview": "import 'dart:async';\nimport 'dart:convert';\nimport 'dart:io';\nimport 'dart:typed_data';\n\nimport 'package:dio/dio.dart';\n"
},
{
"path": "dio_test/lib/src/test/url_encoded_tests.dart",
"chars": 1446,
"preview": "import 'package:dio/dio.dart';\nimport 'package:test/test.dart';\n\nimport '../../util.dart';\n\nvoid urlEncodedTests(\n Dio "
},
{
"path": "dio_test/lib/src/utils.dart",
"chars": 865,
"preview": "const _kIsWebInterop = bool.fromEnvironment('dart.library.js_interop');\nconst _kIsWebUtil = bool.fromEnvironment('dart.l"
},
{
"path": "dio_test/lib/tests.dart",
"chars": 501,
"preview": "export 'src/test/basic_tests.dart';\nexport 'src/test/cancellation_tests.dart';\nexport 'src/test/cors_tests.dart';\nexport"
},
{
"path": "dio_test/lib/util.dart",
"chars": 79,
"preview": "export 'src/httpbun.dart';\nexport 'src/matcher.dart';\nexport 'src/utils.dart';\n"
},
{
"path": "dio_test/pubspec.yaml",
"chars": 315,
"preview": "name: dio_test\nversion: 1.0.0\npublish_to: none\nhomepage: https://github.com/cfug/dio\nrepository: https://github.com/cfug"
},
{
"path": "dio_workspace.iml",
"chars": 2077,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<module type=\"WEB_MODULE\" version=\"4\">\n <component name=\"NewModuleRootManager\" i"
},
{
"path": "example_dart/.gitignore",
"chars": 425,
"preview": "# Miscellaneous\n*.class\n*.log\n*.pyc\n*.swp\n.DS_Store\n.atom/\n.buildlog/\n.history\n.svn/\n\n# IntelliJ related\n*.ipr\n*.iws\n.id"
},
{
"path": "example_dart/analysis_options.yaml",
"chars": 34,
"preview": "include: ../analysis_options.yaml\n"
},
{
"path": "example_dart/dart_test.yaml",
"chars": 56,
"preview": "file_reporters:\n json: build/reports/test-results.json\n"
},
{
"path": "example_dart/dio_example.iml",
"chars": 762,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<module type=\"WEB_MODULE\" version=\"4\">\n <component name=\"NewModuleRootManager\" i"
},
{
"path": "example_dart/lib/adapter.dart",
"chars": 883,
"preview": "import 'dart:async';\nimport 'dart:typed_data';\n\nimport 'package:dio/dio.dart';\n\nclass MyAdapter implements HttpClientAda"
},
{
"path": "example_dart/lib/cancel_request.dart",
"chars": 1264,
"preview": "import 'dart:async';\n\nimport 'package:dio/dio.dart';\n\nvoid main() async {\n final dio = Dio();\n dio.interceptors.add(Lo"
},
{
"path": "example_dart/lib/certificate_pinning.dart",
"chars": 2193,
"preview": "import 'dart:io';\n\nimport 'package:crypto/crypto.dart';\nimport 'package:dio/dio.dart';\nimport 'package:dio/io.dart';\n\nvo"
},
{
"path": "example_dart/lib/cookie_mgr.dart",
"chars": 499,
"preview": "import 'package:cookie_jar/cookie_jar.dart';\nimport 'package:dio/dio.dart';\nimport 'package:dio_cookie_manager/dio_cooki"
},
{
"path": "example_dart/lib/custom_cache_interceptor.dart",
"chars": 1289,
"preview": "import 'package:dio/dio.dart';\n\nclass CacheInterceptor extends Interceptor {\n CacheInterceptor();\n\n final _cache = <Ur"
},
{
"path": "example_dart/lib/dio.dart",
"chars": 2067,
"preview": "import 'dart:io';\n\nimport 'package:dio/dio.dart';\n\nvoid main() async {\n final dio = Dio();\n dio.options\n ..baseUrl "
},
{
"path": "example_dart/lib/download.dart",
"chars": 1744,
"preview": "import 'dart:async';\nimport 'dart:io';\n\nimport 'package:dio/dio.dart';\n\n// In this example we download a image and liste"
},
{
"path": "example_dart/lib/download_with_trunks.dart",
"chars": 2446,
"preview": "import 'dart:async';\nimport 'dart:io';\n\nimport 'package:dio/dio.dart';\n\nvoid main() async {\n final url = 'https://avata"
},
{
"path": "example_dart/lib/extend_dio.dart",
"chars": 489,
"preview": "import 'package:dio/dio.dart';\nimport 'package:dio/io.dart';\n\nclass HttpService extends DioForNative {\n HttpService([su"
},
{
"path": "example_dart/lib/formdata.dart",
"chars": 2672,
"preview": "import 'dart:convert';\nimport 'dart:io';\n\nimport 'package:dio/dio.dart';\nimport 'package:dio/io.dart';\n\nFuture<FormData>"
},
{
"path": "example_dart/lib/generic.dart",
"chars": 1291,
"preview": "import 'package:dio/dio.dart';\n\nvoid main() async {\n final dio = Dio(\n BaseOptions(\n baseUrl: 'https://httpbin."
},
{
"path": "example_dart/lib/http2_adapter.dart",
"chars": 520,
"preview": "import 'package:dio/dio.dart';\nimport 'package:dio_http2_adapter/dio_http2_adapter.dart';\n\nvoid main() async {\n final d"
},
{
"path": "example_dart/lib/options.dart",
"chars": 1239,
"preview": "import 'dart:io';\n\nimport 'package:dio/dio.dart';\n\nvoid main() async {\n final dio = Dio(\n BaseOptions(\n baseUrl"
},
{
"path": "example_dart/lib/post_stream_and_bytes.dart",
"chars": 1121,
"preview": "import 'dart:async';\nimport 'dart:convert';\nimport 'dart:io';\n\nimport 'package:dio/dio.dart';\n\nvoid main() async {\n fin"
},
{
"path": "example_dart/lib/proxy.dart",
"chars": 877,
"preview": "import 'dart:io';\n\nimport 'package:dio/dio.dart';\nimport 'package:dio/io.dart';\n\nvoid main() async {\n final dio = Dio()"
},
{
"path": "example_dart/lib/queue_interceptors.dart",
"chars": 1271,
"preview": "import 'package:dio/dio.dart';\n\nvoid main() async {\n final dio = Dio();\n dio.options.baseUrl = 'https://httpbin.org/st"
},
{
"path": "example_dart/lib/queued_interceptor_crsftoken.dart",
"chars": 4987,
"preview": "import 'dart:convert';\nimport 'dart:math';\n\nimport 'package:dio/dio.dart';\n\nvoid main() async {\n final tokenManager = T"
},
{
"path": "example_dart/lib/request_interceptors.dart",
"chars": 1518,
"preview": "import 'package:dio/dio.dart';\n\nvoid main() async {\n final dio = Dio();\n dio.options.baseUrl = 'https://httpbin.org/';"
},
{
"path": "example_dart/lib/response_interceptor.dart",
"chars": 2076,
"preview": "import 'dart:convert';\n\nimport 'package:dio/dio.dart';\n\nvoid main() async {\n const urlNotFound = 'https://wendux.github"
},
{
"path": "example_dart/lib/test.dart",
"chars": 868,
"preview": "import 'package:dio/dio.dart';\n\n// void getHttp() async {\n// final dio = Dio();\n// dio.interceptors.add(LogIntercept"
},
{
"path": "example_dart/lib/transformer.dart",
"chars": 1477,
"preview": "import 'dart:async';\n\nimport 'package:dio/dio.dart';\n\n/// If the request data is a `List` type, the [BackgroundTransform"
},
{
"path": "example_dart/lib/upload.txt",
"chars": 22,
"preview": "你好, 世界\n&\n$\n% U。想 。。\n\n"
},
{
"path": "example_dart/pubspec.yaml",
"chars": 415,
"preview": "name: dio_example\ndescription: The example snippets for Dio.\nversion: 0.0.1\npublish_to: \"none\"\n\nenvironment:\n sdk: \">=3"
},
{
"path": "example_flutter_app/.gitignore",
"chars": 726,
"preview": "# Miscellaneous\n*.class\n*.log\n*.pyc\n*.swp\n.DS_Store\n.atom/\n.buildlog/\n.history\n.svn/\n\n# IntelliJ related\n*.ipr\n*.iws\n.id"
},
{
"path": "example_flutter_app/.metadata",
"chars": 1706,
"preview": "# This file tracks properties of this Flutter project.\n# Used by Flutter tool to assess capabilities and perform upgrade"
},
{
"path": "example_flutter_app/README.md",
"chars": 558,
"preview": "# flutter_app\n\nA new Flutter application for dio test.\n\n## Getting Started\n\nThis project is a starting point for a Flutt"
},
{
"path": "example_flutter_app/analysis_options.yaml",
"chars": 34,
"preview": "include: ../analysis_options.yaml\n"
},
{
"path": "example_flutter_app/android/.gitignore",
"chars": 262,
"preview": "gradle-wrapper.jar\n/.gradle\n/.kotlin\n/captures/\n/gradlew\n/gradlew.bat\n/local.properties\nGeneratedPluginRegistrant.java\n."
},
{
"path": "example_flutter_app/android/app/build.gradle.kts",
"chars": 1408,
"preview": "plugins {\n id(\"com.android.application\")\n id(\"kotlin-android\")\n // The Flutter Gradle Plugin must be applied af"
},
{
"path": "example_flutter_app/android/app/src/main/AndroidManifest.xml",
"chars": 2273,
"preview": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\">\n <uses-permission android:name=\"android.permiss"
},
{
"path": "example_flutter_app/android/app/src/main/kotlin/cn/flutter/dio_flutter_example/MainActivity.kt",
"chars": 132,
"preview": "package cn.flutter.dio_flutter_example\n\nimport io.flutter.embedding.android.FlutterActivity\n\nclass MainActivity : Flutte"
},
{
"path": "example_flutter_app/android/app/src/main/res/drawable/launch_background.xml",
"chars": 434,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Modify this file to customize your launch splash screen -->\n<layer-list xmln"
},
{
"path": "example_flutter_app/android/app/src/main/res/drawable-v21/launch_background.xml",
"chars": 438,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Modify this file to customize your launch splash screen -->\n<layer-list xmln"
},
{
"path": "example_flutter_app/android/app/src/main/res/values/styles.xml",
"chars": 996,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n <!-- Theme applied to the Android Window while the process is sta"
},
{
"path": "example_flutter_app/android/app/src/main/res/values-night/styles.xml",
"chars": 995,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n <!-- Theme applied to the Android Window while the process is sta"
},
{
"path": "example_flutter_app/android/build.gradle.kts",
"chars": 515,
"preview": "allprojects {\n repositories {\n google()\n mavenCentral()\n }\n}\n\nval newBuildDir: Directory = rootProje"
},
{
"path": "example_flutter_app/android/dio_flutter_example_android.iml",
"chars": 1601,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<module type=\"JAVA_MODULE\" version=\"4\">\n <component name=\"FacetManager\">\n <fa"
},
{
"path": "example_flutter_app/android/gradle/wrapper/gradle-wrapper.properties",
"chars": 203,
"preview": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dist"
},
{
"path": "example_flutter_app/android/gradle.properties",
"chars": 166,
"preview": "org.gradle.jvmargs=-Xmx8G -XX:MaxMetaspaceSize=4G -XX:ReservedCodeCacheSize=512m -XX:+HeapDumpOnOutOfMemoryError\nandroid"
},
{
"path": "example_flutter_app/android/settings.gradle.kts",
"chars": 740,
"preview": "pluginManagement {\n val flutterSdkPath = run {\n val properties = java.util.Properties()\n file(\"local.pr"
},
{
"path": "example_flutter_app/dio_flutter_example.iml",
"chars": 1399,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<module type=\"JAVA_MODULE\" version=\"4\">\n <component name=\"NewModuleRootManager\" "
},
{
"path": "example_flutter_app/example_flutter_app.iml",
"chars": 842,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<module type=\"JAVA_MODULE\" version=\"4\">\n <component name=\"NewModuleRootManager\" "
},
{
"path": "example_flutter_app/ios/.gitignore",
"chars": 569,
"preview": "**/dgph\n*.mode1v3\n*.mode2v3\n*.moved-aside\n*.pbxuser\n*.perspectivev3\n**/*sync/\n.sconsign.dblite\n.tags*\n**/.vagrant/\n**/De"
},
{
"path": "example_flutter_app/ios/Flutter/AppFrameworkInfo.plist",
"chars": 774,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "example_flutter_app/ios/Flutter/Debug.xcconfig",
"chars": 30,
"preview": "#include \"Generated.xcconfig\"\n"
},
{
"path": "example_flutter_app/ios/Flutter/Release.xcconfig",
"chars": 30,
"preview": "#include \"Generated.xcconfig\"\n"
},
{
"path": "example_flutter_app/ios/Runner/AppDelegate.swift",
"chars": 391,
"preview": "import Flutter\nimport UIKit\n\n@main\n@objc class AppDelegate: FlutterAppDelegate {\n override func application(\n _ appl"
},
{
"path": "example_flutter_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json",
"chars": 2519,
"preview": "{\n \"images\" : [\n {\n \"size\" : \"20x20\",\n \"idiom\" : \"iphone\",\n \"filename\" : \"Icon-App-20x20@2x.png\",\n "
},
{
"path": "example_flutter_app/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json",
"chars": 391,
"preview": "{\n \"images\" : [\n {\n \"idiom\" : \"universal\",\n \"filename\" : \"LaunchImage.png\",\n \"scale\" : \"1x\"\n },\n "
},
{
"path": "example_flutter_app/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md",
"chars": 336,
"preview": "# Launch Screen Assets\n\nYou can customize the launch screen with your own desired assets by replacing the image files in"
},
{
"path": "example_flutter_app/ios/Runner/Base.lproj/LaunchScreen.storyboard",
"chars": 2377,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard"
},
{
"path": "example_flutter_app/ios/Runner/Base.lproj/Main.storyboard",
"chars": 1605,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard"
},
{
"path": "example_flutter_app/ios/Runner/Info.plist",
"chars": 1763,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "example_flutter_app/ios/Runner/Runner-Bridging-Header.h",
"chars": 38,
"preview": "#import \"GeneratedPluginRegistrant.h\"\n"
},
{
"path": "example_flutter_app/ios/Runner.xcodeproj/project.pbxproj",
"chars": 23702,
"preview": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 54;\n\tobjects = {\n\n/* Begin PBXBuildFile section *"
},
{
"path": "example_flutter_app/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata",
"chars": 135,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n version = \"1.0\">\n <FileRef\n location = \"self:\">\n </FileRef"
},
{
"path": "example_flutter_app/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist",
"chars": 238,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "example_flutter_app/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings",
"chars": 226,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "example_flutter_app/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme",
"chars": 3833,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n LastUpgradeVersion = \"1510\"\n version = \"1.3\">\n <BuildAction\n "
},
{
"path": "example_flutter_app/ios/Runner.xcworkspace/contents.xcworkspacedata",
"chars": 152,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n version = \"1.0\">\n <FileRef\n location = \"group:Runner.xcodepr"
},
{
"path": "example_flutter_app/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist",
"chars": 238,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "example_flutter_app/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings",
"chars": 226,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "example_flutter_app/ios/RunnerTests/RunnerTests.swift",
"chars": 285,
"preview": "import Flutter\nimport UIKit\nimport XCTest\n\nclass RunnerTests: XCTestCase {\n\n func testExample() {\n // If you add cod"
},
{
"path": "example_flutter_app/lib/http.dart",
"chars": 120,
"preview": "import 'package:dio/dio.dart';\n\nfinal dio = Dio(\n BaseOptions(\n connectTimeout: const Duration(seconds: 3),\n ),\n);\n"
},
{
"path": "example_flutter_app/lib/main.dart",
"chars": 2212,
"preview": "import 'package:dio/dio.dart';\nimport 'package:flutter/material.dart';\n\nimport 'http.dart'; // make dio as global top-le"
},
{
"path": "example_flutter_app/lib/routes/request.dart",
"chars": 1938,
"preview": "import 'package:dio/dio.dart';\nimport 'package:flutter/material.dart';\n\nimport '../http.dart';\n\nclass RequestRoute exten"
},
{
"path": "example_flutter_app/linux/.gitignore",
"chars": 18,
"preview": "flutter/ephemeral\n"
},
{
"path": "example_flutter_app/linux/CMakeLists.txt",
"chars": 4776,
"preview": "# Project-level configuration.\ncmake_minimum_required(VERSION 3.13)\nproject(runner LANGUAGES CXX)\n\n# The name of the exe"
},
{
"path": "example_flutter_app/linux/flutter/CMakeLists.txt",
"chars": 2815,
"preview": "# This file controls Flutter-level build steps. It should not be edited.\ncmake_minimum_required(VERSION 3.10)\n\nset(EPHEM"
},
{
"path": "example_flutter_app/linux/flutter/generated_plugin_registrant.cc",
"chars": 161,
"preview": "//\n// Generated file. Do not edit.\n//\n\n// clang-format off\n\n#include \"generated_plugin_registrant.h\"\n\n\nvoid fl_register"
}
]
// ... and 223 more files (download for full content)
About this extraction
This page contains the full source code of the cfug/dio GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 423 files (1.0 MB), approximately 269.7k tokens, and a symbol index with 674 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.