Commit Graph
8 Commits
Author SHA1 Message Date
Joyee Cheung fd3419178e http: document and validate options.path when it's in absolute-form
When `options.path` passed to `http.request()` contains an absolute
URL, `http.request` has been sending it directly as the request target
in the HTTP 1.1 message. If the receiving server is a proxy,
the proxy server typically forwards the request to the destination
specified in the request target and ignores the Host header.
This means eventually the request can be forwarded to a destination
that is not consistent with `options.host`, depending on how the
receiving server behaves. Mimatched Host header and request target
also violates RFC 9112 Section 3.2, which we have been entirely
leaving to the users to verify.

This patch documents this behavior and warns that the user needs
to ensure the `path`, `option` and `headers` conform to the RFC.
If the receiving server is known to be a proxy server because
the request is routed by Node.js' built-in HTTP proxy support,
we now do a best-effort check to verify that the authority in
`options.path` (if absolute), Host headers and `options.host`
agree at request construction time. Node.js will give up on the
require target rewriting and throw an error when they don't match
at request construction.

Signed-off-by: Joyee Cheung <joyeec9h3@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/64108
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Tim Perry <pimterry@gmail.com>
Reviewed-By: Ulises Gascón <ulisesgascongonzalez@gmail.com>
2026-07-01 10:44:52 +00:00
Joyee Cheung c0108bfc55 http: add http.setGlobalProxyFromEnv()
This adds an API to dynamically enable built-in proxy support
for all of fetch() and http.request()/https.request(), so
that users do not have to be aware of them all and configure them
one by one.

PR-URL: https://github.com/nodejs/node/pull/60953
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Tim Perry <pimterry@gmail.com>
2025-12-10 16:12:28 +00:00
Joyee Cheung 81af7b93c5 http,https: handle IPv6 with proxies
This simplifies the proxy configuration handling code,
 adds tests to make sure the proxy support works with IPv6
and throws correct errors for invalid proxy IPs.
Drive-by: remove useless properties from ProxyConfig

PR-URL: https://github.com/nodejs/node/pull/59894
Refs: https://github.com/nodejs/node/issues/57872
Reviewed-By: Aditi Singh <aditisingh1400@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
2025-09-22 23:19:26 +00:00
Joyee Cheung 5c7b83a94e test: guard write to proxy client if proxy connection is ended
In the testing proxy server for proxy client tests, the proxy
client might have already closed the connection when the upstream
connection fails. In that case, there's no need for the proxy
server to inform the proxy client about the error.

PR-URL: https://github.com/nodejs/node/pull/59742
Fixes: https://github.com/nodejs/node/issues/59741
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
2025-09-17 13:59:09 +00:00
Joyee Cheung 0259df9faf cli: add --use-env-proxy
This does the same as NODE_USE_ENV_PROXY. When both are set,
like other options that can be configured from both sides,
the CLI flag takes precedence.

PR-URL: https://github.com/nodejs/node/pull/59151
Fixes: https://github.com/nodejs/node/issues/59100
Reviewed-By: Ilyas Shabi <ilyasshabi94@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
2025-07-26 20:43:10 +00:00
Joyee Cheung 036b1fd66d http,https: add built-in proxy support in http/https.request and Agent
This patch implements proxy support for HTTP and HTTPS clients and
agents in the `http` and `https` built-ins`. When NODE_USE_ENV_PROXY
is set to 1, the default global agent would parse the
HTTP_PROXY/http_proxy, HTTPS_PROXY/https_proxy, NO_PROXY/no_proxy
settings from the environment variables, and proxy the requests
sent through the built-in http/https client accordingly.

To support this, `http.Agent` and `https.Agent` now accept a few new
options:

- `proxyEnv`: when it's an object, the agent would read and parse
  the HTTP_PROXY/http_proxy, HTTPS_PROXY/https_proxy, NO_PROXY/no_proxy
  properties from it, and apply them based on the protocol it uses
  to send requests. This option allows custom agents to
  reuse built-in proxy support by composing options. Global agents
  set this to `process.env` when NODE_USE_ENV_PROXY is 1.
- `defaultPort` and `protocol`: these allow setting of the default port
  and protocol of the agents. We also need these when configuring
  proxy settings and deciding whether a request should be proxied.

Implementation-wise, this adds a `ProxyConfig` internal class to handle
parsing and application of proxy configurations. The configuration
is parsed during agent construction. When requests are made,
the `createConnection()` methods on the agents would check whether
the request should be proxied. If yes, they either connect to the
proxy server (in the case of HTTP reqeusts) or establish a tunnel
(in the case of HTTPS requests) through either a TCP socket (if the
proxy uses HTTP) or a TLS socket (if the proxy uses HTTPS).

When proxying HTTPS requests through a tunnel, the connection listener
is invoked after the tunnel is established. Tunnel establishment uses
the timeout of the request options, if there is one. Otherwise it uses
the timeout of the agent.

If an error is encountered during tunnel establishment, an
ERR_PROXY_TUNNEL would be emitted on the returned socket. If the proxy
server sends a errored status code, the error would contain an
`statusCode` property. If the error is caused by timeout, the error
would contain a `proxyTunnelTimeout` property.

This implementation honors the built-in socket pool and socket limits.
Pooled sockets are still keyed by request endpoints, they are just
connected to the proxy server instead, and the persistence of the
connection can be maintained as long as the proxy server respects
connection/proxy-connection or persist by default (HTTP/1.1)

PR-URL: https://github.com/nodejs/node/pull/58980
Refs: https://github.com/nodejs/node/issues/57872
Refs: https://github.com/nodejs/node/issues/8381
Refs: https://github.com/nodejs/node/issues/15620
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
2025-07-18 09:06:32 +02:00
Joyee Cheung 0221d6b652 test: move http proxy tests to test/client-proxy
Rewrite to ESM to use TLA.
Also add a test to make sure case precedence is honored.
Refs: https://about.gitlab.com/blog/we-need-to-talk-no-proxy

PR-URL: https://github.com/nodejs/node/pull/58980
Refs: https://github.com/nodejs/node/issues/57872
Refs: https://github.com/nodejs/node/issues/8381
Refs: https://github.com/nodejs/node/issues/15620
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
2025-07-18 09:06:30 +02:00
Joyee Cheung 5a7b7d2124 http: support http proxy for fetch under NODE_USE_ENV_PROXY
When enabled, Node.js parses the `HTTP_PROXY`, `HTTPS_PROXY` and
`NO_PROXY` environment variables during startup, and tunnels requests
over the specified proxy.

This currently only affects requests sent over `fetch()`. Support for
other built-in `http` and `https` methods is under way.

PR-URL: https://github.com/nodejs/node/pull/57165
Refs: https://github.com/nodejs/undici/issues/1650
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
2025-03-20 14:35:05 +00:00