From 7f2682bb7bbf7b91a68e9846b717fba1a3b04331 Mon Sep 17 00:00:00 2001 From: HeXis-YS <40174982+HeXis-YS@users.noreply.github.com> Date: Tue, 17 Mar 2026 05:43:03 -0700 Subject: [PATCH] opt(download): force cache downloads to use http/1.1 (#1870) * opt(download): force cache downloads to use http/1.1 * refactor(http): lazily initialize fallback http/1.1 client * fix(http): keep fallback client decision consistent at startup * opt: use clone * fix * fix --------- Co-authored-by: My-Responsitories <107370289+My-Responsitories@users.noreply.github.com> --- lib/http/init.dart | 31 ++++++++++++++++++--- lib/http/retry_interceptor.dart | 11 +++++--- lib/services/download/download_manager.dart | 2 +- 3 files changed, 35 insertions(+), 9 deletions(-) diff --git a/lib/http/init.dart b/lib/http/init.dart index 0f8a2e150..9537e2ca9 100644 --- a/lib/http/init.dart +++ b/lib/http/init.dart @@ -27,7 +27,11 @@ class Request { static final Request _instance = Request._internal(); static late AccountManager accountManager; + static final _enableHttp2 = Pref.enableHttp2; static late final Dio dio; + static Dio? _http11Dio; + static Dio get http11Dio => + _http11Dio ??= _enableHttp2 ? _cloneHttp11Dio() : dio; factory Request() => _instance; /// 设置cookie @@ -95,11 +99,26 @@ class Request { } catch (_) {} } + static Dio _cloneHttp11Dio() { + final h11 = dio.clone( + httpClientAdapter: + (dio.httpClientAdapter as Http2Adapter).fallbackAdapter, + ); + final interceptors = h11.interceptors; + for (var i = 0; i < interceptors.length; i++) { + final elem = interceptors[i]; + if (elem is RetryInterceptor) { + interceptors[i] = elem.copyWith(client: h11); + break; + } + } + return h11; + } + /* * config it and create */ Request._internal() { - final enableHttp2 = Pref.enableHttp2; //BaseOptions、Options、RequestOptions 都可以配置参数,优先级别依次递增,且可以根据优先级别覆盖参数 BaseOptions options = BaseOptions( //请求基地址,可以包含子路径 @@ -111,7 +130,7 @@ class Request { //Http请求头. headers: { 'user-agent': 'Dart/3.6 (dart:io)', // Http2Adapter不会自动添加标头 - if (!enableHttp2) 'connection': 'keep-alive', + if (!_enableHttp2) 'connection': 'keep-alive', 'accept-encoding': 'br,gzip', }, responseDecoder: _responseDecoder, // Http2Adapter没有自动解压 @@ -142,7 +161,7 @@ class Request { ); dio = Dio(options) - ..httpClientAdapter = enableHttp2 + ..httpClientAdapter = _enableHttp2 ? Http2Adapter( ConnectionManager( idleTimeout: const Duration(seconds: 15), @@ -167,7 +186,11 @@ class Request { : http11Adapter; // 先于其他Interceptor - dio.interceptors.add(RetryInterceptor(Pref.retryCount, Pref.retryDelay)); + if (Pref.retryCount != 0) { + dio.interceptors.add( + RetryInterceptor(dio, Pref.retryCount, Pref.retryDelay), + ); + } // 日志拦截器 输出请求、响应内容 if (kDebugMode) { diff --git a/lib/http/retry_interceptor.dart b/lib/http/retry_interceptor.dart index 7bf1d8918..1584d52c8 100644 --- a/lib/http/retry_interceptor.dart +++ b/lib/http/retry_interceptor.dart @@ -1,12 +1,12 @@ -import 'package:PiliPlus/http/init.dart'; import 'package:dio/dio.dart'; import 'package:http2/http2.dart'; class RetryInterceptor extends Interceptor { + final Dio _client; final int _count; final int _delay; - RetryInterceptor(this._count, this._delay); + RetryInterceptor(this._client, this._count, this._delay); @override void onError(DioException err, ErrorInterceptorHandler handler) { @@ -31,7 +31,7 @@ class RetryInterceptor extends Interceptor { ..data = null ..method = 'GET'; } - Request.dio + _client .fetch(options) .then( (i) => handler.resolve( @@ -62,7 +62,7 @@ class RetryInterceptor extends Interceptor { Duration( milliseconds: ++err.requestOptions.extra['_rt'] * _delay, ), - () => Request.dio + () => _client .fetch(err.requestOptions) .then(handler.resolve) .onError((error, _) => handler.reject(error)), @@ -76,4 +76,7 @@ class RetryInterceptor extends Interceptor { } } } + + RetryInterceptor copyWith({Dio? client, int? count, int? delay}) => + .new(client ?? _client, count ?? _count, delay ?? _delay); } diff --git a/lib/services/download/download_manager.dart b/lib/services/download/download_manager.dart index 3ec8cbc04..a9aa7466e 100644 --- a/lib/services/download/download_manager.dart +++ b/lib/services/download/download_manager.dart @@ -58,7 +58,7 @@ class DownloadManager { Response response; try { - response = await Request.dio.get( + response = await Request.http11Dio.get( url.http2https, options: Options( headers: {'range': 'bytes=$received-'},