Add a validator to ensure NO_PROXY is set correctly if HTTP_PROXY is set (#25974)

* Add a validator to ensure NO_PROXY is set correctly if HTTP_PROXY is set

Fixes #24854.

* Fix typo

* Dummy edit to try and force update of PR desc on Cirrus
diff --git a/packages/flutter_tools/lib/src/proxy_validator.dart b/packages/flutter_tools/lib/src/proxy_validator.dart
new file mode 100644
index 0000000..211a9d5
--- /dev/null
+++ b/packages/flutter_tools/lib/src/proxy_validator.dart
@@ -0,0 +1,55 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'dart:async';
+
+import 'base/platform.dart';
+import 'doctor.dart';
+
+class ProxyValidator extends DoctorValidator {
+  ProxyValidator() : super('Proxy Configuration');
+
+  static bool get shouldShow => _getEnv('HTTP_PROXY').isNotEmpty;
+
+  final String _httpProxy = _getEnv('HTTP_PROXY');
+  final String _noProxy = _getEnv('NO_PROXY');
+
+  /// Gets a trimmed, non-null environment variable. If the variable is not set
+  /// an empty string will be returned. Checks for the lowercase version of the
+  /// environment variable first, then uppercase to match Dart's HTTP implementation.
+  static String _getEnv(String key) =>
+      platform.environment[key.toLowerCase()]?.trim() ??
+      platform.environment[key.toUpperCase()]?.trim() ??
+      '';
+
+  @override
+  Future<ValidationResult> validate() async {
+    final List<ValidationMessage> messages = <ValidationMessage>[];
+
+    if (_httpProxy.isNotEmpty) {
+      messages.add(ValidationMessage('HTTP_PROXY is set'));
+
+      if (_noProxy.isEmpty) {
+        messages.add(ValidationMessage.hint('NO_PROXY is not set'));
+      } else {
+        messages.add(ValidationMessage('NO_PROXY is $_noProxy'));
+        for (String host in const <String>['127.0.0.1', 'localhost']) {
+          final ValidationMessage msg = _noProxy.contains(host)
+              ? ValidationMessage('NO_PROXY contains $host')
+              : ValidationMessage.hint('NO_PROXY does not contain $host');
+
+          messages.add(msg);
+        }
+      }
+    }
+
+    final bool hasIssues =
+        messages.any((ValidationMessage msg) => msg.isHint || msg.isHint);
+
+    return ValidationResult(
+      hasIssues ? ValidationType.partial : ValidationType.installed,
+      messages,
+    );
+  }
+}