diff --git a/.github/labeler.yml b/.github/labeler.yml
index 7ac52ce..b49eaf2 100644
--- a/.github/labeler.yml
+++ b/.github/labeler.yml
@@ -1,6 +1,6 @@
-# Configuration for .github/workflows/pull_request_label.yml. 
+# Configuration for .github/workflows/pull_request_label.yml.
 
-'infra':
+'type-infra':
   - '.github/**'
 
 'package:cronet_http':
diff --git a/.github/workflows/cronet.yml b/.github/workflows/cronet.yml
index 94fcf1c..0976a75 100644
--- a/.github/workflows/cronet.yml
+++ b/.github/workflows/cronet.yml
@@ -6,10 +6,12 @@
       - main
       - master
     paths:
+      - '.github/workflows/cronet.yaml'
       - 'pkgs/cronet_http/**'
       - 'pkgs/http_client_conformance_tests/**'
   pull_request:
     paths:
+      - '.github/workflows/cronet.yaml'
       - 'pkgs/cronet_http/**'
       - 'pkgs/http_client_conformance_tests/**'
   schedule:
@@ -19,48 +21,48 @@
   PUB_ENVIRONMENT: bot.github
 
 jobs:
-  analyze:
-    name: Lint and static analysis
-    runs-on: ubuntu-latest
-    defaults:
-      run:
-        working-directory: pkgs/cronet_http
-    steps:
-      - uses: actions/checkout@v4
-      - uses: subosito/flutter-action@v2
-        with:
-          # TODO: Change to 'stable' when a release version of flutter
-          # pins version 1.21.1 or later of 'package:test'
-          channel: 'master'
-      - id: install
-        name: Install dependencies
-        run: flutter pub get
-      - name: Check formatting
-        run: dart format --output=none --set-exit-if-changed .
-        if: always() && steps.install.outcome == 'success'
-      - name: Analyze code
-        run: flutter analyze --fatal-infos
-        if: always() && steps.install.outcome == 'success'
-
-  test:
-    # Test package:cupertino_http use flutter integration tests.
-    needs: analyze
-    name: "Build and test"
+  verify:
+    name: Format & Analyze & Test
     runs-on: macos-latest
+    strategy:
+      matrix:
+        package: ['cronet_http', 'cronet_http_embedded']
     steps:
       - uses: actions/checkout@v4
-      - uses: actions/setup-java@v3
+      - uses: actions/setup-java@v4
         with:
           distribution: 'zulu'
           java-version: '17'
       - uses: subosito/flutter-action@v2
         with:
           channel: 'stable'
+      - name: Make cronet_http_embedded copy
+        if: ${{ matrix.package == 'cronet_http_embedded' }}
+        run: |
+          cp -r pkgs/cronet_http pkgs/cronet_http_embedded
+          cd pkgs/cronet_http_embedded
+          flutter pub get && dart tool/prepare_for_embedded.dart
+      - id: install
+        name: Install dependencies
+        working-directory: 'pkgs/${{ matrix.package }}'
+        run: flutter pub get
+      - name: Check formatting
+        working-directory: 'pkgs/${{ matrix.package }}'
+        run: dart format --output=none --set-exit-if-changed .
+        if: always() && steps.install.outcome == 'success'
+      - name: Analyze code
+        working-directory: 'pkgs/${{ matrix.package }}'
+        run: flutter analyze --fatal-infos
+        if: always() && steps.install.outcome == 'success'
       - name: Run tests
         uses: reactivecircus/android-emulator-runner@v2
+        if: always() && steps.install.outcome == 'success'
         with:
+          # api-level/minSdkVersion should be help in sync in:
+          # - .github/workflows/cronet.yml
+          # - pkgs/cronet_http/android/build.gradle
+          # - pkgs/cronet_http/example/android/app/build.gradle
           api-level: 28
-          target: playstore
-          arch: x86_64
+          target: ${{ matrix.package == 'cronet_http_embedded' && 'google_apis' || 'playstore' }}
           profile: pixel
-          script: cd ./pkgs/cronet_http/example && flutter test --timeout=1200s integration_test/
+          script: cd 'pkgs/${{ matrix.package }}/example' && flutter test --timeout=1200s integration_test/
diff --git a/.github/workflows/dart.yml b/.github/workflows/dart.yml
index 35af167..3cb8d19 100644
--- a/.github/workflows/dart.yml
+++ b/.github/workflows/dart.yml
@@ -1,4 +1,4 @@
-# Created with package:mono_repo v6.6.0
+# Created with package:mono_repo v6.6.1
 name: Dart CI
 on:
   push:
@@ -36,27 +36,27 @@
         name: Checkout repository
         uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
       - name: mono_repo self validate
-        run: dart pub global activate mono_repo 6.6.0
+        run: dart pub global activate mono_repo 6.6.1
       - name: mono_repo self validate
         run: dart pub global run mono_repo generate --validate
   job_002:
-    name: "analyze_and_format; linux; Dart 2.19.0; PKG: pkgs/http_client_conformance_tests; `dart analyze --fatal-infos`"
+    name: "analyze_and_format; linux; Dart 3.0.0; PKGS: pkgs/http_client_conformance_tests, pkgs/http_profile; `dart analyze --fatal-infos`"
     runs-on: ubuntu-latest
     steps:
       - name: Cache Pub hosted dependencies
         uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84
         with:
           path: "~/.pub-cache/hosted"
-          key: "os:ubuntu-latest;pub-cache-hosted;sdk:2.19.0;packages:pkgs/http_client_conformance_tests;commands:analyze_1"
+          key: "os:ubuntu-latest;pub-cache-hosted;sdk:3.0.0;packages:pkgs/http_client_conformance_tests-pkgs/http_profile;commands:analyze_1"
           restore-keys: |
-            os:ubuntu-latest;pub-cache-hosted;sdk:2.19.0;packages:pkgs/http_client_conformance_tests
-            os:ubuntu-latest;pub-cache-hosted;sdk:2.19.0
+            os:ubuntu-latest;pub-cache-hosted;sdk:3.0.0;packages:pkgs/http_client_conformance_tests-pkgs/http_profile
+            os:ubuntu-latest;pub-cache-hosted;sdk:3.0.0
             os:ubuntu-latest;pub-cache-hosted
             os:ubuntu-latest
       - name: Setup Dart SDK
         uses: dart-lang/setup-dart@b64355ae6ca0b5d484f0106a033dd1388965d06d
         with:
-          sdk: "2.19.0"
+          sdk: "3.0.0"
       - id: checkout
         name: Checkout repository
         uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
@@ -69,24 +69,33 @@
         run: dart analyze --fatal-infos
         if: "always() && steps.pkgs_http_client_conformance_tests_pub_upgrade.conclusion == 'success'"
         working-directory: pkgs/http_client_conformance_tests
+      - id: pkgs_http_profile_pub_upgrade
+        name: pkgs/http_profile; dart pub upgrade
+        run: dart pub upgrade
+        if: "always() && steps.checkout.conclusion == 'success'"
+        working-directory: pkgs/http_profile
+      - name: "pkgs/http_profile; dart analyze --fatal-infos"
+        run: dart analyze --fatal-infos
+        if: "always() && steps.pkgs_http_profile_pub_upgrade.conclusion == 'success'"
+        working-directory: pkgs/http_profile
   job_003:
-    name: "analyze_and_format; linux; Dart 3.0.0; PKGS: pkgs/http, pkgs/http_profile; `dart analyze --fatal-infos`"
+    name: "analyze_and_format; linux; Dart 3.2.0; PKG: pkgs/http; `dart analyze --fatal-infos`"
     runs-on: ubuntu-latest
     steps:
       - name: Cache Pub hosted dependencies
         uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84
         with:
           path: "~/.pub-cache/hosted"
-          key: "os:ubuntu-latest;pub-cache-hosted;sdk:3.0.0;packages:pkgs/http-pkgs/http_profile;commands:analyze_1"
+          key: "os:ubuntu-latest;pub-cache-hosted;sdk:3.2.0;packages:pkgs/http;commands:analyze_1"
           restore-keys: |
-            os:ubuntu-latest;pub-cache-hosted;sdk:3.0.0;packages:pkgs/http-pkgs/http_profile
-            os:ubuntu-latest;pub-cache-hosted;sdk:3.0.0
+            os:ubuntu-latest;pub-cache-hosted;sdk:3.2.0;packages:pkgs/http
+            os:ubuntu-latest;pub-cache-hosted;sdk:3.2.0
             os:ubuntu-latest;pub-cache-hosted
             os:ubuntu-latest
       - name: Setup Dart SDK
         uses: dart-lang/setup-dart@b64355ae6ca0b5d484f0106a033dd1388965d06d
         with:
-          sdk: "3.0.0"
+          sdk: "3.2.0"
       - id: checkout
         name: Checkout repository
         uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
@@ -99,15 +108,6 @@
         run: dart analyze --fatal-infos
         if: "always() && steps.pkgs_http_pub_upgrade.conclusion == 'success'"
         working-directory: pkgs/http
-      - id: pkgs_http_profile_pub_upgrade
-        name: pkgs/http_profile; dart pub upgrade
-        run: dart pub upgrade
-        if: "always() && steps.checkout.conclusion == 'success'"
-        working-directory: pkgs/http_profile
-      - name: "pkgs/http_profile; dart analyze --fatal-infos"
-        run: dart analyze --fatal-infos
-        if: "always() && steps.pkgs_http_profile_pub_upgrade.conclusion == 'success'"
-        working-directory: pkgs/http_profile
   job_004:
     name: "analyze_and_format; linux; Dart dev; PKGS: pkgs/http, pkgs/http_client_conformance_tests, pkgs/http_profile; `dart analyze --fatal-infos`"
     runs-on: ubuntu-latest
@@ -265,16 +265,16 @@
         if: "always() && steps.pkgs_flutter_http_example_pub_upgrade.conclusion == 'success'"
         working-directory: pkgs/flutter_http_example
   job_008:
-    name: "unit_test; linux; Dart 3.0.0; PKG: pkgs/http; `dart run --define=no_default_http_client=true test/no_default_http_client_test.dart`"
+    name: "unit_test; linux; Dart 3.0.0; PKG: pkgs/http_profile; `dart test --platform vm`"
     runs-on: ubuntu-latest
     steps:
       - name: Cache Pub hosted dependencies
         uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84
         with:
           path: "~/.pub-cache/hosted"
-          key: "os:ubuntu-latest;pub-cache-hosted;sdk:3.0.0;packages:pkgs/http;commands:command_1"
+          key: "os:ubuntu-latest;pub-cache-hosted;sdk:3.0.0;packages:pkgs/http_profile;commands:test_2"
           restore-keys: |
-            os:ubuntu-latest;pub-cache-hosted;sdk:3.0.0;packages:pkgs/http
+            os:ubuntu-latest;pub-cache-hosted;sdk:3.0.0;packages:pkgs/http_profile
             os:ubuntu-latest;pub-cache-hosted;sdk:3.0.0
             os:ubuntu-latest;pub-cache-hosted
             os:ubuntu-latest
@@ -285,6 +285,44 @@
       - id: checkout
         name: Checkout repository
         uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
+      - id: pkgs_http_profile_pub_upgrade
+        name: pkgs/http_profile; dart pub upgrade
+        run: dart pub upgrade
+        if: "always() && steps.checkout.conclusion == 'success'"
+        working-directory: pkgs/http_profile
+      - name: "pkgs/http_profile; dart test --platform vm"
+        run: dart test --platform vm
+        if: "always() && steps.pkgs_http_profile_pub_upgrade.conclusion == 'success'"
+        working-directory: pkgs/http_profile
+    needs:
+      - job_001
+      - job_002
+      - job_003
+      - job_004
+      - job_005
+      - job_006
+      - job_007
+  job_009:
+    name: "unit_test; linux; Dart 3.2.0; PKG: pkgs/http; `dart run --define=no_default_http_client=true test/no_default_http_client_test.dart`"
+    runs-on: ubuntu-latest
+    steps:
+      - name: Cache Pub hosted dependencies
+        uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84
+        with:
+          path: "~/.pub-cache/hosted"
+          key: "os:ubuntu-latest;pub-cache-hosted;sdk:3.2.0;packages:pkgs/http;commands:command_1"
+          restore-keys: |
+            os:ubuntu-latest;pub-cache-hosted;sdk:3.2.0;packages:pkgs/http
+            os:ubuntu-latest;pub-cache-hosted;sdk:3.2.0
+            os:ubuntu-latest;pub-cache-hosted
+            os:ubuntu-latest
+      - name: Setup Dart SDK
+        uses: dart-lang/setup-dart@b64355ae6ca0b5d484f0106a033dd1388965d06d
+        with:
+          sdk: "3.2.0"
+      - id: checkout
+        name: Checkout repository
+        uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
       - id: pkgs_http_pub_upgrade
         name: pkgs/http; dart pub upgrade
         run: dart pub upgrade
@@ -302,24 +340,24 @@
       - job_005
       - job_006
       - job_007
-  job_009:
-    name: "unit_test; linux; Dart 3.0.0; PKG: pkgs/http; `dart test --platform chrome`"
+  job_010:
+    name: "unit_test; linux; Dart 3.2.0; PKG: pkgs/http; `dart test --platform chrome`"
     runs-on: ubuntu-latest
     steps:
       - name: Cache Pub hosted dependencies
         uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84
         with:
           path: "~/.pub-cache/hosted"
-          key: "os:ubuntu-latest;pub-cache-hosted;sdk:3.0.0;packages:pkgs/http;commands:test_3"
+          key: "os:ubuntu-latest;pub-cache-hosted;sdk:3.2.0;packages:pkgs/http;commands:test_3"
           restore-keys: |
-            os:ubuntu-latest;pub-cache-hosted;sdk:3.0.0;packages:pkgs/http
-            os:ubuntu-latest;pub-cache-hosted;sdk:3.0.0
+            os:ubuntu-latest;pub-cache-hosted;sdk:3.2.0;packages:pkgs/http
+            os:ubuntu-latest;pub-cache-hosted;sdk:3.2.0
             os:ubuntu-latest;pub-cache-hosted
             os:ubuntu-latest
       - name: Setup Dart SDK
         uses: dart-lang/setup-dart@b64355ae6ca0b5d484f0106a033dd1388965d06d
         with:
-          sdk: "3.0.0"
+          sdk: "3.2.0"
       - id: checkout
         name: Checkout repository
         uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
@@ -340,24 +378,24 @@
       - job_005
       - job_006
       - job_007
-  job_010:
-    name: "unit_test; linux; Dart 3.0.0; PKGS: pkgs/http, pkgs/http_profile; `dart test --platform vm`"
+  job_011:
+    name: "unit_test; linux; Dart 3.2.0; PKG: pkgs/http; `dart test --platform vm`"
     runs-on: ubuntu-latest
     steps:
       - name: Cache Pub hosted dependencies
         uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84
         with:
           path: "~/.pub-cache/hosted"
-          key: "os:ubuntu-latest;pub-cache-hosted;sdk:3.0.0;packages:pkgs/http-pkgs/http_profile;commands:test_2"
+          key: "os:ubuntu-latest;pub-cache-hosted;sdk:3.2.0;packages:pkgs/http;commands:test_2"
           restore-keys: |
