Skip to content

Commit

Permalink
add sendTimeout and receiveTimeout in Http2Adapter (#1942)
Browse files Browse the repository at this point in the history
Add send time out and receive time for http2

### New Pull Request Checklist

- [x] I have read the
[Documentation](https://pub.dev/documentation/dio/latest/)
- [x] I have searched for a similar pull request in the
[project](https://github.com/cfug/dio/pulls) and found none
- [x] I have updated this branch with the latest `main` branch to avoid
conflicts (via merge from master or rebase)
- [x] I have added the required tests to prove the fix/feature I'm
adding
- [ ] I have updated the documentation (if necessary)
- [x] I have run the tests without failures
- [x] I have updated the `CHANGELOG.md` in the corresponding package

### Additional context and info (if any)

Http2Adapter only implements connect timeout,the
`RequestOptions.sendTimeout` and `RequestOptions.receiveTimeout` not
work.

---------

Signed-off-by: sunhapper <[email protected]>
Co-authored-by: Alex Li <[email protected]>
  • Loading branch information
sunhapper and AlexV525 authored Aug 25, 2023
1 parent 3ad3947 commit f4d0052
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 4 deletions.
2 changes: 1 addition & 1 deletion plugins/http2_adapter/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## Unreleased

*None.*
- Implement `sendTimeout` and `receiveTimeout` for the adapter.

## 2.3.1+1

Expand Down
33 changes: 30 additions & 3 deletions plugins/http2_adapter/lib/src/http2_adapter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -89,11 +89,24 @@ class Http2Adapter implements HttpClientAdapter {
}

if (hasRequestData) {
await requestStream!.listen((data) {
final requestStreamFuture = requestStream!.listen((data) {
stream.outgoingMessages.add(DataStreamMessage(data));
}).asFuture();
final sendTimeout = options.sendTimeout;
if (sendTimeout != null) {
await requestStreamFuture.timeout(
sendTimeout,
onTimeout: () {
throw DioException.sendTimeout(
timeout: sendTimeout,
requestOptions: options,
);
},
);
} else {
await requestStreamFuture;
}
}

await stream.outgoingMessages.close();

final sc = StreamController<Uint8List>();
Expand Down Expand Up @@ -145,7 +158,21 @@ class Http2Adapter implements HttpClientAdapter {
cancelOnError: true,
);

await completer.future;
final receiveTimeout = options.receiveTimeout;
if (receiveTimeout != null) {
await completer.future.timeout(
receiveTimeout,
onTimeout: () {
subscription.cancel().whenComplete(() => sc.close());
throw DioException.receiveTimeout(
timeout: receiveTimeout,
requestOptions: options,
);
},
);
} else {
await completer.future;
}

// Handle redirection
if (needRedirect) {
Expand Down
41 changes: 41 additions & 0 deletions plugins/http2_adapter/test/http2_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -76,4 +76,45 @@ void main() {
final res = await dio.post('post', data: 'TEST');
expect(res.data.toString(), contains('TEST'));
});

test('catch DioException when receiveTimeout', () {
final dio = Dio(
BaseOptions(
baseUrl: 'https://httpbun.com/',
receiveTimeout: Duration(seconds: 5),
),
);
dio.httpClientAdapter = Http2Adapter(
ConnectionManager(
idleTimeout: Duration(milliseconds: 10),
),
);

expectLater(
dio.get('/drip?delay=10&numbytes=1'),
allOf([
throwsA(isA<DioException>()),
throwsA(predicate(
(DioException e) => e.type == DioExceptionType.receiveTimeout)),
throwsA(predicate(
(DioException e) => e.message!.contains('0:00:05.000000'))),
]),
);
});

test('no DioException when receiveTimeout > request duration', () async {
final dio = Dio(
BaseOptions(
baseUrl: 'https://httpbun.com/',
receiveTimeout: Duration(seconds: 5),
),
);
dio.httpClientAdapter = Http2Adapter(
ConnectionManager(
idleTimeout: Duration(milliseconds: 10),
),
);

await dio.get('/drip?delay=1&numbytes=1');
});
}

0 comments on commit f4d0052

Please sign in to comment.