From c1fa94951a209911ecddbabd2743272aef90d2c5 Mon Sep 17 00:00:00 2001 From: Moritz Date: Fri, 8 Sep 2023 17:41:32 +0200 Subject: [PATCH] Fix regression on fetching the remote address of a closed socket. (#664) * Fix regression on fetching the remote address of a closed socket * Changes as per review * Add changelog entry * Rev version for publish --- CHANGELOG.md | 3 +- lib/src/server/server.dart | 56 ++++++++++++++++++++++++-------------- pubspec.yaml | 2 +- 3 files changed, 38 insertions(+), 23 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6f88c542..e1332dc5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,9 @@ -## 3.2.4-wip +## 3.2.4 * Forward internal `GrpcError` on when throwing while sending a request. * Add support for proxies, see [#33](https://github.com/grpc/grpc-dart/issues/33). * Remove canceled `ServerHandler`s from tracking list. +* Fix regression on fetching the remote address of a closed socket. ## 3.2.3 diff --git a/lib/src/server/server.dart b/lib/src/server/server.dart index f571230a..bc40edb0 100644 --- a/lib/src/server/server.dart +++ b/lib/src/server/server.dart @@ -241,28 +241,33 @@ class Server extends ConnectionServer { bool requireClientCertificate = false, }) async { // TODO(dart-lang/grpc-dart#9): Handle HTTP/1.1 upgrade to h2c, if allowed. - Stream? server; + Stream server; final securityContext = security?.securityContext; if (securityContext != null) { - _secureServer = await SecureServerSocket.bind( - address ?? InternetAddress.anyIPv4, port ?? 443, securityContext, - backlog: backlog, - shared: shared, - v6Only: v6Only, - requestClientCertificate: requestClientCertificate, - requireClientCertificate: requireClientCertificate); - server = _secureServer; + final _server = await SecureServerSocket.bind( + address ?? InternetAddress.anyIPv4, + port ?? 443, + securityContext, + backlog: backlog, + shared: shared, + v6Only: v6Only, + requestClientCertificate: requestClientCertificate, + requireClientCertificate: requireClientCertificate, + ); + _secureServer = _server; + server = _server; } else { - _insecureServer = await ServerSocket.bind( + final _server = await ServerSocket.bind( address ?? InternetAddress.anyIPv4, port ?? 80, backlog: backlog, shared: shared, v6Only: v6Only, ); - server = _insecureServer; + _insecureServer = _server; + server = _server; } - server!.listen((socket) { + server.listen((socket) { // Don't wait for io buffers to fill up before sending requests. if (socket.address.type != InternetAddressType.unix) { socket.setOption(SocketOption.tcpNoDelay, true); @@ -282,7 +287,7 @@ class Server extends ConnectionServer { serveConnection( connection: connection, clientCertificate: clientCertificate, - remoteAddress: socket.remoteAddress, + remoteAddress: socket.remoteAddressOrNull, ); }, onError: (error, stackTrace) { if (error is Error) { @@ -320,15 +325,24 @@ class Server extends ConnectionServer { } Future shutdown() async { - final done = _connections.map((connection) => connection.finish()).toList(); - if (_insecureServer != null) { - done.add(_insecureServer!.close()); - } - if (_secureServer != null) { - done.add(_secureServer!.close()); - } - await Future.wait(done); + await Future.wait([ + for (var connection in _connections) connection.finish(), + if (_insecureServer != null) _insecureServer!.close(), + if (_secureServer != null) _secureServer!.close(), + ]); _insecureServer = null; _secureServer = null; } } + +extension on Socket { + InternetAddress? get remoteAddressOrNull { + try { + // Using a try-catch control flow as dart:io Sockets don't expose their + // connectivity state. + return remoteAddress; + } on Exception catch (_) { + return null; + } + } +} diff --git a/pubspec.yaml b/pubspec.yaml index 5b4f6050..ba84fd5f 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: grpc description: Dart implementation of gRPC, a high performance, open-source universal RPC framework. -version: 3.2.4-wip +version: 3.2.4 repository: https://github.com/grpc/grpc-dart