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>
This commit is contained in:
HeXis-YS
2026-03-17 05:43:03 -07:00
committed by GitHub
parent d6579b29ae
commit 7f2682bb7b
3 changed files with 35 additions and 9 deletions

View File

@@ -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) {

View File

@@ -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<DioException>((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);
}

View File

@@ -58,7 +58,7 @@ class DownloadManager {
Response<ResponseBody> response;
try {
response = await Request.dio.get<ResponseBody>(
response = await Request.http11Dio.get<ResponseBody>(
url.http2https,
options: Options(
headers: {'range': 'bytes=$received-'},