-            os:ubuntu-latest;pub-cache-hosted;sdk:3.0.0;packages:pkgs/http-pkgs/http_profile
-            os:ubuntu-latest;pub-cache-hosted;sdk:3.0.0
+            os:ubuntu-latest;pub-cache-hosted;sdk:3.2.0;packages:pkgs/http
+            os:ubuntu-latest;pub-cache-hosted;sdk:3.2.0
             os:ubuntu-latest;pub-cache-hosted
             os:ubuntu-latest
       - name: Setup Dart SDK
         uses: dart-lang/setup-dart@b64355ae6ca0b5d484f0106a033dd1388965d06d
         with:
-          sdk: "3.0.0"
+          sdk: "3.2.0"
       - id: checkout
         name: Checkout repository
         uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
@@ -370,15 +408,6 @@
         run: dart test --platform vm
         if: "always() && steps.pkgs_http_pub_upgrade.conclusion == 'success'"
         working-directory: pkgs/http
-      - id: pkgs_http_profile_pub_upgrade
-        name: pkgs/http_profile; dart pub upgrade
-        run: dart pub upgrade
-        if: "always() && steps.checkout.conclusion == 'success'"
-        working-directory: pkgs/http_profile
-      - name: "pkgs/http_profile; dart test --platform vm"
-        run: dart test --platform vm
-        if: "always() && steps.pkgs_http_profile_pub_upgrade.conclusion == 'success'"
-        working-directory: pkgs/http_profile
     needs:
       - job_001
       - job_002
@@ -387,7 +416,7 @@
       - job_005
       - job_006
       - job_007
-  job_011:
+  job_012:
     name: "unit_test; linux; Dart dev; PKG: pkgs/http; `dart run --define=no_default_http_client=true test/no_default_http_client_test.dart`"
     runs-on: ubuntu-latest
     steps:
@@ -425,7 +454,7 @@
       - job_005
       - job_006
       - job_007
-  job_012:
+  job_013:
     name: "unit_test; linux; Dart dev; PKG: pkgs/http; `dart test --platform chrome`"
     runs-on: ubuntu-latest
     steps:
@@ -463,7 +492,7 @@
       - job_005
       - job_006
       - job_007
-  job_013:
+  job_014:
     name: "unit_test; linux; Dart dev; PKGS: pkgs/http, pkgs/http_profile; `dart test --platform vm`"
     runs-on: ubuntu-latest
     steps:
@@ -510,7 +539,45 @@
       - job_005
       - job_006
       - job_007
-  job_014:
+  job_015:
+    name: "unit_test; linux; Dart dev; PKG: pkgs/http; `dart test --test-randomize-ordering-seed=random -p chrome -c dart2wasm`"
+    runs-on: ubuntu-latest
+    steps:
+      - name: Cache Pub hosted dependencies
+        uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84
+        with:
+          path: "~/.pub-cache/hosted"
+          key: "os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:pkgs/http;commands:test_4"
+          restore-keys: |
+            os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:pkgs/http
+            os:ubuntu-latest;pub-cache-hosted;sdk:dev
+            os:ubuntu-latest;pub-cache-hosted
+            os:ubuntu-latest
+      - name: Setup Dart SDK
+        uses: dart-lang/setup-dart@b64355ae6ca0b5d484f0106a033dd1388965d06d
+        with:
+          sdk: dev
+      - id: checkout
+        name: Checkout repository
+        uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
+      - id: pkgs_http_pub_upgrade
+        name: pkgs/http; dart pub upgrade
+        run: dart pub upgrade
+        if: "always() && steps.checkout.conclusion == 'success'"
+        working-directory: pkgs/http
+      - name: "pkgs/http; dart test --test-randomize-ordering-seed=random -p chrome -c dart2wasm"
+        run: "dart test --test-randomize-ordering-seed=random -p chrome -c dart2wasm"
+        if: "always() && steps.pkgs_http_pub_upgrade.conclusion == 'success'"
+        working-directory: pkgs/http
+    needs:
+      - job_001
+      - job_002
+      - job_003
+      - job_004
+      - job_005
+      - job_006
+      - job_007
+  job_016:
     name: "unit_test; linux; Flutter stable; PKG: pkgs/flutter_http_example; `flutter test --platform chrome`"
     runs-on: ubuntu-latest
     steps:
@@ -548,7 +615,7 @@
       - job_005
       - job_006
       - job_007
-  job_015:
+  job_017:
     name: "unit_test; linux; Flutter stable; PKG: pkgs/flutter_http_example; `flutter test`"
     runs-on: ubuntu-latest
     steps:
@@ -586,7 +653,7 @@
       - job_005
       - job_006
       - job_007
-  job_016:
+  job_018:
     name: "unit_test; macos; Flutter stable; PKG: pkgs/flutter_http_example; `flutter test`"
     runs-on: macos-latest
     steps:
@@ -624,7 +691,7 @@
       - job_005
       - job_006
       - job_007
-  job_017:
+  job_019:
     name: "unit_test; windows; Flutter stable; PKG: pkgs/flutter_http_example; `flutter test`"
     runs-on: windows-latest
     steps:
diff --git a/.github/workflows/pull_request_label.yml b/.github/workflows/pull_request_label.yml
index 9933aad..54e3df5 100644
--- a/.github/workflows/pull_request_label.yml
+++ b/.github/workflows/pull_request_label.yml
@@ -16,7 +16,7 @@
       pull-requests: write
     runs-on: ubuntu-latest
     steps:
-      - uses: actions/labeler@ac9175f8a1f3625fd0d4fb234536d26811351594
+      - uses: actions/labeler@8558fd74291d67161a8a78ce36a881fa63b766a9
         with:
           repo-token: "${{ secrets.GITHUB_TOKEN }}"
           sync-labels: true
diff --git a/analysis_options.yaml b/analysis_options.yaml
index 7d741bd..e536739 100644
--- a/analysis_options.yaml
+++ b/analysis_options.yaml
@@ -14,15 +14,10 @@
   - avoid_returning_this
   - avoid_unused_constructor_parameters
   - cascade_invocations
-  - comment_references
   - join_return_with_assignment
   - missing_whitespace_between_adjacent_strings
   - no_adjacent_strings_in_list
   - no_runtimeType_toString
-  - prefer_const_constructors
   - prefer_const_declarations
   - prefer_expression_function_bodies
-  - prefer_relative_imports
-  - test_types_in_equals
   - use_string_buffers
-  - use_super_parameters
diff --git a/pkgs/cronet_http/CHANGELOG.md b/pkgs/cronet_http/CHANGELOG.md
index 83e2701..cf1fcbc 100644
--- a/pkgs/cronet_http/CHANGELOG.md
+++ b/pkgs/cronet_http/CHANGELOG.md
@@ -1,6 +1,11 @@
+## 1.0.0
+
+* No functional changes. 
+
 ## 0.4.2
 
 * Require `package:jni >= 0.7.2` to remove a potential buffer overflow.
+* Fix a bug where incorrect HTTP request methods were sent.
 
 ## 0.4.1
  
