From 57eaa839602a3b2d36eae01a1702e9d239004b26 Mon Sep 17 00:00:00 2001 From: Liplum Date: Tue, 30 Apr 2024 18:04:30 +0800 Subject: [PATCH] fixed session lock issue (might e) --- lib/network/dio.dart | 16 ++++++++++-- lib/session/class2nd.dart | 7 +++-- lib/session/sso.dart | 55 +++++++++++++++++++++++---------------- pubspec.lock | 8 ++++++ pubspec.yaml | 1 + 5 files changed, 60 insertions(+), 27 deletions(-) diff --git a/lib/network/dio.dart b/lib/network/dio.dart index 990642496..a55832063 100644 --- a/lib/network/dio.dart +++ b/lib/network/dio.dart @@ -51,10 +51,19 @@ class DioInit { } } +final _debugRequests = []; +final _debugResponses = []; + class PoorNetworkDioInterceptor extends Interceptor { @override Future onRequest(RequestOptions options, RequestInterceptorHandler handler) async { - final duration = Duration(milliseconds: _rand.nextInt(5000)); + if(kDebugMode){ + _debugRequests.add(options); + } + if(options.path == "http://sc.sit.edu.cn//public/init/index.action" || options.path == "http://sc.sit.edu.cn/public/init/index.action"){ + print("!!!!!!!!!!"); + } + final duration = Duration(milliseconds: _rand.nextInt(2000)); debugPrint("Start to request ${options.uri}"); await Future.delayed(duration); debugPrint("Delayed Request ${options.uri} $duration"); @@ -63,7 +72,10 @@ class PoorNetworkDioInterceptor extends Interceptor { @override Future onResponse(Response response, ResponseInterceptorHandler handler) async { - final duration = Duration(milliseconds: _rand.nextInt(5000)); + if(kDebugMode){ + _debugResponses.add(response); + } + final duration = Duration(milliseconds: _rand.nextInt(2000)); debugPrint("Start to response ${response.realUri}"); await Future.delayed(duration); debugPrint("Delayed Response ${response.realUri} $duration"); diff --git a/lib/session/class2nd.dart b/lib/session/class2nd.dart index aad0229d8..0dcf04b0f 100644 --- a/lib/session/class2nd.dart +++ b/lib/session/class2nd.dart @@ -1,4 +1,5 @@ import 'package:dio/dio.dart'; +import 'package:sit/init.dart'; import 'package:sit/session/sso.dart'; class Class2ndSession { @@ -33,13 +34,15 @@ class Class2ndSession { final responseData = res.data; // 如果返回值是登录页面,那就从 SSO 跳转一次以登录. if (responseData is String && _needRedirectToLoginPage(responseData)) { - await ssoSession.request( + await Init.cookieJar.delete(Uri.parse(url), true); + // the response has been already redirected to the originally-requested one. + res = await ssoSession.request( 'https://authserver.sit.edu.cn/authserver/login?service=http%3A%2F%2Fsc.sit.edu.cn%2Flogin.jsp', options: Options( method: "GET", ), ); - res = await fetch(); + // res = await fetch(); } return res; } diff --git a/lib/session/sso.dart b/lib/session/sso.dart index 386830de1..f63f66e08 100644 --- a/lib/session/sso.dart +++ b/lib/session/sso.dart @@ -1,5 +1,6 @@ import 'dart:math'; +import 'package:async_locks/async_locks.dart'; import 'package:beautiful_soup_dart/beautiful_soup.dart'; import 'package:collection/collection.dart'; import 'package:cookie_jar/cookie_jar.dart'; @@ -16,7 +17,6 @@ import 'package:sit/r.dart'; import 'package:sit/session/auth.dart'; import 'package:sit/utils/error.dart'; import 'package:sit/utils/riverpod.dart'; -import 'package:synchronized/synchronized.dart'; import 'package:encrypt/encrypt.dart'; import '../utils/dio.dart'; @@ -85,7 +85,7 @@ class SsoSession { /// - User try to log in actively on a login page. Future loginLocked(Credentials credentials) async { - return await _loginLock.synchronized(() async { + return await _loginLock.run(() async { networkLogger.i("loginLocked ${DateTime.now().toIso8601String()}"); try { final byAutoCaptcha = await _login( @@ -306,26 +306,35 @@ class SsoSession { /// Login the single sign-on Future _postLoginRequest(String username, String hashedPassword, String captcha, String casTicket) async { // Login - final res = await dio.post(_loginUrl, - data: { - 'username': username, - 'password': hashedPassword, - 'captchaResponse': captcha, - 'lt': casTicket, - 'dllt': 'userNamePasswordLogin', - 'execution': 'e1s1', - '_eventId': 'submit', - 'rmShown': '1', + final res = await dio.post( + _loginUrl, + data: { + 'username': username, + 'password': hashedPassword, + 'captchaResponse': captcha, + 'lt': casTicket, + 'dllt': 'userNamePasswordLogin', + 'execution': 'e1s1', + '_eventId': 'submit', + 'rmShown': '1', + }, + options: Options( + contentType: Headers.formUrlEncodedContentType, + followRedirects: false, + validateStatus: (status) { + return status! < 400; }, - options: Options( - contentType: Headers.formUrlEncodedContentType, - followRedirects: false, - validateStatus: (status) { - return status! < 400; - }, - headers: _neededHeaders, - )); - return await processRedirect(dio, res, headers: _neededHeaders); + headers: _neededHeaders, + ), + ); + final debugDepths = []; + final finalResponse = await processRedirect( + dio, + res, + headers: _neededHeaders, + debugDepths: debugDepths, + ); + return finalResponse; } Future request( @@ -337,8 +346,8 @@ class SsoSession { ProgressCallback? onReceiveProgress, }) async { networkLogger.i("$SsoSession.request ${DateTime.now().toIso8601String()}"); - return await _ssoLock.synchronized(() async { - networkLogger.i("$SsoSession.request-synchronized ${DateTime.now().toIso8601String()}"); + return await _ssoLock.run(() async { + networkLogger.i("$SsoSession.request-locked ${DateTime.now().toIso8601String()}"); try { return await _request( url, diff --git a/pubspec.lock b/pubspec.lock index 97cd68fb9..e8a87dd09 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -89,6 +89,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.11.0" + async_locks: + dependency: "direct main" + description: + name: async_locks + sha256: "11578df083ce7de82a4a76e14532169eee46ce85ed094a54b05317934164800c" + url: "https://pub.dev" + source: hosted + version: "3.4.0" audio_session: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 0158174c4..7d4717442 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -152,6 +152,7 @@ dependencies: rettulf: ^2.0.1 # lock synchronized: ^3.1.0+1 + async_locks: ^3.4.0 # parse stacktrace stack_trace: ^1.11.0 email_validator: ^2.1.17