retry on HttpException (#34526)

diff --git a/packages/flutter_tools/lib/src/base/io.dart b/packages/flutter_tools/lib/src/base/io.dart
index a32f27c..0250dbd 100644
--- a/packages/flutter_tools/lib/src/base/io.dart
+++ b/packages/flutter_tools/lib/src/base/io.dart
@@ -48,6 +48,7 @@
         HttpClientRequest,
         HttpClientResponse,
         HttpClientResponseCompressionState,
+        HttpException,
         HttpHeaders,
         HttpRequest,
         HttpServer,
diff --git a/packages/flutter_tools/lib/src/base/net.dart b/packages/flutter_tools/lib/src/base/net.dart
index 28c7194..046929d 100644
--- a/packages/flutter_tools/lib/src/base/net.dart
+++ b/packages/flutter_tools/lib/src/base/net.dart
@@ -64,6 +64,9 @@
   } on SocketException catch (error) {
     printTrace('Download error: $error');
     return null;
+  } on HttpException catch (error) {
+    printTrace('Download error: $error');
+    return null;
   }
   final HttpClientResponse response = await request.close();
   // If we're making a HEAD request, we're only checking to see if the URL is
diff --git a/packages/flutter_tools/test/base/net_test.dart b/packages/flutter_tools/test/base/net_test.dart
index fc7a29e..c38437a 100644
--- a/packages/flutter_tools/test/base/net_test.dart
+++ b/packages/flutter_tools/test/base/net_test.dart
@@ -105,6 +105,32 @@
     ),
   });
 
+testUsingContext('retry from HttpException', () async {
+    String error;
+    FakeAsync().run((FakeAsync time) {
+      fetchUrl(Uri.parse('http://example.invalid/')).then((List<int> value) {
+        error = 'test completed unexpectedly';
+      }, onError: (dynamic exception) {
+        error = 'test failed unexpectedly: $exception';
+      });
+      expect(testLogger.statusText, '');
+      time.elapse(const Duration(milliseconds: 10000));
+      expect(testLogger.statusText,
+        'Download failed -- attempting retry 1 in 1 second...\n'
+        'Download failed -- attempting retry 2 in 2 seconds...\n'
+        'Download failed -- attempting retry 3 in 4 seconds...\n'
+        'Download failed -- attempting retry 4 in 8 seconds...\n',
+      );
+    });
+    expect(testLogger.errorText, isEmpty);
+    expect(error, isNull);
+    expect(testLogger.traceText, contains('Download error: HttpException'));
+  }, overrides: <Type, Generator>{
+    HttpClientFactory: () => () => MockHttpClientThrowing(
+      const io.HttpException('test exception handling'),
+    ),
+  });
+
   testUsingContext('max attempts', () async {
     String error;
     List<int> actualResult;