diff --git a/pkgs/cronet_http/README.md b/pkgs/cronet_http/README.md
index 0238eb6..49acf33 100644
--- a/pkgs/cronet_http/README.md
+++ b/pkgs/cronet_http/README.md
@@ -1,31 +1,61 @@
+[![pub package](https://img.shields.io/pub/v/cronet_http.svg)](https://pub.dev/packages/cronet_http)
+[![package publisher](https://img.shields.io/pub/publisher/cronet_http.svg)](https://pub.dev/packages/cronet_http/publisher)
+
 An Android Flutter plugin that provides access to the
-[Cronet](https://developer.android.com/guide/topics/connectivity/cronet/reference/org/chromium/net/package-summary)
+[Cronet][]
 HTTP client.
 
 Cronet is available as part of
-[Google Play Services](https://developers.google.com/android/guides/overview). 
+[Google Play Services][]. 
 
-This package depends on
-[Google Play Services](https://developers.google.com/android/guides/overview)
-for its Cronet implementation.
+This package depends on [Google Play Services][] for its [Cronet][]
+implementation.
 [`package:cronet_http_embedded`](https://pub.dev/packages/cronet_http_embedded)
-is functionally identical to this package but embeds Cronet directly instead
-of relying on
-[Google Play Services](https://developers.google.com/android/guides/overview).
+is functionally identical to this package but embeds [Cronet][] directly
+instead of relying on [Google Play Services][].
 
-## Status: Experimental
+## Motivation
 
-**NOTE**: This package is currently experimental and published under the
-[labs.dart.dev](https://dart.dev/dart-team-packages) pub publisher in order to
-solicit feedback. 
+Using [Cronet][], rather than the socket-based [dart:io HttpClient][]
+implemententation, has several advantages:
 
-For packages in the labs.dart.dev publisher we generally plan to either graduate
-the package into a supported publisher (dart.dev, tools.dart.dev) after a period
-of feedback and iteration, or discontinue the package. These packages have a
-much higher expected rate of API and breaking changes.
+1. It automatically supports Android platform features such as HTTP proxies.
+2. It supports configurable caching.
+3. It supports more HTTP features such as HTTP/3.
 
-Your feedback is valuable and will help us evolve this package. 
-For general feedback and suggestions please comment in the
-[feedback issue](https://github.com/dart-lang/http/issues/764).
-For bugs, please file an issue in the 
-[bug tracker](https://github.com/dart-lang/http/issues).
+## Using
+
+The easiest way to use this library is via the the high-level interface
+defined by [package:http Client][].
+
+This approach allows the same HTTP code to be used on all platforms, while
+still allowing platform-specific setup.
+
+```dart
+import 'package:cronet_http/cronet_http.dart';
+import 'package:http/http.dart';
+import 'package:http/io_client.dart';
+
+void main() async {
+  late Client httpClient;
+  if (Platform.isAndroid) {
+    final engine = CronetEngine.build(
+        cacheMode: CacheMode.memory,
+        cacheMaxSize: 2 * 1024 * 1024,
+        userAgent: 'Book Agent');
+    httpClient = CronetClient.fromCronetEngine(engine);
+  } else {
+    httpClient = IOClient(HttpClient()..userAgent = 'Book Agent');
+  }
+
+  final response = await client.get(Uri.https(
+      'www.googleapis.com',
+      '/books/v1/volumes',
+      {'q': 'HTTP', 'maxResults': '40', 'printType': 'books'}));
+}
+```
+
+[Cronet]: https://developer.android.com/guide/topics/connectivity/cronet/reference/org/chromium/net/package-summary
+[dart:io HttpClient]: https://api.dart.dev/stable/dart-io/HttpClient-class.html
+[Google Play Services]: https://developers.google.com/android/guides/overview
+[package:http Client]: https://pub.dev/documentation/http/latest/http/Client-class.html
diff --git a/pkgs/cronet_http/android/build.gradle b/pkgs/cronet_http/android/build.gradle
index 3a91d8a..96bb197 100644
--- a/pkgs/cronet_http/android/build.gradle
+++ b/pkgs/cronet_http/android/build.gradle
@@ -2,14 +2,14 @@
 version '1.0-SNAPSHOT'
 
 buildscript {
-    ext.kotlin_version = '1.6.10'
+    ext.kotlin_version = '1.7.21'
     repositories {
         google()
         mavenCentral()
     }
 
     dependencies {
-        classpath 'com.android.tools.build:gradle:7.1.2'
+        classpath 'com.android.tools.build:gradle:7.4.2'
         classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
     }
 }
@@ -25,6 +25,11 @@
 apply plugin: 'kotlin-android'
 
 android {
+    // Conditional for compatibility with AGP <4.2.
+    if (project.android.hasProperty("namespace")) {
+        namespace 'io.flutter.plugins.cronet_http'
+    }
+
     compileSdkVersion 31
 
     compileOptions {
@@ -41,7 +46,11 @@
     }
 
     defaultConfig {
-        minSdkVersion 16
+        // api-level/minSdkVersion should be help in sync in:
+        // - .github/workflows/cronet.yml
+        // - pkgs/cronet_http/android/build.gradle
+        // - pkgs/cronet_http/example/android/app/build.gradle
+        minSdkVersion 28
     }
 
     defaultConfig {
diff --git a/pkgs/cronet_http/example/android/app/build.gradle b/pkgs/cronet_http/example/android/app/build.gradle
index 88b3356..1f7cd94 100644
--- a/pkgs/cronet_http/example/android/app/build.gradle
+++ b/pkgs/cronet_http/example/android/app/build.gradle
@@ -46,7 +46,11 @@
         applicationId "io.flutter.cronet_http_example"
         // You can update the following values to match your application needs.
         // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration.
-        minSdkVersion flutter.minSdkVersion
+        // api-level/minSdkVersion should be help in sync in:
+        // - .github/workflows/cronet.yml
+        // - pkgs/cronet_http/android/build.gradle
+        // - pkgs/cronet_http/example/android/app/build.gradle
+        minSdkVersion 28
         targetSdkVersion flutter.targetSdkVersion
         versionCode flutterVersionCode.toInteger()
         versionName flutterVersionName
diff --git a/pkgs/cronet_http/example/android/app/src/debug/AndroidManifest.xml b/pkgs/cronet_http/example/android/app/src/debug/AndroidManifest.xml
index b17be9f..6170951 100644
--- a/pkgs/cronet_http/example/android/app/src/debug/AndroidManifest.xml
+++ b/pkgs/cronet_http/example/android/app/src/debug/AndroidManifest.xml
@@ -1,4 +1,4 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.example.cronet_http_example">
+    package="io.flutter.cronet_http_example">
     <uses-permission android:name="android.permission.INTERNET"/>
 </manifest>
diff --git a/pkgs/cronet_http/example/android/app/src/main/AndroidManifest.xml b/pkgs/cronet_http/example/android/app/src/main/AndroidManifest.xml
index e8d5f3f..254760d 100644
--- a/pkgs/cronet_http/example/android/app/src/main/AndroidManifest.xml
+++ b/pkgs/cronet_http/example/android/app/src/main/AndroidManifest.xml
@@ -1,5 +1,5 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.example.cronet_http_example">
+    package="io.flutter.cronet_http_example">
     <uses-permission android:name="android.permission.INTERNET"/>
    <application
         android:label="cronet_http_example"
diff --git a/pkgs/cronet_http/example/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java b/pkgs/cronet_http/example/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java
index 90015fd..3772f02 100644
--- a/pkgs/cronet_http/example/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java
+++ b/pkgs/cronet_http/example/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java
@@ -16,14 +16,24 @@
   private static final String TAG = "GeneratedPluginRegistrant";
   public static void registerWith(@NonNull FlutterEngine flutterEngine) {
     try {
-      flutterEngine.getPlugins().add(new io.flutter.plugins.cronet_http.CronetHttpPlugin());
-    } catch(Exception e) {
-      Log.e(TAG, "Error registering plugin cronet_http, io.flutter.plugins.cronet_http.CronetHttpPlugin", e);
+      flutterEngine.getPlugins().add(new dev.flutter.plugins.integration_test.IntegrationTestPlugin());
+    } catch (Exception e) {
+      Log.e(TAG, "Error registering plugin integration_test, dev.flutter.plugins.integration_test.IntegrationTestPlugin", e);
     }
     try {
-      flutterEngine.getPlugins().add(new dev.flutter.plugins.integration_test.IntegrationTestPlugin());
-    } catch(Exception e) {
-      Log.e(TAG, "Error registering plugin integration_test, dev.flutter.plugins.integration_test.IntegrationTestPlugin", e);
+      flutterEngine.getPlugins().add(new com.github.dart_lang.jni.JniPlugin());
+    } catch (Exception e) {
+      Log.e(TAG, "Error registering plugin jni, com.github.dart_lang.jni.JniPlugin", e);
+    }
+    try {
+      flutterEngine.getPlugins().add(new io.flutter.plugins.pathprovider.PathProviderPlugin());
+    } catch (Exception e) {
+      Log.e(TAG, "Error registering plugin path_provider_android, io.flutter.plugins.pathprovider.PathProviderPlugin", e);
+    }
+    try {
+      flutterEngine.getPlugins().add(new com.tekartik.sqflite.SqflitePlugin());
+    } catch (Exception e) {
+      Log.e(TAG, "Error registering plugin sqflite, com.tekartik.sqflite.SqflitePlugin", e);
     }
   }
 }
diff --git a/pkgs/cronet_http/example/android/app/src/main/kotlin/com/example/cronet_http_example/MainActivity.kt b/pkgs/cronet_http/example/android/app/src/main/kotlin/io/flutter/cronet_http_example/MainActivity.kt
similarity index 70%
rename from pkgs/cronet_http/example/android/app/src/main/kotlin/com/example/cronet_http_example/MainActivity.kt
rename to pkgs/cronet_http/example/android/app/src/main/kotlin/io/flutter/cronet_http_example/MainActivity.kt
index 2688c93..97b07c8 100644
--- a/pkgs/cronet_http/example/android/app/src/main/kotlin/com/example/cronet_http_example/MainActivity.kt
+++ b/pkgs/cronet_http/example/android/app/src/main/kotlin/io/flutter/cronet_http_example/MainActivity.kt
@@ -1,4 +1,4 @@
-package com.example.cronet_http_example
+package io.flutter.cronet_http_example
 
 import io.flutter.embedding.android.FlutterActivity
 
diff --git a/pkgs/cronet_http/example/android/app/src/profile/AndroidManifest.xml b/pkgs/cronet_http/example/android/app/src/profile/AndroidManifest.xml
index b17be9f..6170951 100644
--- a/pkgs/cronet_http/example/android/app/src/profile/AndroidManifest.xml
+++ b/pkgs/cronet_http/example/android/app/src/profile/AndroidManifest.xml
@@ -1,4 +1,4 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.example.cronet_http_example">
+    package="io.flutter.cronet_http_example">
     <uses-permission android:name="android.permission.INTERNET"/>
 </manifest>
diff --git a/pkgs/cronet_http/example/android/build.gradle b/pkgs/cronet_http/example/android/build.gradle
index 83ae220..954fa1c 100644
--- a/pkgs/cronet_http/example/android/build.gradle
+++ b/pkgs/cronet_http/example/android/build.gradle
@@ -1,12 +1,12 @@
 buildscript {
-    ext.kotlin_version = '1.6.10'
+    ext.kotlin_version = '1.7.21'
     repositories {
         google()
         mavenCentral()
     }
 
     dependencies {
-        classpath 'com.android.tools.build:gradle:7.1.2'
+        classpath 'com.android.tools.build:gradle:7.4.2'
         classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
     }
 }
@@ -26,6 +26,6 @@
     project.evaluationDependsOn(':app')
 }
 
-task clean(type: Delete) {
+tasks.register("clean", Delete) {
     delete rootProject.buildDir
 }
diff --git a/pkgs/cronet_http/example/android/gradle/wrapper/gradle-wrapper.properties b/pkgs/cronet_http/example/android/gradle/wrapper/gradle-wrapper.properties
index cc5527d..cfe88f6 100644
--- a/pkgs/cronet_http/example/android/gradle/wrapper/gradle-wrapper.properties
+++ b/pkgs/cronet_http/example/android/gradle/wrapper/gradle-wrapper.properties
@@ -3,4 +3,4 @@
 distributionPath=wrapper/dists
 zipStoreBase=GRADLE_USER_HOME
 zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-all.zip
diff --git a/pkgs/cronet_http/example/pubspec.yaml b/pkgs/cronet_http/example/pubspec.yaml
index 568cef9..5bb8027 100644
--- a/pkgs/cronet_http/example/pubspec.yaml
+++ b/pkgs/cronet_http/example/pubspec.yaml
@@ -4,7 +4,7 @@
 publish_to: 'none'
 
 environment:
-  sdk: "^3.0.0"
+  sdk: ^3.0.0
 
 dependencies:
   cached_network_image: ^3.2.3
@@ -13,10 +13,10 @@
   cupertino_icons: ^1.0.2
   flutter:
     sdk: flutter
-  http: ^0.13.5
+  http: ^1.0.0
 
 dev_dependencies:
-  dart_flutter_team_lints: ^1.0.0
+  dart_flutter_team_lints: ^2.0.0
   flutter_test:
     sdk: flutter
   http_client_conformance_tests:
diff --git a/pkgs/cronet_http/lib/src/cronet_client.dart b/pkgs/cronet_http/lib/src/cronet_client.dart
index c4d0d19..272b602 100644
--- a/pkgs/cronet_http/lib/src/cronet_client.dart
+++ b/pkgs/cronet_http/lib/src/cronet_client.dart
@@ -317,7 +317,7 @@
       jb.UrlRequestCallbackProxy.new1(
           _urlRequestCallbacks(request, responseCompleter)),
       _executor,
-    );
+    )..setHttpMethod(request.method.toJString());
 
     var headers = request.headers;
     if (body.isNotEmpty &&
diff --git a/pkgs/cronet_http/pubspec.yaml b/pkgs/cronet_http/pubspec.yaml
index 82390c8..5f4229e 100644
--- a/pkgs/cronet_http/pubspec.yaml
+++ b/pkgs/cronet_http/pubspec.yaml
@@ -1,7 +1,7 @@
 name: cronet_http
-description: >
+version: 1.0.0
+description: >-
   An Android Flutter plugin that provides access to the Cronet HTTP client.
-version: 0.4.2
 repository: https://github.com/dart-lang/http/tree/master/pkgs/cronet_http
 
 environment:
@@ -15,7 +15,7 @@
   jni: ^0.7.2
 
 dev_dependencies:
-  dart_flutter_team_lints: ^1.0.0
+  dart_flutter_team_lints: ^2.0.0
   jnigen: ^0.7.0
   xml: ^6.1.0
   yaml_edit: ^2.0.3
@@ -25,4 +25,3 @@
     platforms:
       android:
         ffiPlugin: true
-
diff --git a/pkgs/cronet_http/tool/prepare_for_embedded.dart b/pkgs/cronet_http/tool/prepare_for_embedded.dart
index e0f99d7..3442bc6 100644
--- a/pkgs/cronet_http/tool/prepare_for_embedded.dart
+++ b/pkgs/cronet_http/tool/prepare_for_embedded.dart
@@ -13,6 +13,9 @@
 /// 1. Modifying the Gradle build file to reference the embedded Cronet.
 /// 2. Modifying the *name* and *description* in `pubspec.yaml`.
 /// 3. Replacing `README.md` with `README_EMBEDDED.md`.
+/// 4. Change the name of `cronet_http.dart` to `cronet_http_embedded.dart`.
+/// 5. Update all the imports from `package:cronet_http/cronet_http.dart` to
+///    `package:cronet_http_embedded/cronet_http_embedded.dart`
 ///
 /// After running this script, `flutter pub publish`
 /// can be run to update package:cronet_http_embedded.
@@ -40,7 +43,7 @@
   'android/maven2/org/chromium/net/group-index.xml',
 );
 
-void main() async {
+void main(List<String> args) async {
   if (Directory.current.path.endsWith('tool')) {
     _packageDirectory = Directory.current.parent;
   } else {
@@ -51,6 +54,8 @@
   updateCronetDependency(latestVersion);
   updatePubSpec();
   updateReadme();
+  updateLibraryName();
+  updateImports();
 }
 
 Future<String> _getLatestCronetVersion() async {
@@ -69,7 +74,7 @@
   return versions.last;
 }
 
-/// Update android/build.gradle
+/// Update android/build.gradle.
 void updateCronetDependency(String latestVersion) {
   final fBuildGradle = File('${_packageDirectory.path}/android/build.gradle');
   final gradleContent = fBuildGradle.readAsStringSync();
@@ -88,18 +93,48 @@
   fBuildGradle.writeAsStringSync(newGradleContent);
 }
 
-/// Update pubspec.yaml
+/// Update pubspec.yaml and example/pubspec.yaml.
 void updatePubSpec() {
+  print('Updating pubspec.yaml');
   final fPubspec = File('${_packageDirectory.path}/pubspec.yaml');
   final yamlEditor = YamlEditor(fPubspec.readAsStringSync())
     ..update(['name'], _packageName)
     ..update(['description'], _packageDescription);
   fPubspec.writeAsStringSync(yamlEditor.toString());
+  print('Updating example/pubspec.yaml');
+  final examplePubspec = File('${_packageDirectory.path}/example/pubspec.yaml');
+  final replaced = examplePubspec
+      .readAsStringSync()
+      .replaceAll('cronet_http:', 'cronet_http_embedded:');
+  examplePubspec.writeAsStringSync(replaced);
 }
 
-/// Move README_EMBEDDED.md to replace README.md
+/// Move README_EMBEDDED.md to replace README.md.
 void updateReadme() {
+  print('Updating README.md from README_EMBEDDED.md');
   File('${_packageDirectory.path}/README.md').deleteSync();
   File('${_packageDirectory.path}/README_EMBEDDED.md')
       .renameSync('${_packageDirectory.path}/README.md');
 }
+
+void updateImports() {
+  print('Updating imports in Dart files');
+  for (final file in _packageDirectory.listSync(recursive: true)) {
+    if (file is File && file.path.endsWith('.dart')) {
+      final updatedSource = file.readAsStringSync().replaceAll(
+            'package:cronet_http/cronet_http.dart',
+            'package:cronet_http_embedded/cronet_http_embedded.dart',
+          );
+      file.writeAsStringSync(updatedSource);
+    }
+  }
+}
+
+void updateLibraryName() {
+  print('Renaming cronet_http.dart to cronet_http_embedded.dart');
+  File(
+    '${_packageDirectory.path}/lib/cronet_http.dart',
+  ).renameSync(
+    '${_packageDirectory.path}/lib/cronet_http_embedded.dart',
+  );
+}
diff --git a/pkgs/cupertino_http/CHANGELOG.md b/pkgs/cupertino_http/CHANGELOG.md
index 3a69c49..d768f7a 100644
--- a/pkgs/cupertino_http/CHANGELOG.md
+++ b/pkgs/cupertino_http/CHANGELOG.md
@@ -1,3 +1,8 @@
+## 1.2.0
+
+* Add support for setting additional http headers in
+  `URLSessionConfiguration`.
+
 ## 1.1.0
 
 * Add websocket support to `cupertino_api`.
diff --git a/pkgs/cupertino_http/example/integration_test/client_test.dart b/pkgs/cupertino_http/example/integration_test/client_test.dart
index 9247783..1becd5c 100644
--- a/pkgs/cupertino_http/example/integration_test/client_test.dart
+++ b/pkgs/cupertino_http/example/integration_test/client_test.dart
@@ -2,6 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'dart:async';
 import 'dart:io';
 import 'dart:typed_data';
 
@@ -45,7 +46,7 @@
       }
       final request = StreamedRequest('POST', uri);
       request.sink.add(data);
-      request.sink.close();
+      unawaited(request.sink.close());
       await client.send(request);
       expect(serverHash, sha1.convert(data).bytes);
     });
diff --git a/pkgs/cupertino_http/example/integration_test/url_session_configuration_test.dart b/pkgs/cupertino_http/example/integration_test/url_session_configuration_test.dart
index 85386bc..ab117c3 100644
--- a/pkgs/cupertino_http/example/integration_test/url_session_configuration_test.dart
+++ b/pkgs/cupertino_http/example/integration_test/url_session_configuration_test.dart
@@ -2,10 +2,38 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'dart:io';
+
 import 'package:cupertino_http/cupertino_http.dart';
 import 'package:integration_test/integration_test.dart';
 import 'package:test/test.dart';
 
+/// Make a HTTP request using the given configuration and return the headers
+/// received by the server.
+Future<Map<String, List<String>>> sentHeaders(
+    URLSessionConfiguration config) async {
+  final session = URLSession.sessionWithConfiguration(config);
+  final headers = <String, List<String>>{};
+  final server = (await HttpServer.bind('localhost', 0))
+    ..listen((request) async {
+      request.headers.forEach((k, v) => headers[k] = v);
+      await request.drain<void>();
+      request.response.headers.set('Content-Type', 'text/plain');
+      request.response.write('Hello World');
+      await request.response.close();
+    });
+
+  final task = session.dataTaskWithRequest(URLRequest.fromUrl(
+      Uri(scheme: 'http', host: 'localhost', port: server.port)))
+    ..resume();
+  while (task.state != URLSessionTaskState.urlSessionTaskStateCompleted) {
+    await pumpEventQueue();
+  }
+
+  await server.close();
+  return headers;
+}
+
 void testProperties(URLSessionConfiguration config) {
   group('properties', () {
     test('allowsCellularAccess', () {
@@ -32,6 +60,22 @@
       config.discretionary = false;
       expect(config.discretionary, false);
     });
+    test('httpAdditionalHeaders', () async {
+      expect(config.httpAdditionalHeaders, isNull);
+
+      config.httpAdditionalHeaders = {
+        'User-Agent': 'My Client',
+        'MyHeader': 'myvalue'
+      };
+      expect(config.httpAdditionalHeaders,
+          {'User-Agent': 'My Client', 'MyHeader': 'myvalue'});
+      final headers = await sentHeaders(config);
+      expect(headers, containsPair('user-agent', ['My Client']));
+      expect(headers, containsPair('myheader', ['myvalue']));
+
+      config.httpAdditionalHeaders = null;
+      expect(config.httpAdditionalHeaders, isNull);
+    });
     test('httpCookieAcceptPolicy', () {
       config.httpCookieAcceptPolicy =
           HTTPCookieAcceptPolicy.httpCookieAcceptPolicyAlways;
diff --git a/pkgs/cupertino_http/example/lib/main.dart b/pkgs/cupertino_http/example/lib/main.dart
index edfceac..32c2b08 100644
--- a/pkgs/cupertino_http/example/lib/main.dart
+++ b/pkgs/cupertino_http/example/lib/main.dart
@@ -15,7 +15,10 @@
 void main() {
   var clientFactory = Client.new; // The default Client.
   if (Platform.isIOS || Platform.isMacOS) {
-    clientFactory = CupertinoClient.defaultSessionConfiguration.call;
+    final config = URLSessionConfiguration.ephemeralSessionConfiguration()
+      ..cache = URLCache.withCapacity(memoryCapacity: 2 * 1024 * 1024)
+      ..httpAdditionalHeaders = {'User-Agent': 'Book Agent'};
+    clientFactory = () => CupertinoClient.fromSessionConfiguration(config);
   }
   runWithClient(() => runApp(const BookSearchApp()), clientFactory);
 }
diff --git a/pkgs/cupertino_http/example/pubspec.yaml b/pkgs/cupertino_http/example/pubspec.yaml
index be72731..bae184b 100644
--- a/pkgs/cupertino_http/example/pubspec.yaml
+++ b/pkgs/cupertino_http/example/pubspec.yaml
@@ -16,12 +16,12 @@
   cupertino_icons: ^1.0.2
   flutter:
     sdk: flutter
-  http: ^0.13.5
+  http: ^1.0.0
 
 dev_dependencies:
   convert: ^3.1.1
   crypto: ^3.0.3
-  dart_flutter_team_lints: ^1.0.0
+  dart_flutter_team_lints: ^2.0.0
   ffi: ^2.0.1
   flutter_test:
     sdk: flutter
diff --git a/pkgs/cupertino_http/lib/src/cupertino_api.dart b/pkgs/cupertino_http/lib/src/cupertino_api.dart
index 01c4853..5cebd7e 100644
--- a/pkgs/cupertino_http/lib/src/cupertino_api.dart
+++ b/pkgs/cupertino_http/lib/src/cupertino_api.dart
@@ -344,6 +344,32 @@
   bool get discretionary => _nsObject.discretionary;
   set discretionary(bool value) => _nsObject.discretionary = value;
 
+  /// Additional headers to send with each request.
+  ///
+  /// Note that the getter for this field returns a **copy** of the headers.
+  ///
+  /// See [NSURLSessionConfiguration.HTTPAdditionalHeaders](https://developer.apple.com/documentation/foundation/nsurlsessionconfiguration/1411532-httpadditionalheaders)
+  Map<String, String>? get httpAdditionalHeaders {
+    if (_nsObject.HTTPAdditionalHeaders case var additionalHeaders?) {
+      final headers = ncb.NSDictionary.castFrom(additionalHeaders);
+      return stringDictToMap(headers);
+    }
+    return null;
+  }
+
+  set httpAdditionalHeaders(Map<String, String>? headers) {
+    if (headers == null) {
+      _nsObject.HTTPAdditionalHeaders = null;
+      return;
+    }
+    final d = ncb.NSMutableDictionary.alloc(linkedLibs).init();
+    headers.forEach((key, value) {
+      d.setObject_forKey_(
+          value.toNSString(linkedLibs), key.toNSString(linkedLibs));
+    });
+    _nsObject.HTTPAdditionalHeaders = d;
+  }
+
   /// What policy to use when deciding whether to accept cookies.
   ///
   /// See [NSURLSessionConfiguration.HTTPCookieAcceptPolicy](https://developer.apple.com/documentation/foundation/nsurlsessionconfiguration/1408933-httpcookieacceptpolicy).
@@ -441,6 +467,7 @@
       'allowsConstrainedNetworkAccess=$allowsConstrainedNetworkAccess '
       'allowsExpensiveNetworkAccess=$allowsExpensiveNetworkAccess '
       'discretionary=$discretionary '
+      'httpAdditionalHeaders=$httpAdditionalHeaders '
       'httpCookieAcceptPolicy=$httpCookieAcceptPolicy '
       'httpShouldSetCookies=$httpShouldSetCookies '
       'httpMaximumConnectionsPerHost=$httpMaximumConnectionsPerHost '
diff --git a/pkgs/cupertino_http/pubspec.yaml b/pkgs/cupertino_http/pubspec.yaml
index 9d639a8..0a97bdd 100644
--- a/pkgs/cupertino_http/pubspec.yaml
+++ b/pkgs/cupertino_http/pubspec.yaml
@@ -1,8 +1,8 @@
 name: cupertino_http
-description: >
+version: 1.2.0
+description: >-
   A macOS/iOS Flutter plugin that provides access to the Foundation URL
   Loading System.
-version: 1.1.0
 repository: https://github.com/dart-lang/http/tree/master/pkgs/cupertino_http
 
 environment:
@@ -17,7 +17,7 @@
   http: '>=0.13.4 <2.0.0'
 
 dev_dependencies:
-  dart_flutter_team_lints: ^1.0.0
+  dart_flutter_team_lints: ^2.0.0
   ffigen: ^9.0.1
 
 flutter:
diff --git a/pkgs/flutter_http_example/lib/main.dart b/pkgs/flutter_http_example/lib/main.dart
index 70f003c..406b9e6 100644
--- a/pkgs/flutter_http_example/lib/main.dart
+++ b/pkgs/flutter_http_example/lib/main.dart
@@ -11,7 +11,7 @@
 
 import 'book.dart';
 import 'http_client_factory.dart'
-    if (dart.library.html) 'http_client_factory_web.dart' as http_factory;
+    if (dart.library.js_interop) 'http_client_factory_web.dart' as http_factory;
 
 void main() {
   // `runWithClient` is used to control which `package:http` `Client` is used
diff --git a/pkgs/flutter_http_example/pubspec.yaml b/pkgs/flutter_http_example/pubspec.yaml
index 6f3d1ba..0331490 100644
--- a/pkgs/flutter_http_example/pubspec.yaml
+++ b/pkgs/flutter_http_example/pubspec.yaml
@@ -1,10 +1,9 @@
 name: flutter_http_example
+version: 1.0.0
 description: Demonstrates how to use package:http in a Flutter app.
 
 publish_to: 'none'
 
-version: 1.0.0
-
 environment:
   sdk: ^3.0.0
   flutter: '>=3.10.0'
@@ -17,11 +16,11 @@
   fetch_client: ^1.0.2
   flutter:
     sdk: flutter
-  http: ^0.13.5
+  http: ^1.0.0
   provider: ^6.0.5
 
 dev_dependencies:
-  dart_flutter_team_lints: ^1.0.0
+  dart_flutter_team_lints: ^2.0.0
   flutter_test:
     sdk: flutter
   integration_test:
diff --git a/pkgs/http/CHANGELOG.md b/pkgs/http/CHANGELOG.md
index 6d39b10..7b8dec4 100644
--- a/pkgs/http/CHANGELOG.md
+++ b/pkgs/http/CHANGELOG.md
@@ -1,8 +1,18 @@
+## 1.1.3-wip
+
+* Add `MockClient.pngResponse`, which makes it easier to fake image responses.
+
+## 1.1.2
+
+* Allow `web: '>=0.3.0 <0.5.0'`.
+
 ## 1.1.1
 
 * `BrowserClient` throws `ClientException` when the `'Content-Length'` header
   is invalid.
 * `IOClient` trims trailing whitespace on header values.
+* Require Dart 3.2
+* Browser: support Wasm by using `package:web`.
 
 ## 1.1.0
 
diff --git a/pkgs/http/README.md b/pkgs/http/README.md
index c889f2b..642c238 100644
--- a/pkgs/http/README.md
+++ b/pkgs/http/README.md
@@ -4,8 +4,8 @@
 A composable, Future-based library for making HTTP requests.
 
 This package contains a set of high-level functions and classes that make it
-easy to consume HTTP resources. It's multi-platform, and supports mobile, desktop,
-and the browser.
+easy to consume HTTP resources. It's multi-platform (mobile, desktop, and
+browser) and supports multiple implementations.
 
 ## Using
 
@@ -23,6 +23,11 @@
 print(await http.read(Uri.https('example.com', 'foobar.txt')));
 ```
 
+> [!NOTE]
+> Flutter applications may require
+> [additional configuration](https://docs.flutter.dev/data-and-backend/networking#platform-notes)
+> to make HTTP requests.
+
 If you're making multiple requests to the same server, you can keep open a
 persistent connection by using a [Client][] rather than making one-off requests.
 If you do this, make sure to close the client when you're done:
@@ -41,6 +46,12 @@
 }
 ```
 
+> [!TIP]
+> For detailed background information and practical usage examples, see:
+> - [Dart Development: Fetch data from the internet](https://dart.dev/tutorials/server/fetch-data)
+> - [Flutter Cookbook: Fetch data from the internet](https://docs.flutter.dev/cookbook/networking/fetch-data)
+> - [The Flutter HTTP example application][flutterhttpexample]
+
 You can also exert more fine-grained control over your requests and responses by
 creating [Request][] or [StreamedRequest][] objects yourself and passing them to
 [Client.send][].
@@ -100,3 +111,181 @@
 the [`RetryClient()`][new RetryClient] constructor.
 
 [new RetryClient]: https://pub.dev/documentation/http/latest/retry/RetryClient/RetryClient.html
+
+## Choosing an implementation
+
+There are multiple implementations of the `package:http` [`Client`][client] interface. By default, `package:http` uses [`BrowserClient`][browserclient] on the web and [`IOClient`][ioclient] on all other platforms. You an choose a different [`Client`][client] implementation based on the needs of your application.
+
+You can change implementations without changing your application code, except
+for a few lines of [configuration](#2-configure-the-http-client).
+
+Some well supported implementations are:
+
+| Implementation | Supported Platforms | SDK | Caching | HTTP3/QUIC | Platform Native | 
+| -------------- | ------------------- | ----| ------- | ---------- | --------------- |
+| `package:http` — [`IOClient`][ioclient] | Android, iOS, Linux, macOS, Windows | Dart, Flutter | ❌ | ❌ | ❌ |
+| `package:http` — [`BrowserClient`][browserclient] | Web | Dart, Flutter | ― | ✅︎ | ✅︎ | Dart, Flutter |
+| [`package:cupertino_http`][cupertinohttp] — [`CupertinoClient`][cupertinoclient] | iOS, macOS | Flutter | ✅︎ | ✅︎ | ✅︎ |
+| [`package:cronet_http`][cronethttp] — [`CronetClient`][cronetclient] | Android | Flutter | ✅︎ | ✅︎ | ― |
+| [`package:fetch_client`][fetch] — [`FetchClient`][fetchclient] | Web | Dart, Flutter | ✅︎ | ✅︎ | ✅︎ |
+
+> [!TIP]
+> If you are writing a Dart package or Flutter pluggin that uses
+> `package:http`, you should not depend on a particular [`Client`][client]
+> implementation. Let the application author decide what implementation is
+> best for their project. You can make that easier by accepting an explicit
+> [`Client`][client] argument. For example:
+>
+> ```dart
+> Future<Album> fetchAlbum({Client? client}) async {
+>   client ??= Client();
+>   ...
+> }
+> ```
+
+## Configuration
+
+To use a HTTP client implementation other than the default, you must:
+1. Add the HTTP client as a dependency.
+2. Configure the HTTP client.
+3. Connect the HTTP client to the code that uses it.
+
+### 1. Add the HTTP client as a dependency.
+
+To add a package compatible with the Dart SDK to your project, use `dart pub add`.
+
+For example:
+
+```terminal
+# Replace  "fetch_client" with the package that you want to use.
+dart pub add fetch_client
+```
+
+To add a package that requires the Flutter SDK, use `flutter pub add`.
+
+For example:
+
+```terminal
+# Replace  "cupertino_http" with the package that you want to use.
+flutter pub add cupertino_http
+```
+
+### 2. Configure the HTTP client.
+
+Different `package:http` [`Client`][client] implementations may require
+different configuration options.
+
+Add a function that returns a correctly configured [`Client`][client]. You can
+return a different [`Client`][client] on different platforms.
+
+For example:
+
+```dart
+Client httpClient() {
+  if (Platform.isAndroid) {
+    final engine = CronetEngine.build(
+        cacheMode: CacheMode.memory,
+        cacheMaxSize: 1000000);
+    return CronetClient.fromCronetEngine(engine);
+  }
+  if (Platform.isIOS || Platform.isMacOS) {
+    final config = URLSessionConfiguration.ephemeralSessionConfiguration()
+      ..cache = URLCache.withCapacity(memoryCapacity: 1000000);
+    return CupertinoClient.fromSessionConfiguration(config);
+  }
+  return IOClient();
+}
+```
+
+> [!TIP]
+> [The Flutter HTTP example application][flutterhttpexample] demonstrates
+> configuration best practices.
+
+#### Supporting browser and native
+
+If your application can be run in the browser and natively, you must put your
+browser and native configurations in seperate files and import the correct file
+based on the platform.
+
+For example:
+
+```dart
+// -- http_client_factory.dart
+Client httpClient() {
+  if (Platform.isAndroid) {
+    return CronetClient.defaultCronetEngine();
+  }
+  if (Platform.isIOS || Platform.isMacOS) {
+    return CupertinoClient.defaultSessionConfiguration();
+  }
+  return IOClient();
+}
+```
+
+```dart
+// -- http_client_factory_web.dart
+Client httpClient() => FetchClient();
+```
+
+```dart
+// -- main.dart
+import 'http_client_factory.dart'
+    if (dart.library.js_interop) 'http_client_factory_web.dart'
+
+// The correct `httpClient` will be available.
+```
+
+### 3. Connect the HTTP client to the code that uses it.
+
+The best way to pass [`Client`][client] to the places that use it is
+explicitly through arguments.
+
+For example:
+
+```dart
+void main() {
+  final client = httpClient();
+  fetchAlbum(client, ...);
+}
+```
+
+In Flutter, you can use a one of many
+[state mangement approaches][flutterstatemanagement].
+
+If you depend on code that uses top-level functions (e.g. `http.post`) or
+calls the [`Client()`][clientconstructor] constructor, then you can use
+[`runWithClient`](runwithclient) to ensure that the correct
+`Client` is used. When an [Isolate][isolate] is spawned, it does not inherit
+any variables from the calling Zone, so `runWithClient` needs to be used in
+each Isolate that uses `package:http`.
+
+You can ensure that only the `Client` that you have explicitly configured is
+used by defining `no_default_http_client=true` in the environment. This will
+also allow the default `Client` implementation to be removed, resulting in
+a reduced application size.
+
+```terminal
+$ flutter build appbundle --dart-define=no_default_http_client=true ...
+$ dart compile exe --define=no_default_http_client=true ...
+```
+
+> [!TIP]
+> [The Flutter HTTP example application][flutterhttpexample] demonstrates
+> how to make the configured [`Client`][client] available using
+> [`package:provider`][provider] and [`runWithClient`](runwithclient).
+
+[browserclient]: https://pub.dev/documentation/http/latest/browser_client/BrowserClient-class.html
+[client]: https://pub.dev/documentation/http/latest/http/Client-class.html
+[clientconstructor]: https://pub.dev/documentation/http/latest/http/Client/Client.html
+[cupertinohttp]: https://pub.dev/packages/cupertino_http
+[cupertinoclient]: https://pub.dev/documentation/cupertino_http/latest/cupertino_http/CupertinoClient-class.html
+[cronethttp]: https://pub.dev/packages/cronet_http
+[cronetclient]: https://pub.dev/documentation/cronet_http/latest/cronet_http/CronetClient-class.html
+[fetch]: https://pub.dev/packages/fetch_client
+[fetchclient]: https://pub.dev/documentation/fetch_client/latest/fetch_client/FetchClient-class.html
+[flutterhttpexample]: https://github.com/dart-lang/http/tree/master/pkgs/flutter_http_example
+[ioclient]: https://pub.dev/documentation/http/latest/io_client/IOClient-class.html
+[isolate]: https://dart.dev/language/concurrency#how-isolates-work
+[flutterstatemanagement]: https://docs.flutter.dev/data-and-backend/state-mgmt/options
+[provider]: https://pub.dev/packages/provider
+[runwithclient]: https://pub.dev/documentation/http/latest/http/runWithClient.html
diff --git a/pkgs/http/lib/src/browser_client.dart b/pkgs/http/lib/src/browser_client.dart
index 9345be0..80db8b1 100644
--- a/pkgs/http/lib/src/browser_client.dart
+++ b/pkgs/http/lib/src/browser_client.dart
@@ -3,8 +3,9 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'dart:async';
-import 'dart:html';
-import 'dart:typed_data';
+import 'dart:js_interop';
+
+import 'package:web/helpers.dart';
 
 import 'base_client.dart';
 import 'base_request.dart';
@@ -25,8 +26,8 @@
   return BrowserClient();
 }
 
-/// A `dart:html`-based HTTP client that runs in the browser and is backed by
-/// XMLHttpRequests.
+/// A `package:web`-based HTTP client that runs in the browser and is backed by
+/// [XMLHttpRequest].
 ///
 /// This client inherits some of the limitations of XMLHttpRequest. It ignores
 /// the [BaseRequest.contentLength], [BaseRequest.persistentConnection],
@@ -37,7 +38,7 @@
   /// The currently active XHRs.
   ///
   /// These are aborted if the client is closed.
-  final _xhrs = <HttpRequest>{};
+  final _xhrs = <XMLHttpRequest>{};
 
   /// Whether to send credentials such as cookies or authorization headers for
   /// cross-site requests.
@@ -55,28 +56,31 @@
           'HTTP request failed. Client is already closed.', request.url);
     }
     var bytes = await request.finalize().toBytes();
-    var xhr = HttpRequest();
+    var xhr = XMLHttpRequest();
     _xhrs.add(xhr);
     xhr
-      ..open(request.method, '${request.url}', async: true)
+      ..open(request.method, '${request.url}', true)
       ..responseType = 'arraybuffer'
       ..withCredentials = withCredentials;
-    request.headers.forEach(xhr.setRequestHeader);
+    for (var header in request.headers.entries) {
+      xhr.setRequestHeader(header.key, header.value);
+    }
 
     var completer = Completer<StreamedResponse>();
 
     unawaited(xhr.onLoad.first.then((_) {
-      if (xhr.responseHeaders['content-length'] case final contentLengthHeader?
-          when !_digitRegex.hasMatch(contentLengthHeader)) {
+      if (xhr.responseHeaders['content-length'] case final contentLengthHeader
+          when contentLengthHeader != null &&
+              !_digitRegex.hasMatch(contentLengthHeader)) {
         completer.completeError(ClientException(
           'Invalid content-length header [$contentLengthHeader].',
           request.url,
         ));
         return;
       }
-      var body = (xhr.response as ByteBuffer).asUint8List();
+      var body = (xhr.response as JSArrayBuffer).toDart.asUint8List();
       completer.complete(StreamedResponse(
-          ByteStream.fromBytes(body), xhr.status!,
+          ByteStream.fromBytes(body), xhr.status,
           contentLength: body.length,
           request: request,
           headers: xhr.responseHeaders,
@@ -91,7 +95,7 @@
           StackTrace.current);
     }));
 
-    xhr.send(bytes);
+    xhr.send(bytes.toJS);
 
     try {
       return await completer.future;
@@ -112,3 +116,30 @@
     _xhrs.clear();
   }
 }
+
+extension on XMLHttpRequest {
+  Map<String, String> get responseHeaders {
+    // from Closure's goog.net.Xhrio.getResponseHeaders.
+    var headers = <String, String>{};
+    var headersString = getAllResponseHeaders();
+    var headersList = headersString.split('\r\n');
+    for (var header in headersList) {
+      if (header.isEmpty) {
+        continue;
+      }
+
+      var splitIdx = header.indexOf(': ');
+      if (splitIdx == -1) {
+        continue;
+      }
+      var key = header.substring(0, splitIdx).toLowerCase();
+      var value = header.substring(splitIdx + 2);
+      if (headers.containsKey(key)) {
+        headers[key] = '${headers[key]}, $value';
+      } else {
+        headers[key] = value;
+      }
+    }
+    return headers;
+  }
+}
diff --git a/pkgs/http/lib/src/client.dart b/pkgs/http/lib/src/client.dart
index 9bceb88..7429ca8 100644
--- a/pkgs/http/lib/src/client.dart
+++ b/pkgs/http/lib/src/client.dart
@@ -12,7 +12,7 @@
 import 'base_client.dart';
 import 'base_request.dart';
 import 'client_stub.dart'
-    if (dart.library.html) 'browser_client.dart'
+    if (dart.library.js_interop) 'browser_client.dart'
     if (dart.library.io) 'io_client.dart';
 import 'exception.dart';
 import 'response.dart';
@@ -37,7 +37,8 @@
   /// Creates a new platform appropriate client.
   ///
   /// Creates an `IOClient` if `dart:io` is available and a `BrowserClient` if
-  /// `dart:html` is available, otherwise it will throw an unsupported error.
+  /// `dart:js_interop` is available, otherwise it will throw an unsupported
+  /// error.
   factory Client() => zoneClient ?? createClient();
 
   /// Sends an HTTP HEAD request with the given headers to the given URL.
diff --git a/pkgs/http/lib/src/client_stub.dart b/pkgs/http/lib/src/client_stub.dart
index 1a34d50..6384fd0 100644
--- a/pkgs/http/lib/src/client_stub.dart
+++ b/pkgs/http/lib/src/client_stub.dart
@@ -6,4 +6,4 @@
 
 /// Implemented in `browser_client.dart` and `io_client.dart`.
 BaseClient createClient() => throw UnsupportedError(
-    'Cannot create a client without dart:html or dart:io.');
+    'Cannot create a client without dart:js_interop or dart:io.');
diff --git a/pkgs/http/lib/src/io_client.dart b/pkgs/http/lib/src/io_client.dart
index 247cc8c..db66b02 100644
--- a/pkgs/http/lib/src/io_client.dart
+++ b/pkgs/http/lib/src/io_client.dart
@@ -72,6 +72,18 @@
   /// The underlying `dart:io` HTTP client.
   HttpClient? _inner;
 
+  /// Create a new `dart:io`-based HTTP [Client].
+  ///
+  /// If [inner] is provided then it can be used to provide configuration
+  /// options for the client.
+  ///
+  /// For example:
+  /// ```dart
+  /// final httpClient = HttpClient()
+  ///    ..userAgent = 'Book Agent'
+  ///    ..idleTimeout = const Duration(seconds: 5);
+  /// final client = IOClient(httpClient);
+  /// ```
   IOClient([HttpClient? inner]) : _inner = inner ?? HttpClient();
 
   /// Sends an HTTP request and asynchronously returns the response.
diff --git a/pkgs/http/lib/src/mock_client.dart b/pkgs/http/lib/src/mock_client.dart
index bf2df40..52f108a 100644
--- a/pkgs/http/lib/src/mock_client.dart
+++ b/pkgs/http/lib/src/mock_client.dart
@@ -2,6 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'dart:convert';
+
 import 'base_client.dart';
 import 'base_request.dart';
 import 'byte_stream.dart';
@@ -10,6 +12,11 @@
 import 'streamed_request.dart';
 import 'streamed_response.dart';
 
+final _pngImageData = base64Decode(
+  'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDw'
+  'AEhQGAhKmMIQAAAABJRU5ErkJggg==',
+);
+
 // TODO(nweiz): once Dart has some sort of Rack- or WSGI-like standard for
 // server APIs, MockClient should conform to it.
 
@@ -69,6 +76,17 @@
     var bodyStream = request.finalize();
     return await _handler(request, bodyStream);
   }
+
+  /// Return a response containing a PNG image.
+  static Response pngResponse({BaseRequest? request}) {
+    final headers = {
+      'content-type': 'image/png',
+      'content-length': '${_pngImageData.length}'
+    };
+
+    return Response.bytes(_pngImageData, 200,
+        request: request, headers: headers, reasonPhrase: 'OK');
+  }
 }
 
 /// A handler function that receives [StreamedRequest]s and sends
diff --git a/pkgs/http/mono_pkg.yaml b/pkgs/http/mono_pkg.yaml
index 0e2f9d8..06f79d9 100644
--- a/pkgs/http/mono_pkg.yaml
+++ b/pkgs/http/mono_pkg.yaml
@@ -18,3 +18,5 @@
   - command: dart run --define=no_default_http_client=true test/no_default_http_client_test.dart
     os:
     - linux
+  - test: --test-randomize-ordering-seed=random -p chrome -c dart2wasm
+    sdk: dev
diff --git a/pkgs/http/pubspec.yaml b/pkgs/http/pubspec.yaml
index ec23e2d..1645f96 100644
--- a/pkgs/http/pubspec.yaml
+++ b/pkgs/http/pubspec.yaml
@@ -1,18 +1,19 @@
 name: http
-version: 1.1.1-wip
+version: 1.1.3-wip
 description: A composable, multi-platform, Future-based API for HTTP requests.
 repository: https://github.com/dart-lang/http/tree/master/pkgs/http
 
 environment:
-  sdk: ^3.0.0
+  sdk: ^3.2.0
 
 dependencies:
   async: ^2.5.0
   http_parser: ^4.0.0
   meta: ^1.3.0
+  web: '>=0.3.0 <0.5.0'
 
 dev_dependencies:
-  dart_flutter_team_lints: ^1.0.0
+  dart_flutter_team_lints: ^2.0.0
   fake_async: ^1.2.0
   http_client_conformance_tests:
     path: ../http_client_conformance_tests/
diff --git a/pkgs/http/test/html/utils.dart b/pkgs/http/test/html/utils.dart
index abe5808..501c621 100644
--- a/pkgs/http/test/html/utils.dart
+++ b/pkgs/http/test/html/utils.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'dart:html';
+import 'package:web/helpers.dart';
 
 export '../utils.dart';
 
diff --git a/pkgs/http/test/io/client_conformance_test.dart b/pkgs/http/test/io/client_conformance_test.dart
index 5d8f7f5..20bf39f 100644
--- a/pkgs/http/test/io/client_conformance_test.dart
+++ b/pkgs/http/test/io/client_conformance_test.dart
@@ -10,5 +10,6 @@
 import 'package:test/test.dart';
 
 void main() {
-  testAll(IOClient.new);
+  testAll(IOClient.new, preservesMethodCase: false // https://dartbug.com/54187
+      );
 }
diff --git a/pkgs/http/test/mock_client_test.dart b/pkgs/http/test/mock_client_test.dart
index db561c5..625285c 100644
--- a/pkgs/http/test/mock_client_test.dart
+++ b/pkgs/http/test/mock_client_test.dart
@@ -5,6 +5,7 @@
 import 'dart:convert';
 
 import 'package:http/http.dart' as http;
+import 'package:http/src/request.dart';
 import 'package:http/testing.dart';
 import 'package:test/test.dart';
 
@@ -43,4 +44,25 @@
     expect(await client.read(Uri.http('example.com', '/foo')),
         equals('you did it'));
   });
+
+  test('pngResponse with default options', () {
+    final response = MockClient.pngResponse();
+    expect(response.statusCode, 200);
+    expect(response.bodyBytes.take(8),
+        [137, 80, 78, 71, 13, 10, 26, 10] // PNG header
+        );
+    expect(response.request, null);
+    expect(response.headers, containsPair('content-type', 'image/png'));
+  });
+
+  test('pngResponse with request', () {
+    final request = Request('GET', Uri.https('example.com'));
+    final response = MockClient.pngResponse(request: request);
+    expect(response.statusCode, 200);
+    expect(response.bodyBytes.take(8),
+        [137, 80, 78, 71, 13, 10, 26, 10] // PNG header
+        );
+    expect(response.request, request);
+    expect(response.headers, containsPair('content-type', 'image/png'));
+  });
 }
diff --git a/pkgs/http_client_conformance_tests/bin/generate_server_wrappers.dart b/pkgs/http_client_conformance_tests/bin/generate_server_wrappers.dart
index 74f9d00..6e86737 100644
--- a/pkgs/http_client_conformance_tests/bin/generate_server_wrappers.dart
+++ b/pkgs/http_client_conformance_tests/bin/generate_server_wrappers.dart
@@ -10,12 +10,17 @@
 
 import 'package:dart_style/dart_style.dart';
 
-const vm = '''// Generated by generate_server_wrappers.dart. Do not edit.
+const _export = '''export 'server_queue_helpers.dart'
+    show StreamQueueOfNullableObjectExtension;''';
+
+const _vm = '''// Generated by generate_server_wrappers.dart. Do not edit.
 
 import 'package:stream_channel/stream_channel.dart';
 
 import '<server_file_placeholder>';
 
+$_export
+
 /// Starts the redirect test HTTP server in the same process.
 Future<StreamChannel<Object?>> startServer() async {
   final controller = StreamChannelController<Object?>(sync: true);
@@ -24,11 +29,13 @@
 }
 ''';
 
-const web = '''// Generated by generate_server_wrappers.dart. Do not edit.
+const _web = '''// Generated by generate_server_wrappers.dart. Do not edit.
 
 import 'package:stream_channel/stream_channel.dart';
 import 'package:test/test.dart';
 
+$_export
+
 /// Starts the redirect test HTTP server out-of-process.
 Future<StreamChannel<Object?>> startServer() async => spawnHybridUri(Uri(
     scheme: 'package',
@@ -41,11 +48,11 @@
 
   files.where((file) => file.path.endsWith('_server.dart')).forEach((file) {
     final vmPath = file.path.replaceAll('_server.dart', '_server_vm.dart');
-    File(vmPath).writeAsStringSync(formatter.format(vm.replaceAll(
+    File(vmPath).writeAsStringSync(formatter.format(_vm.replaceAll(
         '<server_file_placeholder>', file.uri.pathSegments.last)));
 
     final webPath = file.path.replaceAll('_server.dart', '_server_web.dart');
-    File(webPath).writeAsStringSync(formatter.format(web.replaceAll(
+    File(webPath).writeAsStringSync(formatter.format(_web.replaceAll(
         '<server_file_placeholder>', file.uri.pathSegments.last)));
   });
 }
diff --git a/pkgs/http_client_conformance_tests/lib/http_client_conformance_tests.dart b/pkgs/http_client_conformance_tests/lib/http_client_conformance_tests.dart
index 3d00319..bd83c02 100644
--- a/pkgs/http_client_conformance_tests/lib/http_client_conformance_tests.dart
+++ b/pkgs/http_client_conformance_tests/lib/http_client_conformance_tests.dart
@@ -12,6 +12,7 @@
 import 'src/request_body_streamed_tests.dart';
 import 'src/request_body_tests.dart';
 import 'src/request_headers_tests.dart';
+import 'src/request_methods_tests.dart';
 import 'src/response_body_streamed_test.dart';
 import 'src/response_body_tests.dart';
 import 'src/response_headers_tests.dart';
@@ -27,6 +28,7 @@
 export 'src/request_body_streamed_tests.dart' show testRequestBodyStreamed;
 export 'src/request_body_tests.dart' show testRequestBody;
 export 'src/request_headers_tests.dart' show testRequestHeaders;
+export 'src/request_methods_tests.dart' show testRequestMethods;
 export 'src/response_body_streamed_test.dart' show testResponseBodyStreamed;
 export 'src/response_body_tests.dart' show testResponseBody;
 export 'src/response_headers_tests.dart' show testResponseHeaders;
@@ -49,14 +51,20 @@
 /// If [canWorkInIsolates] is `false` then tests that require that the [Client]
 /// work in Isolates other than the main isolate will be skipped.
 ///
+/// If [preservesMethodCase] is `false` then tests that assume that the
+/// [Client] preserves custom request method casing will be skipped.
+///
 /// The tests are run against a series of HTTP servers that are started by the
 /// tests. If the tests are run in the browser, then the test servers are
 /// started in another process. Otherwise, the test servers are run in-process.
-void testAll(Client Function() clientFactory,
-    {bool canStreamRequestBody = true,
-    bool canStreamResponseBody = true,
-    bool redirectAlwaysAllowed = false,
-    bool canWorkInIsolates = true}) {
+void testAll(
+  Client Function() clientFactory, {
+  bool canStreamRequestBody = true,
+  bool canStreamResponseBody = true,
+  bool redirectAlwaysAllowed = false,
+  bool canWorkInIsolates = true,
+  bool preservesMethodCase = false,
+}) {
   testRequestBody(clientFactory());
   testRequestBodyStreamed(clientFactory(),
       canStreamRequestBody: canStreamRequestBody);
@@ -65,6 +73,7 @@
   testResponseBodyStreamed(clientFactory(),
       canStreamResponseBody: canStreamResponseBody);
   testRequestHeaders(clientFactory());
+  testRequestMethods(clientFactory(), preservesMethodCase: preservesMethodCase);
   testResponseHeaders(clientFactory());
   testResponseStatusLine(clientFactory());
   testRedirect(clientFactory(), redirectAlwaysAllowed: redirectAlwaysAllowed);
diff --git a/pkgs/http_client_conformance_tests/lib/src/close_tests.dart b/pkgs/http_client_conformance_tests/lib/src/close_tests.dart
index 040b338..39324ad 100644
--- a/pkgs/http_client_conformance_tests/lib/src/close_tests.dart
+++ b/pkgs/http_client_conformance_tests/lib/src/close_tests.dart
@@ -8,7 +8,7 @@
 import 'package:test/test.dart';
 
 import 'request_body_server_vm.dart'
-    if (dart.library.html) 'request_body_server_web.dart';
+    if (dart.library.js_interop) 'request_body_server_web.dart';
 
 /// Tests that the [Client] correctly implements [Client.close].
 void testClose(Client Function() clientFactory) {
@@ -20,7 +20,7 @@
     setUpAll(() async {
       httpServerChannel = await startServer();
       httpServerQueue = StreamQueue(httpServerChannel.stream);
-      host = 'localhost:${await httpServerQueue.next}';
+      host = 'localhost:${await httpServerQueue.nextAsInt}';
     });
     tearDownAll(() => httpServerChannel.sink.add(null));
 
diff --git a/pkgs/http_client_conformance_tests/lib/src/compressed_response_body_server_vm.dart b/pkgs/http_client_conformance_tests/lib/src/compressed_response_body_server_vm.dart
index 2bb2c16..a5ae1e0 100644
--- a/pkgs/http_client_conformance_tests/lib/src/compressed_response_body_server_vm.dart
+++ b/pkgs/http_client_conformance_tests/lib/src/compressed_response_body_server_vm.dart
@@ -4,6 +4,8 @@
 
 import 'compressed_response_body_server.dart';
 
+export 'server_queue_helpers.dart' show StreamQueueOfNullableObjectExtension;
+
 /// Starts the redirect test HTTP server in the same process.
 Future<StreamChannel<Object?>> startServer() async {
   final controller = StreamChannelController<Object?>(sync: true);
diff --git a/pkgs/http_client_conformance_tests/lib/src/compressed_response_body_server_web.dart b/pkgs/http_client_conformance_tests/lib/src/compressed_response_body_server_web.dart
index f880799..7b1d1a6 100644
--- a/pkgs/http_client_conformance_tests/lib/src/compressed_response_body_server_web.dart
+++ b/pkgs/http_client_conformance_tests/lib/src/compressed_response_body_server_web.dart
@@ -3,6 +3,8 @@
 import 'package:stream_channel/stream_channel.dart';
 import 'package:test/test.dart';
 
+export 'server_queue_helpers.dart' show StreamQueueOfNullableObjectExtension;
+
 /// Starts the redirect test HTTP server out-of-process.
 Future<StreamChannel<Object?>> startServer() async => spawnHybridUri(Uri(
     scheme: 'package',
diff --git a/pkgs/http_client_conformance_tests/lib/src/compressed_response_body_tests.dart b/pkgs/http_client_conformance_tests/lib/src/compressed_response_body_tests.dart
index 3ce871b..538b3ba 100644
--- a/pkgs/http_client_conformance_tests/lib/src/compressed_response_body_tests.dart
+++ b/pkgs/http_client_conformance_tests/lib/src/compressed_response_body_tests.dart
@@ -8,7 +8,7 @@
 import 'package:test/test.dart';
 
 import 'compressed_response_body_server_vm.dart'
-    if (dart.library.html) 'compressed_response_body_server_web.dart';
+    if (dart.library.js_interop) 'compressed_response_body_server_web.dart';
 
 /// Tests that the [Client] correctly implements HTTP responses with compressed
 /// bodies.
@@ -32,7 +32,7 @@
     setUpAll(() async {
       httpServerChannel = await startServer();
       httpServerQueue = StreamQueue(httpServerChannel.stream);
-      host = 'localhost:${await httpServerQueue.next}';
+      host = 'localhost:${await httpServerQueue.nextAsInt}';
     });
     tearDownAll(() => httpServerChannel.sink.add(null));
 
diff --git a/pkgs/http_client_conformance_tests/lib/src/isolate_test.dart b/pkgs/http_client_conformance_tests/lib/src/isolate_test.dart
index b4ac8b2..1723ab5 100644
--- a/pkgs/http_client_conformance_tests/lib/src/isolate_test.dart
+++ b/pkgs/http_client_conformance_tests/lib/src/isolate_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'dart:isolate' if (dart.library.html) 'dummy_isolate.dart';
+import 'dart:isolate' if (dart.library.js_interop) 'dummy_isolate.dart';
 
 import 'package:async/async.dart';
 import 'package:http/http.dart';
@@ -10,7 +10,7 @@
 import 'package:test/test.dart';
 
 import 'request_body_server_vm.dart'
-    if (dart.library.html) 'request_body_server_web.dart';
+    if (dart.library.js_interop) 'request_body_server_web.dart';
 
 Future<void> _testPost(Client Function() clientFactory, String host) async {
   await Isolate.run(
@@ -31,7 +31,7 @@
     setUpAll(() async {
       httpServerChannel = await startServer();
       httpServerQueue = StreamQueue(httpServerChannel.stream);
-      host = 'localhost:${await httpServerQueue.next}';
+      host = 'localhost:${await httpServerQueue.nextAsInt}';
     });
     tearDownAll(() => httpServerChannel.sink.add(null));
 
diff --git a/pkgs/http_client_conformance_tests/lib/src/multiple_clients_server_vm.dart b/pkgs/http_client_conformance_tests/lib/src/multiple_clients_server_vm.dart
index c689212..f00f4ba 100644
--- a/pkgs/http_client_conformance_tests/lib/src/multiple_clients_server_vm.dart
+++ b/pkgs/http_client_conformance_tests/lib/src/multiple_clients_server_vm.dart
@@ -4,6 +4,8 @@
 
 import 'multiple_clients_server.dart';
 
+export 'server_queue_helpers.dart' show StreamQueueOfNullableObjectExtension;
+
 /// Starts the redirect test HTTP server in the same process.
 Future<StreamChannel<Object?>> startServer() async {
   final controller = StreamChannelController<Object?>(sync: true);
diff --git a/pkgs/http_client_conformance_tests/lib/src/multiple_clients_server_web.dart b/pkgs/http_client_conformance_tests/lib/src/multiple_clients_server_web.dart
index 91cfc76..3f71aa7 100644
--- a/pkgs/http_client_conformance_tests/lib/src/multiple_clients_server_web.dart
+++ b/pkgs/http_client_conformance_tests/lib/src/multiple_clients_server_web.dart
@@ -3,6 +3,8 @@
 import 'package:stream_channel/stream_channel.dart';
 import 'package:test/test.dart';
 
+export 'server_queue_helpers.dart' show StreamQueueOfNullableObjectExtension;
+
 /// Starts the redirect test HTTP server out-of-process.
 Future<StreamChannel<Object?>> startServer() async => spawnHybridUri(Uri(
     scheme: 'package',
diff --git a/pkgs/http_client_conformance_tests/lib/src/multiple_clients_tests.dart b/pkgs/http_client_conformance_tests/lib/src/multiple_clients_tests.dart
index be9c4d9..ad40d4a 100644
--- a/pkgs/http_client_conformance_tests/lib/src/multiple_clients_tests.dart
+++ b/pkgs/http_client_conformance_tests/lib/src/multiple_clients_tests.dart
@@ -8,7 +8,7 @@
 import 'package:test/test.dart';
 
 import 'multiple_clients_server_vm.dart'
-    if (dart.library.html) 'multiple_clients_server_web.dart';
+    if (dart.library.js_interop) 'multiple_clients_server_web.dart';
 
 /// Tests that the [Client] works correctly if there are many used
 /// simultaneously.
@@ -21,7 +21,7 @@
     setUpAll(() async {
       httpServerChannel = await startServer();
       httpServerQueue = StreamQueue(httpServerChannel.stream);
-      host = 'localhost:${await httpServerQueue.next}';
+      host = 'localhost:${await httpServerQueue.nextAsInt}';
     });
     tearDownAll(() => httpServerChannel.sink.add(null));
 
diff --git a/pkgs/http_client_conformance_tests/lib/src/redirect_server_vm.dart b/pkgs/http_client_conformance_tests/lib/src/redirect_server_vm.dart
index 7f9cf8c..4a9450a 100644
--- a/pkgs/http_client_conformance_tests/lib/src/redirect_server_vm.dart
+++ b/pkgs/http_client_conformance_tests/lib/src/redirect_server_vm.dart
@@ -4,6 +4,8 @@
 
 import 'redirect_server.dart';
 
+export 'server_queue_helpers.dart' show StreamQueueOfNullableObjectExtension;
+
 /// Starts the redirect test HTTP server in the same process.
 Future<StreamChannel<Object?>> startServer() async {
   final controller = StreamChannelController<Object?>(sync: true);
diff --git a/pkgs/http_client_conformance_tests/lib/src/redirect_server_web.dart b/pkgs/http_client_conformance_tests/lib/src/redirect_server_web.dart
index 0fbe8a3..a5fb0f2 100644
--- a/pkgs/http_client_conformance_tests/lib/src/redirect_server_web.dart
+++ b/pkgs/http_client_conformance_tests/lib/src/redirect_server_web.dart
@@ -3,6 +3,8 @@
 import 'package:stream_channel/stream_channel.dart';
 import 'package:test/test.dart';
 
+export 'server_queue_helpers.dart' show StreamQueueOfNullableObjectExtension;
+
 /// Starts the redirect test HTTP server out-of-process.
 Future<StreamChannel<Object?>> startServer() async => spawnHybridUri(Uri(
     scheme: 'package',
diff --git a/pkgs/http_client_conformance_tests/lib/src/redirect_tests.dart b/pkgs/http_client_conformance_tests/lib/src/redirect_tests.dart
index e21a5c2..47a77a7 100644
--- a/pkgs/http_client_conformance_tests/lib/src/redirect_tests.dart
+++ b/pkgs/http_client_conformance_tests/lib/src/redirect_tests.dart
@@ -8,7 +8,7 @@
 import 'package:test/test.dart';
 
 import 'redirect_server_vm.dart'
-    if (dart.library.html) 'redirect_server_web.dart';
+    if (dart.library.js_interop) 'redirect_server_web.dart';
 
 /// Tests that the [Client] correctly implements HTTP redirect logic.
 ///
@@ -23,7 +23,7 @@
     setUpAll(() async {
       httpServerChannel = await startServer();
       httpServerQueue = StreamQueue(httpServerChannel.stream);
-      host = 'localhost:${await httpServerQueue.next}';
+      host = 'localhost:${await httpServerQueue.nextAsInt}';
     });
     tearDownAll(() => httpServerChannel.sink.add(null));
 
diff --git a/pkgs/http_client_conformance_tests/lib/src/request_body_server_vm.dart b/pkgs/http_client_conformance_tests/lib/src/request_body_server_vm.dart
index 2260766..d2e1e4a 100644
--- a/pkgs/http_client_conformance_tests/lib/src/request_body_server_vm.dart
+++ b/pkgs/http_client_conformance_tests/lib/src/request_body_server_vm.dart
@@ -4,6 +4,8 @@
 
 import 'request_body_server.dart';
 
+export 'server_queue_helpers.dart' show StreamQueueOfNullableObjectExtension;
+
 /// Starts the redirect test HTTP server in the same process.
 Future<StreamChannel<Object?>> startServer() async {
   final controller = StreamChannelController<Object?>(sync: true);
diff --git a/pkgs/http_client_conformance_tests/lib/src/request_body_server_web.dart b/pkgs/http_client_conformance_tests/lib/src/request_body_server_web.dart
index 250bd52..6b6ab00 100644
--- a/pkgs/http_client_conformance_tests/lib/src/request_body_server_web.dart
+++ b/pkgs/http_client_conformance_tests/lib/src/request_body_server_web.dart
@@ -3,6 +3,8 @@
 import 'package:stream_channel/stream_channel.dart';
 import 'package:test/test.dart';
 
+export 'server_queue_helpers.dart' show StreamQueueOfNullableObjectExtension;
+
 /// Starts the redirect test HTTP server out-of-process.
 Future<StreamChannel<Object?>> startServer() async => spawnHybridUri(Uri(
     scheme: 'package',
diff --git a/pkgs/http_client_conformance_tests/lib/src/request_body_streamed_server_vm.dart b/pkgs/http_client_conformance_tests/lib/src/request_body_streamed_server_vm.dart
index 9f58119..c343d68 100644
--- a/pkgs/http_client_conformance_tests/lib/src/request_body_streamed_server_vm.dart
+++ b/pkgs/http_client_conformance_tests/lib/src/request_body_streamed_server_vm.dart
@@ -4,6 +4,8 @@
 
 import 'request_body_streamed_server.dart';
 
+export 'server_queue_helpers.dart' show StreamQueueOfNullableObjectExtension;
+
 /// Starts the redirect test HTTP server in the same process.
 Future<StreamChannel<Object?>> startServer() async {
   final controller = StreamChannelController<Object?>(sync: true);
diff --git a/pkgs/http_client_conformance_tests/lib/src/request_body_streamed_server_web.dart b/pkgs/http_client_conformance_tests/lib/src/request_body_streamed_server_web.dart
index 97e8fbc..41477ee 100644
--- a/pkgs/http_client_conformance_tests/lib/src/request_body_streamed_server_web.dart
+++ b/pkgs/http_client_conformance_tests/lib/src/request_body_streamed_server_web.dart
@@ -3,6 +3,8 @@
 import 'package:stream_channel/stream_channel.dart';
 import 'package:test/test.dart';
 
+export 'server_queue_helpers.dart' show StreamQueueOfNullableObjectExtension;
+
 /// Starts the redirect test HTTP server out-of-process.
 Future<StreamChannel<Object?>> startServer() async => spawnHybridUri(Uri(
     scheme: 'package',
diff --git a/pkgs/http_client_conformance_tests/lib/src/request_body_streamed_tests.dart b/pkgs/http_client_conformance_tests/lib/src/request_body_streamed_tests.dart
index 560858d..0f43505 100644
--- a/pkgs/http_client_conformance_tests/lib/src/request_body_streamed_tests.dart
+++ b/pkgs/http_client_conformance_tests/lib/src/request_body_streamed_tests.dart
@@ -11,7 +11,7 @@
 import 'package:test/test.dart';
 
 import 'request_body_streamed_server_vm.dart'
-    if (dart.library.html) 'request_body_streamed_server_web.dart';
+    if (dart.library.js_interop) 'request_body_streamed_server_web.dart';
 
 /// Tests that the [Client] correctly implements streamed request body
 /// uploading.
@@ -29,7 +29,7 @@
     setUp(() async {
       httpServerChannel = await startServer();
       httpServerQueue = StreamQueue(httpServerChannel.stream);
-      host = 'localhost:${await httpServerQueue.next}';
+      host = 'localhost:${await httpServerQueue.nextAsInt}';
     });
     tearDown(() => httpServerChannel.sink.add(null));
 
diff --git a/pkgs/http_client_conformance_tests/lib/src/request_body_tests.dart b/pkgs/http_client_conformance_tests/lib/src/request_body_tests.dart
index e211da5..901f7f7 100644
--- a/pkgs/http_client_conformance_tests/lib/src/request_body_tests.dart
+++ b/pkgs/http_client_conformance_tests/lib/src/request_body_tests.dart
@@ -10,7 +10,7 @@
 import 'package:test/test.dart';
 
 import 'request_body_server_vm.dart'
-    if (dart.library.html) 'request_body_server_web.dart';
+    if (dart.library.js_interop) 'request_body_server_web.dart';
 
 class _Plus2Decoder extends Converter<List<int>, String> {
   @override
@@ -47,7 +47,7 @@
     setUp(() async {
       httpServerChannel = await startServer();
       httpServerQueue = StreamQueue(httpServerChannel.stream);
-      host = 'localhost:${await httpServerQueue.next}';
+      host = 'localhost:${await httpServerQueue.nextAsInt}';
     });
     tearDown(() => httpServerChannel.sink.add(null));
 
@@ -260,6 +260,47 @@
       expect(serverReceivedBody.codeUnits, <int>[]);
     });
 
+    test('client.send() with persistentConnection', () async {
+      // Do five requests to verify that the connection persistance logic is
+      // correct.
+      for (var i = 0; i < 5; ++i) {
+        final request = Request('POST', Uri.http(host, ''))
+          ..headers['Content-Type'] = 'text/plain; charset=utf-8'
+          ..persistentConnection = true
+          ..body = 'Hello World $i';
+
+        final response = await client.send(request);
+        expect(response.statusCode, 200);
+
+        final serverReceivedContentType = await httpServerQueue.next;
+        final serverReceivedBody = await httpServerQueue.next as String;
+
+        expect(serverReceivedContentType, ['text/plain; charset=utf-8']);
+        expect(serverReceivedBody, 'Hello World $i');
+      }
+    });
+
+    test('client.send() with persistentConnection and body >64K', () async {
+      // 64KiB is special for the HTTP network API:
+      // https://fetch.spec.whatwg.org/#http-network-or-cache-fetch
+      // See https://github.com/dart-lang/http/issues/977
+      final body = ''.padLeft(64 * 1024, 'XYZ');
+
+      final request = Request('POST', Uri.http(host, ''))
+        ..headers['Content-Type'] = 'text/plain; charset=utf-8'
+        ..persistentConnection = true
+        ..body = body;
+
+      final response = await client.send(request);
+      expect(response.statusCode, 200);
+
+      final serverReceivedContentType = await httpServerQueue.next;
+      final serverReceivedBody = await httpServerQueue.next as String;
+
+      expect(serverReceivedContentType, ['text/plain; charset=utf-8']);
+      expect(serverReceivedBody, body);
+    });
+
     test('client.send() GET with non-empty stream', () async {
       final request = StreamedRequest('GET', Uri.http(host, ''));
       request.headers['Content-Type'] = 'image/png';
diff --git a/pkgs/http_client_conformance_tests/lib/src/request_headers_server_vm.dart b/pkgs/http_client_conformance_tests/lib/src/request_headers_server_vm.dart
index 44e6565..dc930dc 100644
--- a/pkgs/http_client_conformance_tests/lib/src/request_headers_server_vm.dart
+++ b/pkgs/http_client_conformance_tests/lib/src/request_headers_server_vm.dart
@@ -4,6 +4,8 @@
 
 import 'request_headers_server.dart';
 
+export 'server_queue_helpers.dart' show StreamQueueOfNullableObjectExtension;
+
 /// Starts the redirect test HTTP server in the same process.
 Future<StreamChannel<Object?>> startServer() async {
   final controller = StreamChannelController<Object?>(sync: true);
diff --git a/pkgs/http_client_conformance_tests/lib/src/request_headers_server_web.dart b/pkgs/http_client_conformance_tests/lib/src/request_headers_server_web.dart
index 62e8d9e..a15b69b 100644
--- a/pkgs/http_client_conformance_tests/lib/src/request_headers_server_web.dart
+++ b/pkgs/http_client_conformance_tests/lib/src/request_headers_server_web.dart
@@ -3,6 +3,8 @@
 import 'package:stream_channel/stream_channel.dart';
 import 'package:test/test.dart';
 
+export 'server_queue_helpers.dart' show StreamQueueOfNullableObjectExtension;
+
 /// Starts the redirect test HTTP server out-of-process.
 Future<StreamChannel<Object?>> startServer() async => spawnHybridUri(Uri(
     scheme: 'package',
diff --git a/pkgs/http_client_conformance_tests/lib/src/request_headers_tests.dart b/pkgs/http_client_conformance_tests/lib/src/request_headers_tests.dart
index 8adf98c..24d94d8 100644
--- a/pkgs/http_client_conformance_tests/lib/src/request_headers_tests.dart
+++ b/pkgs/http_client_conformance_tests/lib/src/request_headers_tests.dart
@@ -8,7 +8,7 @@
 import 'package:test/test.dart';
 
 import 'request_headers_server_vm.dart'
-    if (dart.library.html) 'request_headers_server_web.dart';
+    if (dart.library.js_interop) 'request_headers_server_web.dart';
 
 /// Tests that the [Client] correctly sends headers in the request.
 void testRequestHeaders(Client client) async {
@@ -20,7 +20,7 @@
     setUpAll(() async {
       httpServerChannel = await startServer();
       httpServerQueue = StreamQueue(httpServerChannel.stream);
-      host = 'localhost:${await httpServerQueue.next}';
+      host = 'localhost:${await httpServerQueue.nextAsInt}';
     });
     tearDownAll(() => httpServerChannel.sink.add(null));
 
diff --git a/pkgs/http_client_conformance_tests/lib/src/request_methods_server.dart b/pkgs/http_client_conformance_tests/lib/src/request_methods_server.dart
new file mode 100644
index 0000000..bf05ec0
--- /dev/null
+++ b/pkgs/http_client_conformance_tests/lib/src/request_methods_server.dart
@@ -0,0 +1,41 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:io';
+
+import 'package:stream_channel/stream_channel.dart';
+
+/// Starts an HTTP server that captures the request headers.
+///
+/// Channel protocol:
+///    On Startup:
+///     - send port
+///    On Request Received:
+///     - send the received request method (e.g. GET) as a String
+///    When Receive Anything:
+///     - exit
+void hybridMain(StreamChannel<Object?> channel) async {
+  late HttpServer server;
+
+  server = (await HttpServer.bind('localhost', 0))
+    ..listen((request) async {
+      request.response.headers.set('Access-Control-Allow-Origin', '*');
+      if (request.method == 'OPTIONS') {
+        // Handle a CORS preflight request:
+        // https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#preflighted_requests
+        request.response.headers
+          ..set('Access-Control-Allow-Methods', '*')
+          ..set('Access-Control-Allow-Headers', '*');
+      } else {
+        channel.sink.add(request.method);
+      }
+      unawaited(request.response.close());
+    });
+
+  channel.sink.add(server.port);
+  await channel
+      .stream.first; // Any writes indicates that the server should exit.
+  unawaited(server.close());
+}
diff --git a/pkgs/http_client_conformance_tests/lib/src/request_methods_server_vm.dart b/pkgs/http_client_conformance_tests/lib/src/request_methods_server_vm.dart
new file mode 100644
index 0000000..fa25735
--- /dev/null
+++ b/pkgs/http_client_conformance_tests/lib/src/request_methods_server_vm.dart
@@ -0,0 +1,14 @@
+// Generated by generate_server_wrappers.dart. Do not edit.
+
+import 'package:stream_channel/stream_channel.dart';
+
+import 'request_methods_server.dart';
+
+export 'server_queue_helpers.dart' show StreamQueueOfNullableObjectExtension;
+
+/// Starts the redirect test HTTP server in the same process.
+Future<StreamChannel<Object?>> startServer() async {
+  final controller = StreamChannelController<Object?>(sync: true);
+  hybridMain(controller.foreign);
+  return controller.local;
+}
diff --git a/pkgs/http_client_conformance_tests/lib/src/request_methods_server_web.dart b/pkgs/http_client_conformance_tests/lib/src/request_methods_server_web.dart
new file mode 100644
index 0000000..f9c924e
--- /dev/null
+++ b/pkgs/http_client_conformance_tests/lib/src/request_methods_server_web.dart
@@ -0,0 +1,11 @@
+// Generated by generate_server_wrappers.dart. Do not edit.
+
+import 'package:stream_channel/stream_channel.dart';
+import 'package:test/test.dart';
+
+export 'server_queue_helpers.dart' show StreamQueueOfNullableObjectExtension;
+
+/// Starts the redirect test HTTP server out-of-process.
+Future<StreamChannel<Object?>> startServer() async => spawnHybridUri(Uri(
+    scheme: 'package',
+    path: 'http_client_conformance_tests/src/request_methods_server.dart'));
diff --git a/pkgs/http_client_conformance_tests/lib/src/request_methods_tests.dart b/pkgs/http_client_conformance_tests/lib/src/request_methods_tests.dart
new file mode 100644
index 0000000..802f57e
--- /dev/null
+++ b/pkgs/http_client_conformance_tests/lib/src/request_methods_tests.dart
@@ -0,0 +1,88 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:async/async.dart';
+import 'package:http/http.dart';
+import 'package:stream_channel/stream_channel.dart';
+import 'package:test/test.dart';
+
+import 'request_methods_server_vm.dart'
+    if (dart.library.js_interop) 'request_methods_server_web.dart';
+
+/// Tests that the [Client] correctly sends HTTP request methods
+/// (e.g. GET, HEAD).
+///
+/// If [preservesMethodCase] is `false` then tests that assume that the
+/// [Client] preserves custom request method casing will be skipped.
+void testRequestMethods(Client client,
+    {bool preservesMethodCase = true}) async {
+  group('request methods', () {
+    late final String host;
+    late final StreamChannel<Object?> httpServerChannel;
+    late final StreamQueue<Object?> httpServerQueue;
+
+    setUpAll(() async {
+      httpServerChannel = await startServer();
+      httpServerQueue = StreamQueue(httpServerChannel.stream);
+      host = 'localhost:${await httpServerQueue.nextAsInt}';
+    });
+    tearDownAll(() => httpServerChannel.sink.add(null));
+
+    test('custom method - not case preserving', () async {
+      await client.send(Request(
+        'CuStOm',
+        Uri.http(host, ''),
+      ));
+      final method = await httpServerQueue.next as String;
+      expect('CUSTOM', method.toUpperCase());
+    });
+
+    test('custom method case preserving', () async {
+      await client.send(Request(
+        'CuStOm',
+        Uri.http(host, ''),
+      ));
+      final method = await httpServerQueue.next as String;
+      expect('CuStOm', method);
+    },
+        skip: preservesMethodCase
+            ? false
+            : 'does not preserve HTTP request method case');
+
+    test('delete', () async {
+      await client.delete(Uri.http(host, ''));
+      final method = await httpServerQueue.next as String;
+      expect('DELETE', method);
+    });
+
+    test('get', () async {
+      await client.get(Uri.http(host, ''));
+      final method = await httpServerQueue.next as String;
+      expect('GET', method);
+    });
+    test('head', () async {
+      await client.head(Uri.http(host, ''));
+      final method = await httpServerQueue.next as String;
+      expect('HEAD', method);
+    });
+
+    test('patch', () async {
+      await client.patch(Uri.http(host, ''));
+      final method = await httpServerQueue.next as String;
+      expect('PATCH', method);
+    });
+
+    test('post', () async {
+      await client.post(Uri.http(host, ''));
+      final method = await httpServerQueue.next as String;
+      expect('POST', method);
+    });
+
+    test('put', () async {
+      await client.put(Uri.http(host, ''));
+      final method = await httpServerQueue.next as String;
+      expect('PUT', method);
+    });
+  });
+}
diff --git a/pkgs/http_client_conformance_tests/lib/src/response_body_server_vm.dart b/pkgs/http_client_conformance_tests/lib/src/response_body_server_vm.dart
index f88e065..a12b6fb 100644
--- a/pkgs/http_client_conformance_tests/lib/src/response_body_server_vm.dart
+++ b/pkgs/http_client_conformance_tests/lib/src/response_body_server_vm.dart
@@ -4,6 +4,8 @@
 
 import 'response_body_server.dart';
 
+export 'server_queue_helpers.dart' show StreamQueueOfNullableObjectExtension;
+
 /// Starts the redirect test HTTP server in the same process.
 Future<StreamChannel<Object?>> startServer() async {
   final controller = StreamChannelController<Object?>(sync: true);
diff --git a/pkgs/http_client_conformance_tests/lib/src/response_body_server_web.dart b/pkgs/http_client_conformance_tests/lib/src/response_body_server_web.dart
index 94bdaa9..4d23a48 100644
--- a/pkgs/http_client_conformance_tests/lib/src/response_body_server_web.dart
+++ b/pkgs/http_client_conformance_tests/lib/src/response_body_server_web.dart
@@ -3,6 +3,8 @@
 import 'package:stream_channel/stream_channel.dart';
 import 'package:test/test.dart';
 
+export 'server_queue_helpers.dart' show StreamQueueOfNullableObjectExtension;
+
 /// Starts the redirect test HTTP server out-of-process.
 Future<StreamChannel<Object?>> startServer() async => spawnHybridUri(Uri(
     scheme: 'package',
diff --git a/pkgs/http_client_conformance_tests/lib/src/response_body_streamed_server_vm.dart b/pkgs/http_client_conformance_tests/lib/src/response_body_streamed_server_vm.dart
index 01d84a1..4e4eaff 100644
--- a/pkgs/http_client_conformance_tests/lib/src/response_body_streamed_server_vm.dart
+++ b/pkgs/http_client_conformance_tests/lib/src/response_body_streamed_server_vm.dart
@@ -4,6 +4,8 @@
 
 import 'response_body_streamed_server.dart';
 
+export 'server_queue_helpers.dart' show StreamQueueOfNullableObjectExtension;
+
 /// Starts the redirect test HTTP server in the same process.
 Future<StreamChannel<Object?>> startServer() async {
   final controller = StreamChannelController<Object?>(sync: true);
diff --git a/pkgs/http_client_conformance_tests/lib/src/response_body_streamed_server_web.dart b/pkgs/http_client_conformance_tests/lib/src/response_body_streamed_server_web.dart
index a9ce00b..e04ebd6 100644
--- a/pkgs/http_client_conformance_tests/lib/src/response_body_streamed_server_web.dart
+++ b/pkgs/http_client_conformance_tests/lib/src/response_body_streamed_server_web.dart
@@ -3,6 +3,8 @@
 import 'package:stream_channel/stream_channel.dart';
 import 'package:test/test.dart';
 
+export 'server_queue_helpers.dart' show StreamQueueOfNullableObjectExtension;
+
 /// Starts the redirect test HTTP server out-of-process.
 Future<StreamChannel<Object?>> startServer() async => spawnHybridUri(Uri(
     scheme: 'package',
diff --git a/pkgs/http_client_conformance_tests/lib/src/response_body_streamed_test.dart b/pkgs/http_client_conformance_tests/lib/src/response_body_streamed_test.dart
index 28686fa..f355d6c 100644
--- a/pkgs/http_client_conformance_tests/lib/src/response_body_streamed_test.dart
+++ b/pkgs/http_client_conformance_tests/lib/src/response_body_streamed_test.dart
@@ -10,7 +10,7 @@
 import 'package:test/test.dart';
 
 import 'response_body_streamed_server_vm.dart'
-    if (dart.library.html) 'response_body_streamed_server_web.dart';
+    if (dart.library.js_interop) 'response_body_streamed_server_web.dart';
 
 /// Tests that the [Client] correctly implements HTTP responses with bodies of
 /// unbounded size.
@@ -28,7 +28,7 @@
     setUpAll(() async {
       httpServerChannel = await startServer();
       httpServerQueue = StreamQueue(httpServerChannel.stream);
-      host = 'localhost:${await httpServerQueue.next}';
+      host = 'localhost:${await httpServerQueue.nextAsInt}';
     });
     tearDownAll(() => httpServerChannel.sink.add(null));
 
diff --git a/pkgs/http_client_conformance_tests/lib/src/response_body_tests.dart b/pkgs/http_client_conformance_tests/lib/src/response_body_tests.dart
index 91ee549..34c29f6 100644
--- a/pkgs/http_client_conformance_tests/lib/src/response_body_tests.dart
+++ b/pkgs/http_client_conformance_tests/lib/src/response_body_tests.dart
@@ -8,7 +8,7 @@
 import 'package:test/test.dart';
 
 import 'response_body_server_vm.dart'
-    if (dart.library.html) 'response_body_server_web.dart';
+    if (dart.library.js_interop) 'response_body_server_web.dart';
 
 /// Tests that the [Client] correctly implements HTTP responses with bodies.
 ///
@@ -26,7 +26,7 @@
     setUpAll(() async {
       httpServerChannel = await startServer();
       httpServerQueue = StreamQueue(httpServerChannel.stream);
-      host = 'localhost:${await httpServerQueue.next}';
+      host = 'localhost:${await httpServerQueue.nextAsInt}';
     });
     tearDownAll(() => httpServerChannel.sink.add(null));
 
diff --git a/pkgs/http_client_conformance_tests/lib/src/response_headers_server_vm.dart b/pkgs/http_client_conformance_tests/lib/src/response_headers_server_vm.dart
index b7d4a01..c99a021 100644
--- a/pkgs/http_client_conformance_tests/lib/src/response_headers_server_vm.dart
+++ b/pkgs/http_client_conformance_tests/lib/src/response_headers_server_vm.dart
@@ -4,6 +4,8 @@
 
 import 'response_headers_server.dart';
 
+export 'server_queue_helpers.dart' show StreamQueueOfNullableObjectExtension;
+
 /// Starts the redirect test HTTP server in the same process.
 Future<StreamChannel<Object?>> startServer() async {
   final controller = StreamChannelController<Object?>(sync: true);
diff --git a/pkgs/http_client_conformance_tests/lib/src/response_headers_server_web.dart b/pkgs/http_client_conformance_tests/lib/src/response_headers_server_web.dart
index 8ee938a..0e6dabd 100644
--- a/pkgs/http_client_conformance_tests/lib/src/response_headers_server_web.dart
+++ b/pkgs/http_client_conformance_tests/lib/src/response_headers_server_web.dart
@@ -3,6 +3,8 @@
 import 'package:stream_channel/stream_channel.dart';
 import 'package:test/test.dart';
 
+export 'server_queue_helpers.dart' show StreamQueueOfNullableObjectExtension;
+
 /// Starts the redirect test HTTP server out-of-process.
 Future<StreamChannel<Object?>> startServer() async => spawnHybridUri(Uri(
     scheme: 'package',
diff --git a/pkgs/http_client_conformance_tests/lib/src/response_headers_tests.dart b/pkgs/http_client_conformance_tests/lib/src/response_headers_tests.dart
index 4f92042..84f0fb6 100644
--- a/pkgs/http_client_conformance_tests/lib/src/response_headers_tests.dart
+++ b/pkgs/http_client_conformance_tests/lib/src/response_headers_tests.dart
@@ -8,7 +8,7 @@
 import 'package:test/test.dart';
 
 import 'response_headers_server_vm.dart'
-    if (dart.library.html) 'response_headers_server_web.dart';
+    if (dart.library.js_interop) 'response_headers_server_web.dart';
 
 /// Tests that the [Client] correctly processes response headers.
 void testResponseHeaders(Client client) async {
@@ -20,7 +20,7 @@
     setUp(() async {
       httpServerChannel = await startServer();
       httpServerQueue = StreamQueue(httpServerChannel.stream);
-      host = 'localhost:${await httpServerQueue.next}';
+      host = 'localhost:${await httpServerQueue.nextAsInt}';
     });
 
     test('single header', () async {
diff --git a/pkgs/http_client_conformance_tests/lib/src/response_status_line_server_vm.dart b/pkgs/http_client_conformance_tests/lib/src/response_status_line_server_vm.dart
index ff2ea84..053bd11 100644
--- a/pkgs/http_client_conformance_tests/lib/src/response_status_line_server_vm.dart
+++ b/pkgs/http_client_conformance_tests/lib/src/response_status_line_server_vm.dart
@@ -4,6 +4,8 @@
 
 import 'response_status_line_server.dart';
 
+export 'server_queue_helpers.dart' show StreamQueueOfNullableObjectExtension;
+
 /// Starts the redirect test HTTP server in the same process.
 Future<StreamChannel<Object?>> startServer() async {
   final controller = StreamChannelController<Object?>(sync: true);
diff --git a/pkgs/http_client_conformance_tests/lib/src/response_status_line_server_web.dart b/pkgs/http_client_conformance_tests/lib/src/response_status_line_server_web.dart
index f1ebbcb..d70a325 100644
--- a/pkgs/http_client_conformance_tests/lib/src/response_status_line_server_web.dart
+++ b/pkgs/http_client_conformance_tests/lib/src/response_status_line_server_web.dart
@@ -3,6 +3,8 @@
 import 'package:stream_channel/stream_channel.dart';
 import 'package:test/test.dart';
 
+export 'server_queue_helpers.dart' show StreamQueueOfNullableObjectExtension;
+
 /// Starts the redirect test HTTP server out-of-process.
 Future<StreamChannel<Object?>> startServer() async => spawnHybridUri(Uri(
     scheme: 'package',
diff --git a/pkgs/http_client_conformance_tests/lib/src/response_status_line_tests.dart b/pkgs/http_client_conformance_tests/lib/src/response_status_line_tests.dart
index b618fa0..6eb70c5 100644
--- a/pkgs/http_client_conformance_tests/lib/src/response_status_line_tests.dart
+++ b/pkgs/http_client_conformance_tests/lib/src/response_status_line_tests.dart
@@ -8,7 +8,7 @@
 import 'package:test/test.dart';
 
 import 'response_status_line_server_vm.dart'
-    if (dart.library.html) 'response_status_line_server_web.dart';
+    if (dart.library.js_interop) 'response_status_line_server_web.dart';
 
 /// Tests that the [Client] correctly processes the response status line (e.g.
 /// 'HTTP/1.1 200 OK\r\n').
@@ -23,7 +23,7 @@
     setUp(() async {
       httpServerChannel = await startServer();
       httpServerQueue = StreamQueue(httpServerChannel.stream);
-      host = 'localhost:${await httpServerQueue.next}';
+      host = 'localhost:${await httpServerQueue.nextAsInt}';
     });
 
     test('complete', () async {
diff --git a/pkgs/http_client_conformance_tests/lib/src/server_errors_server_vm.dart b/pkgs/http_client_conformance_tests/lib/src/server_errors_server_vm.dart
index 257adcf..e5aa09f 100644
--- a/pkgs/http_client_conformance_tests/lib/src/server_errors_server_vm.dart
+++ b/pkgs/http_client_conformance_tests/lib/src/server_errors_server_vm.dart
@@ -4,6 +4,8 @@
 
 import 'server_errors_server.dart';
 
+export 'server_queue_helpers.dart' show StreamQueueOfNullableObjectExtension;
+
 /// Starts the redirect test HTTP server in the same process.
 Future<StreamChannel<Object?>> startServer() async {
   final controller = StreamChannelController<Object?>(sync: true);
diff --git a/pkgs/http_client_conformance_tests/lib/src/server_errors_server_web.dart b/pkgs/http_client_conformance_tests/lib/src/server_errors_server_web.dart
index cc763e3..9614f36 100644
--- a/pkgs/http_client_conformance_tests/lib/src/server_errors_server_web.dart
+++ b/pkgs/http_client_conformance_tests/lib/src/server_errors_server_web.dart
@@ -3,6 +3,8 @@
 import 'package:stream_channel/stream_channel.dart';
 import 'package:test/test.dart';
 
+export 'server_queue_helpers.dart' show StreamQueueOfNullableObjectExtension;
+
 /// Starts the redirect test HTTP server out-of-process.
 Future<StreamChannel<Object?>> startServer() async => spawnHybridUri(Uri(
     scheme: 'package',
diff --git a/pkgs/http_client_conformance_tests/lib/src/server_errors_test.dart b/pkgs/http_client_conformance_tests/lib/src/server_errors_test.dart
index 65de499..1a83696 100644
--- a/pkgs/http_client_conformance_tests/lib/src/server_errors_test.dart
+++ b/pkgs/http_client_conformance_tests/lib/src/server_errors_test.dart
@@ -8,7 +8,7 @@
 import 'package:test/test.dart';
 
 import 'server_errors_server_vm.dart'
-    if (dart.library.html) 'server_errors_server_web.dart';
+    if (dart.library.js_interop) 'server_errors_server_web.dart';
 
 /// Tests that the [Client] correctly handles server errors.
 void testServerErrors(Client client, {bool redirectAlwaysAllowed = false}) {
@@ -20,7 +20,7 @@
     setUpAll(() async {
       httpServerChannel = await startServer();
       httpServerQueue = StreamQueue(httpServerChannel.stream);
-      host = 'localhost:${await httpServerQueue.next}';
+      host = 'localhost:${await httpServerQueue.nextAsInt}';
     });
     tearDownAll(() => httpServerChannel.sink.add(null));
 
diff --git a/pkgs/http_client_conformance_tests/lib/src/server_queue_helpers.dart b/pkgs/http_client_conformance_tests/lib/src/server_queue_helpers.dart
new file mode 100644
index 0000000..df87ddd
--- /dev/null
+++ b/pkgs/http_client_conformance_tests/lib/src/server_queue_helpers.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:async/async.dart';
+
+extension StreamQueueOfNullableObjectExtension on StreamQueue<Object?> {
+  /// When run under dart2wasm, JSON numbers are always returned as [double].
+  Future<int> get nextAsInt async => ((await next) as num).toInt();
+}
diff --git a/pkgs/http_client_conformance_tests/pubspec.yaml b/pkgs/http_client_conformance_tests/pubspec.yaml
index 4264059..520f131 100644
--- a/pkgs/http_client_conformance_tests/pubspec.yaml
+++ b/pkgs/http_client_conformance_tests/pubspec.yaml
@@ -2,18 +2,19 @@
 description: >-
   A library that tests whether implementations of package:http's `Client` class
   behave as expected.
-publish_to: none
 repository: https://github.com/dart-lang/http/tree/master/pkgs/http_client_conformance_tests
 
+publish_to: none
+
 environment:
-  sdk: '>=2.19.0 <3.0.0'
+  sdk: ^3.0.0
 
 dependencies:
   async: ^2.8.2
   dart_style: ^2.2.3
-  http: '>=0.13.4 <2.0.0'
+  http: ^1.0.0
   stream_channel: ^2.1.1
   test: ^1.21.2
 
 dev_dependencies:
-  dart_flutter_team_lints: ^1.0.0
+  dart_flutter_team_lints: ^2.0.0
diff --git a/pkgs/http_profile/pubspec.yaml b/pkgs/http_profile/pubspec.yaml
index 9e3b69e..1b5891e 100644
--- a/pkgs/http_profile/pubspec.yaml
+++ b/pkgs/http_profile/pubspec.yaml
@@ -1,10 +1,11 @@
 name: http_profile
 description: >-
-  A library used by HTTP client authors to integrate with the DevTools
-  Network tab.
-publish_to: none
+  A library used by HTTP client authors to integrate with the DevTools Network
+  tab.
 repository: https://github.com/dart-lang/http/tree/master/pkgs/http_profile
 
+publish_to: none
+
 environment:
   sdk: ^3.0.0
 
diff --git a/pkgs/java_http/pubspec.yaml b/pkgs/java_http/pubspec.yaml
index ecba4f1..c04429a 100644
--- a/pkgs/java_http/pubspec.yaml
+++ b/pkgs/java_http/pubspec.yaml
@@ -1,7 +1,9 @@
 name: java_http
-description: A Dart package for making HTTP requests using java.net.HttpURLConnection.
 version: 0.0.1
+description: >-
+  A Dart package for making HTTP requests using java.net.HttpURLConnection.
 repository: https://github.com/dart-lang/http/tree/master/pkgs/java_http
+
 publish_to: none
 
 environment:
@@ -14,9 +16,8 @@
   path: ^1.8.0
 
 dev_dependencies:
-  dart_flutter_team_lints: ^1.0.0
+  dart_flutter_team_lints: ^2.0.0
   http_client_conformance_tests:
     path: ../http_client_conformance_tests/
   jnigen: ^0.5.0
-  lints: ^2.0.0
   test: ^1.21.0
diff --git a/tool/ci.sh b/tool/ci.sh
index 26395d2..d4cc8d2 100755
--- a/tool/ci.sh
+++ b/tool/ci.sh
@@ -1,9 +1,10 @@
 #!/bin/bash
-# Created with package:mono_repo v6.6.0
+# Created with package:mono_repo v6.6.1
 
 # Support built in commands on windows out of the box.
+
 # When it is a flutter repo (check the pubspec.yaml for "sdk: flutter")
-# then "flutter" is called instead of "pub".
+# then "flutter pub" is called instead of "dart pub".
 # This assumes that the Flutter SDK has been installed in a previous step.
 function pub() {
   if grep -Fq "sdk: flutter" "${PWD}/pubspec.yaml"; then
@@ -12,18 +13,13 @@
     command dart pub "$@"
   fi
 }
-# When it is a flutter repo (check the pubspec.yaml for "sdk: flutter")
-# then "flutter" is called instead of "pub".
-# This assumes that the Flutter SDK has been installed in a previous step.
+
 function format() {
-  if grep -Fq "sdk: flutter" "${PWD}/pubspec.yaml"; then
-    command flutter format "$@"
-  else
-    command dart format "$@"
-  fi
+  command dart format "$@"
 }
+
 # When it is a flutter repo (check the pubspec.yaml for "sdk: flutter")
-# then "flutter" is called instead of "pub".
+# then "flutter analyze" is called instead of "dart analyze".
 # This assumes that the Flutter SDK has been installed in a previous step.
 function analyze() {
   if grep -Fq "sdk: flutter" "${PWD}/pubspec.yaml"; then
@@ -99,6 +95,10 @@
         echo 'dart test --platform chrome'
         dart test --platform chrome || EXIT_CODE=$?
         ;;
+      test_4)
+        echo 'dart test --test-randomize-ordering-seed=random -p chrome -c dart2wasm'
+        dart test --test-randomize-ordering-seed=random -p chrome -c dart2wasm || EXIT_CODE=$?
+        ;;
       *)
         echo -e "\033[31mUnknown TASK '${TASK}' - TERMINATING JOB\033[0m"
         exit 64