From aff97ea3140c28f6ef550cad6d55e197bcfaa521 Mon Sep 17 00:00:00 2001 From: Liplum Date: Tue, 30 Apr 2024 16:39:09 +0800 Subject: [PATCH] SSO lock --- lib/network/dio.dart | 9 +++------ lib/r.dart | 1 + lib/session/sso.dart | 39 ++++++++++++++++++++++++++------------- lib/utils/dio.dart | 20 ++++++++++++-------- 4 files changed, 42 insertions(+), 27 deletions(-) diff --git a/lib/network/dio.dart b/lib/network/dio.dart index a2d68c03b..990642496 100644 --- a/lib/network/dio.dart +++ b/lib/network/dio.dart @@ -6,7 +6,6 @@ import 'package:dio_cookie_manager/dio_cookie_manager.dart'; import 'package:fk_user_agent/fk_user_agent.dart'; import 'package:flutter/foundation.dart'; import 'package:sit/r.dart'; -import 'package:sit/session/sso.dart'; final _rand = Random(); @@ -19,12 +18,10 @@ class DioInit { if (!kIsWeb) { dio.interceptors.add(CookieManager(cookieJar)); } - if (kDebugMode) { - dio.interceptors.add(LogInterceptor(logPrint: (obj) { - networkLogger.i(obj); - })); - } if (kDebugMode && R.debugNetwork) { + dio.interceptors.add(LogInterceptor()); + } + if (kDebugMode && R.debugNetwork && R.poorNetworkSimulation) { dio.interceptors.add(PoorNetworkDioInterceptor()); } if (config != null) { diff --git a/lib/r.dart b/lib/r.dart index 5892628b5..a5abed141 100644 --- a/lib/r.dart +++ b/lib/r.dart @@ -24,6 +24,7 @@ class R { static const debugCupertino = kDebugMode ? false : false; static const debugNetwork = true; + static const poorNetworkSimulation = true; /// The default window size is small enough for any modern desktop device. static const Size defaultWindowSize = Size(500, 800); diff --git a/lib/session/sso.dart b/lib/session/sso.dart index 925cb031f..386830de1 100644 --- a/lib/session/sso.dart +++ b/lib/session/sso.dart @@ -74,6 +74,9 @@ class SsoSession { /// Lock it to prevent simultaneous login. static final _loginLock = Lock(); + /// Lock all requests through SSO. + static final _ssoLock = Lock(); + SsoSession({ required this.dio, required this.cookieJar, @@ -110,7 +113,6 @@ class SsoSession { ProgressCallback? onReceiveProgress, }) async { options ??= Options(); - Future requestNormally() async { final response = await dio.request( url, @@ -125,7 +127,14 @@ class SsoSession { onSendProgress: onSendProgress, onReceiveProgress: onReceiveProgress, ); - return await processRedirect(dio, response, headers: _neededHeaders); + final debugDepths = []; + final finalResponse = await processRedirect( + dio, + response, + headers: _neededHeaders, + debugDepths: debugDepths, + ); + return finalResponse; } // request normally at first @@ -327,17 +336,21 @@ class SsoSession { ProgressCallback? onSendProgress, ProgressCallback? onReceiveProgress, }) async { - try { - return await _request( - url, - queryParameters: para, - data: data, - options: options, - ); - } catch (error, stackTrace) { - debugPrintError(error, stackTrace); - rethrow; - } + networkLogger.i("$SsoSession.request ${DateTime.now().toIso8601String()}"); + return await _ssoLock.synchronized(() async { + networkLogger.i("$SsoSession.request-synchronized ${DateTime.now().toIso8601String()}"); + try { + return await _request( + url, + queryParameters: para, + data: data, + options: options, + ); + } catch (error, stackTrace) { + debugPrintError(error, stackTrace); + rethrow; + } + }); } } diff --git a/lib/utils/dio.dart b/lib/utils/dio.dart index b887e9300..bd12e128e 100644 --- a/lib/utils/dio.dart +++ b/lib/utils/dio.dart @@ -19,24 +19,28 @@ Future processRedirect( Dio dio, Response response, { Map? headers, + List? debugDepths, }) async { - //Prevent the redirect being processed by HttpClient, with the 302 response caught manually. + debugDepths?.add(response); + // Prevent the redirect being processed by HttpClient, with the 302 response caught manually. if (response.statusCode == 302 && response.headers['location'] != null && response.headers['location']!.isNotEmpty) { String location = response.headers['location']![0]; if (location.isEmpty) return response; if (!Uri.parse(location).isAbsolute) { location = '${response.requestOptions.uri.origin}/$location'; } + final redirectedResponse = await dio.get( + location, + options: disableRedirectFormEncodedOptions( + responseType: response.requestOptions.responseType, + headers: headers, + ), + ); return processRedirect( dio, - await dio.get( - location, - options: disableRedirectFormEncodedOptions( - responseType: response.requestOptions.responseType, - headers: headers, - ), - ), + redirectedResponse, headers: headers, + debugDepths: debugDepths, ); } else { return response;