From c39a03a2b4d5598357153677033d51ffb8078431 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Mon, 24 Oct 2016 15:13:04 -0700 Subject: [PATCH] Work in IPv6-only environments. --- CHANGELOG.md | 5 +++++ lib/http_multi_server.dart | 8 ++++++-- lib/src/utils.dart | 22 +++++++++++++--------- pubspec.yaml | 2 +- test/http_multi_server_test.dart | 13 +++++++------ 5 files changed, 32 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5e45056..a3cb13f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +## 2.0.3 + +* Fix `HttpMultiServer.loopback()` and `.loopbackSecure()` for environments that + don't support IPv4. + ## 2.0.2 * Fix a dependency that was incorrectly marked as dev-only. diff --git a/lib/http_multi_server.dart b/lib/http_multi_server.dart index 18d42cf..1f5bddd 100644 --- a/lib/http_multi_server.dart +++ b/lib/http_multi_server.dart @@ -124,10 +124,14 @@ class HttpMultiServer extends StreamView implements HttpServer { static Future _loopback(int port, Future bind(InternetAddress address, int port), [int remainingRetries]) async { - if (remainingRetries == null) remainingRetries = 5; + remainingRetries ??= 5; + + if (!await supportsIPv4) { + return await bind(InternetAddress.LOOPBACK_IP_V6, port); + } var v4Server = await bind(InternetAddress.LOOPBACK_IP_V4, port); - if (!await supportsIpV6) return v4Server; + if (!await supportsIPv6) return v4Server; try { // Reuse the IPv4 server's port so that if [port] is 0, both servers use diff --git a/lib/src/utils.dart b/lib/src/utils.dart index 19188cb..21c335c 100644 --- a/lib/src/utils.dart +++ b/lib/src/utils.dart @@ -5,20 +5,24 @@ import 'dart:async'; import 'dart:io'; -/// A cache for [supportsIpV6]. -bool _supportsIpV6; - /// Returns whether this computer supports binding to IPv6 addresses. -Future get supportsIpV6 async { - if (_supportsIpV6 != null) return _supportsIpV6; - +final Future supportsIPv6 = () async { try { var socket = await ServerSocket.bind(InternetAddress.LOOPBACK_IP_V6, 0); - _supportsIpV6 = true; socket.close(); return true; } on SocketException catch (_) { - _supportsIpV6 = false; return false; } -} +}(); + +/// Returns whether this computer supports binding to IPv4 addresses. +final Future supportsIPv4 = () async { + try { + var socket = await ServerSocket.bind(InternetAddress.LOOPBACK_IP_V4, 0); + socket.close(); + return true; + } on SocketException catch (_) { + return false; + } +}(); diff --git a/pubspec.yaml b/pubspec.yaml index 37bb75e..9beaa7d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: http_multi_server -version: 2.0.2 +version: 2.0.3 author: "Dart Team " homepage: http://github.com/dart-lang/http_multi_server description: diff --git a/test/http_multi_server_test.dart b/test/http_multi_server_test.dart index 4aacab1..9468cfe 100644 --- a/test/http_multi_server_test.dart +++ b/test/http_multi_server_test.dart @@ -140,20 +140,21 @@ void main() { tearDown(() => server.close()); - test("listens on all localhost interfaces", () { + test("listens on all localhost interfaces", () async { server.listen((request) { request.response.write("got request"); request.response.close(); }); - expect(http.read("http://127.0.0.1:${server.port}/"), - completion(equals("got request"))); + if (await supportsIPv4) { + expect(http.read("http://127.0.0.1:${server.port}/"), + completion(equals("got request"))); + } - return supportsIpV6.then((supportsIpV6) { - if (!supportsIpV6) return; + if (await supportsIPv4) { expect(http.read("http://[::1]:${server.port}/"), completion(equals("got request"))); - }); + } }); }); }