Skip to content

Commit 63a1478

Browse files
zandersocommit-bot@chromium.org
authored andcommitted
[dart:io] Handle http timeout race
In http connection setup, when an explicit connection timeout is set on the client, the onTimeout callback on the socket future caused the future to be completed with null. If the 'then' callback on the socket future ran before the error completer on the connection task, then a NoSuchMethod error would result. This CL addresses this issue by checking for null in the 'then' callback on the socket future, and generating an appropriate exception. fixes flutter/flutter#32578 Change-Id: If2e60b1355aa3d80622c644dada8a62a24469567 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/112742 Reviewed-by: Siva Annamalai <asiva@google.com> Commit-Queue: Zach Anderson <zra@google.com>
1 parent 9eb2e8d commit 63a1478

File tree

1 file changed

+15
-3
lines changed

1 file changed

+15
-3
lines changed

sdk/lib/_http/http_impl.dart

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1990,14 +1990,26 @@ class _ConnectionTarget {
19901990
return connectionTask.then((ConnectionTask task) {
19911991
_socketTasks.add(task);
19921992
Future socketFuture = task.socket;
1993-
if (client.connectionTimeout != null) {
1994-
socketFuture =
1995-
socketFuture.timeout(client.connectionTimeout, onTimeout: () {
1993+
final Duration connectionTimeout = client.connectionTimeout;
1994+
if (connectionTimeout != null) {
1995+
socketFuture = socketFuture.timeout(connectionTimeout, onTimeout: () {
19961996
_socketTasks.remove(task);
19971997
task.cancel();
1998+
return null;
19981999
});
19992000
}
20002001
return socketFuture.then((socket) {
2002+
// When there is a timeout, there is a race in which the connectionTask
2003+
// Future won't be completed with an error before the socketFuture here
2004+
// is completed with 'null' by the onTimeout callback above. In this
2005+
// case, propagate a SocketException as specified by the
2006+
// HttpClient.connectionTimeout docs.
2007+
if (socket == null) {
2008+
assert(connectionTimeout != null);
2009+
throw new SocketException(
2010+
"HTTP connection timed out after ${connectionTimeout}, "
2011+
"host: ${host}, port: ${port}");
2012+
}
20012013
_connecting--;
20022014
socket.setOption(SocketOption.tcpNoDelay, true);
20032015
var connection =

0 commit comments

Comments
 (0)