From 013cc248b4a253bcb435c051f0b0a0b5632c9ac0 Mon Sep 17 00:00:00 2001 From: derdilla <82763757+derdilla@users.noreply.github.com> Date: Thu, 21 Nov 2024 02:04:14 +0100 Subject: [PATCH] [flutter_svg] Fix SvgNetworkLoader not closing internal http client (#8126) closes https://github.com/flutter/flutter/issues/158928 Ensures that if a Client is created in `prepareMessage` it is closed after getting the resource. --- third_party/packages/flutter_svg/CHANGELOG.md | 4 ++ .../packages/flutter_svg/lib/src/loaders.dart | 7 ++- third_party/packages/flutter_svg/pubspec.yaml | 2 +- .../flutter_svg/test/loaders_test.dart | 46 +++++++++++++++++++ 4 files changed, 57 insertions(+), 2 deletions(-) diff --git a/third_party/packages/flutter_svg/CHANGELOG.md b/third_party/packages/flutter_svg/CHANGELOG.md index 1adca859374c..7f8898396500 100644 --- a/third_party/packages/flutter_svg/CHANGELOG.md +++ b/third_party/packages/flutter_svg/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.15 + +* Fixes `SvgNetworkLoader` not closing internally created http clients. + ## 2.0.14 * Makes the package WASM compatible. diff --git a/third_party/packages/flutter_svg/lib/src/loaders.dart b/third_party/packages/flutter_svg/lib/src/loaders.dart index 2996cc11f64f..62e395982bd7 100644 --- a/third_party/packages/flutter_svg/lib/src/loaders.dart +++ b/third_party/packages/flutter_svg/lib/src/loaders.dart @@ -438,7 +438,12 @@ class SvgNetworkLoader extends SvgLoader { @override Future prepareMessage(BuildContext? context) async { final http.Client client = _httpClient ?? http.Client(); - return (await client.get(Uri.parse(url), headers: headers)).bodyBytes; + final http.Response response = + await client.get(Uri.parse(url), headers: headers); + if (_httpClient == null) { + client.close(); + } + return response.bodyBytes; } @override diff --git a/third_party/packages/flutter_svg/pubspec.yaml b/third_party/packages/flutter_svg/pubspec.yaml index e18e014e9596..f08db3a5ad64 100644 --- a/third_party/packages/flutter_svg/pubspec.yaml +++ b/third_party/packages/flutter_svg/pubspec.yaml @@ -2,7 +2,7 @@ name: flutter_svg description: An SVG rendering and widget library for Flutter, which allows painting and displaying Scalable Vector Graphics 1.1 files. repository: https://github.com/flutter/packages/tree/main/third_party/packages/flutter_svg issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+flutter_svg%22 -version: 2.0.14 +version: 2.0.15 environment: sdk: ^3.4.0 diff --git a/third_party/packages/flutter_svg/test/loaders_test.dart b/third_party/packages/flutter_svg/test/loaders_test.dart index 591b3b01e708..28f532512633 100644 --- a/third_party/packages/flutter_svg/test/loaders_test.dart +++ b/third_party/packages/flutter_svg/test/loaders_test.dart @@ -2,6 +2,7 @@ import 'package:flutter/services.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:http/http.dart' as http; void main() { setUp(() { @@ -57,6 +58,36 @@ void main() { expect((await loader.prepareMessage(null))!.lengthInBytes, 0); expect((await packageLoader.prepareMessage(null))!.lengthInBytes, 1); }); + + test('SvgNetworkLoader closes internal client', () async { + final List createdClients = []; + + await http.runWithClient(() async { + const SvgNetworkLoader loader = SvgNetworkLoader(''); + + expect(createdClients, isEmpty); + await loader.prepareMessage(null); + + expect(createdClients, hasLength(1)); + expect(createdClients[0].closeCalled, isTrue); + }, () { + final VerifyCloseClient client = VerifyCloseClient(); + createdClients.add(client); + return client; + }); + }); + + test("SvgNetworkLoader doesn't close passed client", () async { + final VerifyCloseClient client = VerifyCloseClient(); + final SvgNetworkLoader loader = SvgNetworkLoader( + '', + httpClient: client as http.Client, + ); + + expect(client.closeCalled, isFalse); + await loader.prepareMessage(null); + expect(client.closeCalled, isFalse); + }); } class TestBundle extends Fake implements AssetBundle { @@ -96,3 +127,18 @@ class _TestColorMapper extends ColorMapper { return color; } } + +class VerifyCloseClient extends Fake implements http.Client { + bool closeCalled = false; + + @override + Future get(Uri url, {Map? headers}) async { + return http.Response('', 200); + } + + @override + void close() { + assert(!closeCalled); + closeCalled = true; + } +}