| // Copyright 2014 The Flutter 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 'base/io.dart'; |
| import 'base/platform.dart'; |
| import 'doctor_validator.dart'; |
| |
| /// A validator that displays configured HTTP_PROXY environment variables. |
| /// |
| /// if the `HTTP_PROXY` environment variable is non-empty, the contents are |
| /// validated along with `NO_PROXY`. |
| class ProxyValidator extends DoctorValidator { |
| ProxyValidator({ |
| required Platform platform, |
| }) : shouldShow = _getEnv('HTTP_PROXY', platform).isNotEmpty, |
| _httpProxy = _getEnv('HTTP_PROXY', platform), |
| _noProxy = _getEnv('NO_PROXY', platform), |
| super('Proxy Configuration'); |
| |
| final bool shouldShow; |
| final String _httpProxy; |
| final String _noProxy; |
| |
| /// 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 platform) => |
| platform.environment[key.toLowerCase()]?.trim() ?? |
| platform.environment[key.toUpperCase()]?.trim() ?? |
| ''; |
| |
| @override |
| Future<ValidationResult> validate() async { |
| if (_httpProxy.isEmpty) { |
| return const ValidationResult( |
| ValidationType.success, <ValidationMessage>[]); |
| } |
| |
| final List<ValidationMessage> messages = <ValidationMessage>[ |
| const ValidationMessage('HTTP_PROXY is set'), |
| if (_noProxy.isEmpty) |
| const ValidationMessage.hint('NO_PROXY is not set') |
| else |
| ...<ValidationMessage>[ |
| ValidationMessage('NO_PROXY is $_noProxy'), |
| for (final String host in await _getLoopbackAddresses()) |
| if (_noProxy.contains(host)) |
| ValidationMessage('NO_PROXY contains $host') |
| else |
| ValidationMessage.hint('NO_PROXY does not contain $host'), |
| ], |
| ]; |
| |
| final bool hasIssues = messages.any( |
| (ValidationMessage msg) => msg.isHint || msg.isError); |
| |
| return ValidationResult( |
| hasIssues ? ValidationType.partial : ValidationType.success, |
| messages, |
| ); |
| } |
| |
| Future<List<String>> _getLoopbackAddresses() async { |
| final List<String> loopBackAddresses = <String>['localhost']; |
| |
| final List<NetworkInterface> networkInterfaces = |
| await listNetworkInterfaces(includeLinkLocal: true, includeLoopback: true); |
| |
| for (final NetworkInterface networkInterface in networkInterfaces) { |
| for (final InternetAddress internetAddress in networkInterface.addresses) { |
| if (internetAddress.isLoopback) { |
| loopBackAddresses.add(internetAddress.address); |
| } |
| } |
| } |
| |
| return loopBackAddresses; |
| } |
| } |