Skip to content

feat(net-http): :ENV proxy resolution (http_proxy/https_proxy/no_proxy) - #198

Merged
tannevaled merged 1 commit into
mainfrom
feat/nethttp-env-proxy
Jul 6, 2026
Merged

tannevaled merged 1 commit into
mainfrom
feat/nethttp-env-proxy

Conversation

@tannevaled

Copy link
Copy Markdown
Contributor

Completes the Net::HTTP proxy work deferred by #183: a bare / :ENV p_addr now resolves the proxy from the environment (MRI's default), instead of leaving the instance proxy-less.

What changed

  • :ENV default — Net::HTTP.new(host, port) (and :ENV explicitly) now opt into environment resolution at request time, keyed on the instance's scheme (@use_ssl) and target host. Net::HTTP.new(host, port, nil) stays a hard opt-out (no proxy even with the env set); an explicit host String is unchanged.
  • Scheme-aware lookup — http reads http_proxy/HTTP_PROXY, https reads https_proxy/HTTPS_PROXY. The proxy URL is parsed as scheme://[user:pass@]host:port (a scheme-less host:port is retried as http://), and any userinfo becomes the Proxy-Authorization credentials.
  • no_proxy/NO_PROXY — comma/space list of hosts, leading-dot or bare-domain suffixes, host:port qualifiers and CIDRs/IP literals; a match forces a direct connection. Mirrors URI::Generic.use_proxy?.
  • CGI-safety — when REQUEST_METHOD is set, the attacker-controllable uppercase HTTP_PROXY is ignored and only lowercase http_proxy is honored (MRI's find_proxy rule).
  • proxy? / proxy_address / proxy_port / proxy_user / proxy_pass now reflect the effective (explicit or env-resolved) proxy.

Proof

End-to-end through the VM against in-process httptest proxies: plain-http routing with Proxy-Authorization, https CONNECT tunnelling via https_proxy, no_proxy bypass, nil opt-out, and the CGI-safety split — plus unit coverage of the resolver and the no_proxy matcher. GOWORK=off go build/vet/test ./... green; 100% coverage on all new code.

Deferred

MRI's DNS-based loopback bypass (find_proxy resolves the target and skips the proxy for 127.*/::1) is intentionally not replicated — it needs a live resolver and would make loopback-target tests non-hermetic.

🤖 Generated with Claude Code

Net::HTTP's p_addr now defaults to MRI's :ENV, resolving the proxy from
the environment at request time instead of leaving the instance
proxy-less (the item deferred by #183).

- p_addr :ENV / omitted -> resolve from the environment against the
  instance's scheme (@use_ssl) and target host; nil/false -> no proxy;
  an explicit host String -> that fixed proxy (unchanged).
- http requests read http_proxy/HTTP_PROXY, https requests read
  https_proxy/HTTPS_PROXY; the resolved userinfo becomes the
  Proxy-Authorization credentials.
- no_proxy/NO_PROXY (comma/space list of hosts, leading-dot or bare
  domain suffixes, host:port qualifiers and CIDRs/IPs) forces a direct
  connection, mirroring URI::Generic.use_proxy?.
- CGI-safety: when REQUEST_METHOD is set, the attacker-controllable
  uppercase HTTP_PROXY is ignored and only the lowercase http_proxy is
  honored (MRI's find_proxy rule).
- proxy?/proxy_address/proxy_port/proxy_user/proxy_pass reflect the
  effective (explicit or env-resolved) proxy.

Proven end-to-end through the VM against in-process httptest proxies
(plain-http routing, https CONNECT tunnelling, no_proxy bypass, nil
opt-out, CGI-safety) plus unit coverage of the resolver and no_proxy
matcher; 100% coverage on the new code.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@tannevaled
tannevaled merged commit 6d1fea1 into main Jul 6, 2026
33 of 38 checks passed
@tannevaled
tannevaled deleted the feat/nethttp-env-proxy branch July 6, 2026 23:17
tannevaled added a commit that referenced this pull request Jul 7, 2026
Merge of main brought #198's TestNetHTTPEnvProxyCGISafety, whose first
assertion (uppercase HTTP_PROXY under CGI is ignored ⇒ proxy? false) cannot
hold on Windows: env vars are case-insensitive there, so HTTP_PROXY and
http_proxy are the same variable and the attacker-controllable-form-is-ignored
distinction is unrepresentable (main's own windows lane is red on this at
6d1fea1). Guard only that first assertion behind non-windows; the lowercase-
honored assertion still runs everywhere and exercises the same
REQUEST_METHOD/os.Getenv("http_proxy") path, so coverage stays 100% on all
lanes. CGI is a unix deployment concern.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
tannevaled added a commit that referenced this pull request Jul 7, 2026
6 pure-Go stdlib bindings (Net:: mail/transfer stack + WEBrick), each 100% cov + full suite + 6-arch. Also fixes net-ftp's Windows basename and guards #198's CGI-proxy test on Windows (case-insensitive env). Supersedes #200-205.
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