|
21 | 21 | import subprocess |
22 | 22 | import sys |
23 | 23 | from pathlib import Path |
| 24 | +from urllib.parse import urlparse |
24 | 25 |
|
25 | 26 | from platformio.package.version import pepver_to_semver |
26 | 27 | from platformio.compat import IS_WINDOWS |
|
60 | 61 | } |
61 | 62 |
|
62 | 63 |
|
63 | | -def has_internet_connection(host="1.1.1.1", port=53, timeout=2): |
| 64 | +def has_internet_connection(timeout=5): |
64 | 65 | """ |
65 | | - Checks if an internet connection is available (default: Cloudflare DNS server). |
66 | | - Returns True if a connection is possible, otherwise False. |
| 66 | + Checks practical internet reachability for dependency installation. |
| 67 | + 1) If HTTPS/HTTP proxy environment variable is set, test TCP connectivity to the proxy endpoint. |
| 68 | + 2) Otherwise, test direct TCP connectivity to common HTTPS endpoints (port 443). |
| 69 | + |
| 70 | + Args: |
| 71 | + timeout (int): Timeout duration in seconds for the connection test. |
| 72 | +
|
| 73 | + Returns: |
| 74 | + True if at least one path appears reachable; otherwise False. |
67 | 75 | """ |
68 | | - try: |
69 | | - with socket.create_connection((host, port), timeout=timeout): |
| 76 | + # 1) Test TCP connectivity to the proxy endpoint. |
| 77 | + proxy = os.getenv("HTTPS_PROXY") or os.getenv("https_proxy") or os.getenv("HTTP_PROXY") or os.getenv("http_proxy") |
| 78 | + if proxy: |
| 79 | + try: |
| 80 | + u = urlparse(proxy if "://" in proxy else f"http://{proxy}") |
| 81 | + host = u.hostname |
| 82 | + port = u.port or (443 if u.scheme == "https" else 80) |
| 83 | + if host and port: |
| 84 | + socket.create_connection((host, port), timeout=timeout).close() |
| 85 | + return True |
| 86 | + except Exception: |
| 87 | + # If proxy connection fails, fall back to direct connection test |
| 88 | + pass |
| 89 | + |
| 90 | + # 2) Test direct TCP connectivity to common HTTPS endpoints (port 443). |
| 91 | + https_hosts = ("pypi.org", "files.pythonhosted.org", "github.com") |
| 92 | + for host in https_hosts: |
| 93 | + try: |
| 94 | + socket.create_connection((host, 443), timeout=timeout).close() |
70 | 95 | return True |
71 | | - except OSError: |
72 | | - return False |
| 96 | + except Exception: |
| 97 | + continue |
| 98 | + |
| 99 | + # Direct DNS:53 connection is abolished due to many false positives on enterprise networks |
| 100 | + # (add it at the end if necessary) |
| 101 | + return False |
73 | 102 |
|
74 | 103 |
|
75 | 104 | def get_executable_path(penv_dir, executable_name): |
|
0 commit comments