node-zwave-js icon indicating copy to clipboard operation
node-zwave-js copied to clipboard

feat: add proxy support for outbound HTTP(S) requests

Open Copilot opened this issue 1 month ago • 3 comments

Adds support for HTTP_PROXY and HTTPS_PROXY environment variables for all outgoing HTTP requests by extending ky with undici's EnvHttpProxyAgent.

Changes

  • New zwave-js module: Added getHttpClient() in packages/zwave-js/src/lib/driver/httpClient.ts which returns a proxy-aware ky instance
    • Uses dynamic imports for undici with graceful fallback to plain ky in non-Node.js environments (e.g., browsers)
    • Promise-based memoization prevents race conditions during concurrent initialization
  • Updated HTTP request sites in zwave-js to use the new client:
    • Config update downloads (UpdateConfig.ts)
    • Firmware update service (FirmwareUpdateService.ts)
    • Telemetry reporting (statistics.ts)
  • Added undici dependency to the zwave-js package

Usage

export HTTP_PROXY=http://proxy.example.com:8080
export HTTPS_PROXY=http://proxy.example.com:8080

All outbound requests from the zwave-js runtime will automatically route through the configured proxy.

  • Fixes zwave-js/zwave-js#8452
Original prompt

This section details on the original issue you should resolve

<issue_title>Add proxy support for outbound HTTP(S) requests</issue_title> <issue_description>

Discussed in https://github.com/zwave-js/zwave-js/discussions/8445

Originally posted by l3s2d November 21, 2025

Description

Currently outbound HTTP(S) requests made by zwave-js, don't respect HTTP_PROXY and HTTPS_PROXY.

I'm running zwave-js-ui in docker with the HTTP_PROXY and HTTPS_PROXY envvars set to a Squid instance. Checking for OTA Updates (getAvailableFirmwareUpdates) does not use the proxy. I verified by checking the Squid logs and also by blocking egress traffic outside of Squid.

Do you have a solution in mind?

I'm not familiar with zwave-js' codebase, but I suspect the library it uses for outbound requests supports using a proxy.

Describe alternatives you've considered

No response

Additional context

No response

</issue_description>

<agent_instructions>Add support for the HTTP_PROXY and HTTPS_PROXY env variables for outgoing requests by extending ky as outlined in the 2nd comment.</agent_instructions>

Comments on the Issue (you are @copilot in this section)

@AlCalzone We need to add `undici` for this, so `ky` can use it:

Using EnvHttpProxyAgent to automatically read proxy settings from environment variables:

import ky from 'ky';
import {EnvHttpProxyAgent} from 'undici';

const proxyAgent = new EnvHttpProxyAgent();

const api = ky.extend({
	// @ts-expect-error - dispatcher is not in the type definition, but it's passed through to fetch.
	dispatcher: proxyAgent
});

const response = await api('https://example.com').json();
```</body></comment_new>
</comments>

  • Fixes zwave-js/zwave-js#8452

💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot avatar Nov 25 '25 14:11 Copilot

@copilot Let's keep the httpclient in the zwave-js module. It is only used there at runtime. The usages in packages/config/maintenance/importConfig.ts are at development time and do not need proxy...

Moved httpClient to packages/zwave-js/src/lib/driver/httpClient.ts, reverted changes to importConfig.ts, and added dynamic loading for undici with a graceful fallback to plain ky in non-Node.js environments (commit 3c48f85, 98ded96).

Copilot avatar Nov 25 '25 18:11 Copilot

💡 The pull request title does not match our guidelines 💡

We follow conventional commits, check out the description and examples. This means that the PR title must...

  • start with the type of change, e.g. feat:, or fix:
  • optionally specify a scope, for example we use config for changes to config files: feat(config):
  • contain a description that explains what is being changed, e.g. add a parameter, correct a typo, ...
  • and ideally explains what the change affects, e.g. the device (manufacturer, device label, firmware, ...)

The description should use uppercase and lowercase normally, except for the first character which must be lowercase.


How about this title instead?

feat(zwave-js): add proxy support for outbound HTTP(S) requests

zwave-js-assistant[bot] avatar Nov 25 '25 20:11 zwave-js-assistant[bot]

TODO: Test that this works everywhere.

AlCalzone avatar Nov 25 '25 20:11 AlCalzone