mirror of
https://github.com/HChaZZY/PiliPlus.git
synced 2025-12-06 09:13:48 +08:00
77 lines
2.5 KiB
Dart
77 lines
2.5 KiB
Dart
import 'package:PiliPlus/http/init.dart';
|
|
import 'package:dio/dio.dart';
|
|
import 'package:http2/http2.dart';
|
|
|
|
class RetryInterceptor extends Interceptor {
|
|
final int _count;
|
|
final int _delay;
|
|
|
|
RetryInterceptor(this._count, this._delay);
|
|
|
|
@override
|
|
void onError(DioException err, ErrorInterceptorHandler handler) {
|
|
if (err.response != null) {
|
|
final options = err.requestOptions;
|
|
if (options.followRedirects && options.maxRedirects > 0) {
|
|
final status = err.response!.statusCode;
|
|
if (status != null && 300 <= status && status < 400) {
|
|
var redirectUrl = err.response!.headers.value('location');
|
|
if (redirectUrl != null) {
|
|
var uri = Uri.parse(redirectUrl);
|
|
if (!uri.hasScheme) {
|
|
uri = options.uri.resolveUri(uri);
|
|
redirectUrl = uri.toString();
|
|
}
|
|
(options..path = redirectUrl).maxRedirects--;
|
|
if (status == 303) {
|
|
options
|
|
..data = null
|
|
..method = 'GET';
|
|
}
|
|
Request.dio
|
|
.fetch(options)
|
|
.then(
|
|
(i) => handler.resolve(
|
|
i
|
|
..redirects.add(
|
|
RedirectRecord(status, options.method, uri),
|
|
)
|
|
..isRedirect = true,
|
|
),
|
|
)
|
|
.onError<DioException>((error, _) => handler.next(error));
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
return handler.next(err);
|
|
} else {
|
|
switch (err.type) {
|
|
case DioExceptionType.connectionError:
|
|
case DioExceptionType.connectionTimeout:
|
|
case DioExceptionType.sendTimeout:
|
|
case DioExceptionType.unknown:
|
|
if ((err.requestOptions.extra['_rt'] ??= 0) < _count &&
|
|
err.error
|
|
is! TransportConnectionException // 网络中断, 此时请求可能已经被服务器所接收
|
|
) {
|
|
Future.delayed(
|
|
Duration(
|
|
milliseconds: ++err.requestOptions.extra['_rt'] * _delay,
|
|
),
|
|
() => Request.dio
|
|
.fetch(err.requestOptions)
|
|
.then(handler.resolve)
|
|
.onError<DioException>((error, _) => handler.reject(error)),
|
|
);
|
|
} else {
|
|
handler.next(err);
|
|
}
|
|
return;
|
|
default:
|
|
return handler.next(err);
|
|
}
|
|
}
|
|
}
|
|
}
|