Skip to content

Fix isOnline() to fall back to HTTP HEAD when DNS fails behind proxy#2635

Draft
nagilson wants to merge 7 commits intodotnet:mainfrom
nagilson:fix-isonline-proxy-awareness
Draft

Fix isOnline() to fall back to HTTP HEAD when DNS fails behind proxy#2635
nagilson wants to merge 7 commits intodotnet:mainfrom
nagilson:fix-isonline-proxy-awareness

Conversation

@nagilson
Copy link
Copy Markdown
Member

@nagilson nagilson commented Apr 9, 2026

In enterprise proxy environments, the client machine may not resolve external DNS directly — DNS resolution is handled by the proxy server. The existing DNS-only check in isOnline() would incorrectly report the machine as offline, causing unnecessary fallback to cached/offline installs.

When DNS resolution fails and the axios client is available, isOnline() now attempts a lightweight HEAD request to www.microsoft.com through the auto-detected (or manually configured) proxy. This ensures connectivity is correctly detected in proxy environments while keeping DNS as the fast-path for non-proxy setups.

#2594

@nagilson nagilson force-pushed the fix-isonline-proxy-awareness branch 2 times, most recently from 98b4071 to 0ae2206 Compare April 9, 2026 22:49
In enterprise proxy environments, the client machine may not resolve
external DNS directly — DNS resolution is handled by the proxy server.
The existing DNS-only check in isOnline() would incorrectly report the
machine as offline, causing unnecessary fallback to cached/offline installs.

When DNS resolution fails and the axios client is available, isOnline()
now attempts a lightweight HEAD request to www.microsoft.com through the
auto-detected (or manually configured) proxy. This ensures connectivity
is correctly detected in proxy environments while keeping DNS as the
fast-path for non-proxy setups.

Refactors GetProxyAgentIfNeeded by extracting proxy resolution into a
standalone getProxyAgent method that does not depend on IAcquisitionWorkerContext.
This allows isOnline and other callers without a full context to reuse
the same proxy detection logic without duplication.

Fixes dotnet#2594

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@nagilson nagilson force-pushed the fix-isonline-proxy-awareness branch from 0ae2206 to 665e82e Compare April 9, 2026 22:59
nagilson and others added 6 commits April 9, 2026 16:16
Reintroduce the helper method with a simplified signature that takes
proxyUrl directly instead of the full IAcquisitionWorkerContext, keeping
the code readable while maintaining the decoupled getProxyAgent design.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add optional proxyUrl parameter to isOnline() so callers with access to
the VS Code proxy setting can pass it through for the HTTP HEAD fallback.
All callsites with a workerContext now forward ctx.proxyUrl; the one
callsite without (LocalInstallUpdateService) still falls back to
auto-detection.

Consolidate the empty-string check into proxySettingConfiguredManually
so the duplicate validation in getProxyAgent is no longer needed.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Updated simulateOffline and simulateDnsOnlyFailure test helpers to emit
error codes matching real observed behavior when a Windows firewall
blocks node.exe outbound:
  - DNS: ETIMEOUT (queryA ETIMEOUT www.microsoft.com)
  - HTTP/HTTPS: EACCES with errno -4092, syscall connect

Verified by blocking node.exe via Windows Firewall and capturing actual
error shapes from dns.promises.Resolver, Axios, and axios-cache-interceptor.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add startLocalProxy() helper: stdlib-only HTTP CONNECT proxy (zero deps)
  using net + http modules, supports HTTPS tunneling for HttpsProxyAgent
- Add test: isOnline returns true via proxy when DNS is blocked
  (simulates enterprise proxy environment where client DNS fails)
- Add test: getCachedData succeeds through proxy when DNS is blocked
  (exercises full getAxiosOptions -> GetProxyAgentIfNeeded -> HttpsProxyAgent chain)
- Both tests use simulateDnsOnlyFailure() + local proxy with proper cleanup

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copy link
Copy Markdown
Member Author

@nagilson nagilson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems good, but want to take a 2nd look at the tests


const targetSocket = net.connect(port, host, () =>
{
clientSocket.write('HTTP/1.1 200 Connection Established\r\n\r\n');
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

need to review this still

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant