From 3114cc2c2ca0ca876a740d829c5a779a058fc587 Mon Sep 17 00:00:00 2001 From: Cyrus Chan Date: Thu, 1 Feb 2024 14:48:31 +0800 Subject: [PATCH] Uses instance's client and fix client don't close --- model/CHANGELOG.md | 3 ++ model/lib/src/client/mock_client.dart | 13 +++--- model/lib/src/content_type_verifier.dart | 54 ++++++++++++++---------- model/lib/src/fetch/fetch.dart | 14 +++++- model/lib/src/fetch/producer.dart | 2 +- model/lib/src/fetch/tester.dart | 3 +- 6 files changed, 55 insertions(+), 34 deletions(-) diff --git a/model/CHANGELOG.md b/model/CHANGELOG.md index c1ed2a4..9a08d18 100644 --- a/model/CHANGELOG.md +++ b/model/CHANGELOG.md @@ -1,6 +1,9 @@ ## 3.4.0 * Add `MockOgHrefClient.advance` for building responding content with different content type applied. +* Fix client does not closes after stream closed when calling `determineContentTypes()` in `IteratedUrlInfoContentTypeResolver`. +* Uses final variable assignment rather than a getter for `MockOgHrefClient.redirect`. +* `IteratedUrlInfoContentTypeResolver` uses current instance of `MetaFetch`'s client to proceed data. ## 3.3.4 diff --git a/model/lib/src/client/mock_client.dart b/model/lib/src/client/mock_client.dart index 0e9e5ad..acfac49 100644 --- a/model/lib/src/client/mock_client.dart +++ b/model/lib/src/client/mock_client.dart @@ -154,7 +154,7 @@ final class MockOgHrefClient extends BaseClient /// Redirect features is always disabled for [MockOgHrefClient]. @override - bool get redirect => false; + final bool redirect = false; static Duration _generateResponseDelay() { late Random rand; @@ -237,12 +237,11 @@ final class MockOgHrefClient extends BaseClient /// For setting [contentLinker] without identical [contentType], /// please uses [MockOgHrefClient.advance] instead. factory MockOgHrefClient(Map contentLinker, - {String contentType = _PLAIN_TEXT_MIME}) { - return MockOgHrefClient.advance({ - for (var MapEntry(key: url, value: body) in contentLinker.entries) - url: MockOgHrefClientContent(content: body, contentType: contentType) - }); - } + {String contentType = _PLAIN_TEXT_MIME}) => + MockOgHrefClient.advance({ + for (var MapEntry(key: url, value: body) in contentLinker.entries) + url: MockOgHrefClientContent(content: body, contentType: contentType) + }); /// Uses [sample files](https://github.com/rk0cc/oghref/tree/main/model/sample) to defined /// content of the simulated HTML files with hosted IP address as `127.0.0.2` with `HTTPS` diff --git a/model/lib/src/content_type_verifier.dart b/model/lib/src/content_type_verifier.dart index 483c4bc..01bff61 100644 --- a/model/lib/src/content_type_verifier.dart +++ b/model/lib/src/content_type_verifier.dart @@ -6,9 +6,10 @@ import 'package:meta/meta.dart'; import 'package:mime_dart/mime_dart.dart'; import 'package:path/path.dart' as p; -import 'client/client.dart'; +import 'fetch/fetch.dart'; import 'model/url.dart'; + /// Determine the content type category from MIME. enum ContentTypeCategory { /// Audio files @@ -148,34 +149,41 @@ extension IteratedUrlInfoContentTypeResolver on Iterable { /// The condition of returned [ContentTypeCategory] will be depended on /// given extendion from [Uri.path] first. If not offered, it will /// try to find `Content-Type` in HTTP response header by making HTTP HEAD request. + /// + /// This features will not be availabled during test and [UnsupportedError] + /// will be thrown if attempted. Stream determineContentTypes() async* { - Client c = OgHrefClient(false); - - for (var ui in this) { - ContentTypeCategory httpCT; - Set httpExtCt = ui.url!.extensionContentType; + Client c = MetaFetch.instance.createClient(false); - if (httpExtCt.isNotEmpty) { - httpCT = httpExtCt.first; - } else { - httpCT = - await c.head(ui.url!).then((value) => value.contentTypeCategory); - } + try { + for (var ui in this) { + ContentTypeCategory httpCT; + Set httpExtCt = ui.url!.extensionContentType; - ContentTypeCategory? httpsCT; - if (ui.secureUrl != null) { - Set httpsExtCt = - ui.secureUrl!.extensionContentType; - if (httpsExtCt.isNotEmpty) { - httpsCT = httpsExtCt.first; + if (httpExtCt.isNotEmpty) { + httpCT = httpExtCt.first; } else { - httpsCT = await c - .head(ui.secureUrl!) - .then((value) => value.contentTypeCategory); + httpCT = + await c.head(ui.url!).then((value) => value.contentTypeCategory); } - } - yield UrlInfoContentTypeResult._(ui, httpCT, httpsCT); + ContentTypeCategory? httpsCT; + if (ui.secureUrl != null) { + Set httpsExtCt = + ui.secureUrl!.extensionContentType; + if (httpsExtCt.isNotEmpty) { + httpsCT = httpsExtCt.first; + } else { + httpsCT = await c + .head(ui.secureUrl!) + .then((value) => value.contentTypeCategory); + } + } + + yield UrlInfoContentTypeResult._(ui, httpCT, httpsCT); + } + } finally { + c.close(); } } } diff --git a/model/lib/src/fetch/fetch.dart b/model/lib/src/fetch/fetch.dart index b0eb472..145b706 100644 --- a/model/lib/src/fetch/fetch.dart +++ b/model/lib/src/fetch/fetch.dart @@ -166,7 +166,8 @@ abstract final class MetaFetch { } @factory - OgHrefClient _createClient(); + // ignore: unused_element + OgHrefClient _createClient(bool? redirectOverride); /// Get the corresponded parser from [prefix]. /// @@ -323,7 +324,7 @@ abstract final class MetaFetch { throw NonHttpUrlException(url); } - Client client = _createClient(); + Client client = _createClient(null); late Response resp; @@ -385,3 +386,12 @@ abstract final class MetaFetch { return _fetchHtmlDocument(url).then(_buildAllMetaInfo); } } + +/// Handle getting [Client] from [MetaFetch] to other components +/// internally. +@internal +extension MetaFetchClientFactoryExtension on MetaFetch { + /// An internal [Client] factory retrived from [MetaFetch]. + Client createClient([bool? redirectOverride]) => + _createClient(redirectOverride); +} diff --git a/model/lib/src/fetch/producer.dart b/model/lib/src/fetch/producer.dart index b553145..49158de 100644 --- a/model/lib/src/fetch/producer.dart +++ b/model/lib/src/fetch/producer.dart @@ -4,5 +4,5 @@ final class _MetaFetchProducer extends MetaFetch { _MetaFetchProducer() : super._(); @override - OgHrefClient _createClient() => OgHrefClient(allowRedirect); + OgHrefClient _createClient(bool? redirectOverride) => OgHrefClient(redirectOverride ?? allowRedirect); } diff --git a/model/lib/src/fetch/tester.dart b/model/lib/src/fetch/tester.dart index 25f710c..b0631ad 100644 --- a/model/lib/src/fetch/tester.dart +++ b/model/lib/src/fetch/tester.dart @@ -22,5 +22,6 @@ final class MetaFetchTester extends MetaFetch { additionalSupportedExtensions: const {"txt"}); @override - OgHrefClient _createClient() => _clientConstructor(); + // ignore: unused_element + OgHrefClient _createClient(bool? redirectOverride) => _clientConstructor(); }