From ab73047e51a23af657aaf6379d5bbad390a8cee8 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Tue, 6 Sep 2022 21:18:07 +0200 Subject: [PATCH] fix: timeout when sending large files fixes https://gitlab.com/famedly/company/frontend/famedly-web/-/issues/540 --- lib/src/client.dart | 4 +-- lib/src/utils/http_timeout.dart | 59 ++------------------------------- 2 files changed, 4 insertions(+), 59 deletions(-) diff --git a/lib/src/client.dart b/lib/src/client.dart index 4890e5bb..f709b53b 100644 --- a/lib/src/client.dart +++ b/lib/src/client.dart @@ -189,8 +189,8 @@ class Client extends MatrixApi { ? NativeImplementationsIsolate(compute) : nativeImplementations, super( - httpClient: - VariableTimeoutHttpClient(httpClient ?? http.Client())) { + httpClient: FixedTimeoutHttpClient( + httpClient ?? http.Client(), Duration(seconds: 35))) { if (logLevel != null) Logs().level = logLevel; importantStateEvents.addAll([ EventTypes.RoomName, diff --git a/lib/src/utils/http_timeout.dart b/lib/src/utils/http_timeout.dart index 943c33cd..de0d745f 100644 --- a/lib/src/utils/http_timeout.dart +++ b/lib/src/utils/http_timeout.dart @@ -20,19 +20,6 @@ import 'dart:async'; import 'package:http/http.dart' as http; -import 'package:matrix/matrix.dart'; - -/// Stream.timeout fails if no progress is made in timeLimit. -/// In contrast, streamTotalTimeout fails if the stream isn't completed -/// until timeoutFuture. -Stream streamTotalTimeout( - Stream stream, Future timeoutFuture) async* { - final si = StreamIterator(stream); - while (await Future.any([si.moveNext(), timeoutFuture])) { - yield si.current; - } -} - http.StreamedResponse replaceStream( http.StreamedResponse base, Stream> stream) => http.StreamedResponse( @@ -57,10 +44,8 @@ abstract class TimeoutHttpClient extends http.BaseClient { @override Future send(http.BaseRequest request) async { - final timeoutFuture = Completer().future.timeout(timeout); - final response = await Future.any([inner.send(request), timeoutFuture]); - return replaceStream( - response, streamTotalTimeout(response.stream, timeoutFuture)); + final response = await inner.send(request); + return replaceStream(response, response.stream.timeout(timeout)); } } @@ -69,43 +54,3 @@ class FixedTimeoutHttpClient extends TimeoutHttpClient { @override Duration timeout; } - -class VariableTimeoutHttpClient extends TimeoutHttpClient { - /// Matrix synchronisation is done with https long polling. This needs a - /// timeout which is usually 30 seconds. - int syncTimeoutSec; - - int _timeoutFactor = 1; - - @override - Duration get timeout => - Duration(seconds: _timeoutFactor * syncTimeoutSec + 5); - - VariableTimeoutHttpClient(http.Client inner, [this.syncTimeoutSec = 30]) - : super(inner); - - @override - Future send(http.BaseRequest request) async { - try { - final response = await super.send(request); - return replaceStream(response, (() async* { - try { - await for (final chunk in response.stream) { - yield chunk; - } - _timeoutFactor = 1; - } on TimeoutException catch (e, s) { - _timeoutFactor *= 2; - throw MatrixConnectionException(e, s); - } catch (e, s) { - throw MatrixConnectionException(e, s); - } - })()); - } on TimeoutException catch (e, s) { - _timeoutFactor *= 2; - throw MatrixConnectionException(e, s); - } catch (e, s) { - throw MatrixConnectionException(e, s); - } - } -}