Last tested: 2026-08-11
Shellroute version: unreleased (post-0.1.0, includes auto NODE_USE_ENV_PROXY) Platform: macOS 26.4 (darwin/arm64)
shellroute run and shellroute (interactive mode) start a local HTTP proxy and set these environment variables for the child process or session:
HTTP_PROXY
HTTPS_PROXY
http_proxy
https_proxy
A tool is routed only when it reads and uses these variables, or when it is explicitly configured to use the local proxy. Shellroute does not intercept arbitrary TCP, UDP, DNS, or raw-socket traffic.
Tested on macOS 26.4 (darwin/arm64). Non-Node rows tested 2026-07-27 with shellroute 0.1.0. Node rows tested 2026-08-11 with unreleased build (post-0.1.0). Each tested row verified: command exit code 0, exit IP differs from direct control, exit country = US, session ended cleanly.
| Client | Version | Outcome | Test command | Condition |
|---|---|---|---|---|
| curl | 8.7.1 | automatic | shellroute run US -- curl -s https://ipinfo.io/json |
Reads proxy env vars by default. |
| wget | 1.25.0 | automatic | shellroute run US -- wget -qO- https://ipinfo.io/json |
Reads proxy env vars by default. |
| Python Requests | 2.32.5 | automatic | shellroute run US -- python3 -c "import requests; print(requests.get('https://ipinfo.io/json').text)" |
Reads proxy env vars by default. Session.proxies can override. |
| Python HTTPX (default) | 0.28.1 | automatic | shellroute run US -- python3 -c "import httpx; print(httpx.get('https://ipinfo.io/json').text)" |
Default trust_env=True. |
Python HTTPX (trust_env=False) |
0.28.1 | not transparent | shellroute run US -- python3 -c "import httpx; print(httpx.get('https://ipinfo.io/json', trust_env=False).text)" |
Bypassed proxy. Returned direct IP. |
| Python urllib | 3.9.6 | automatic | shellroute run US -- python3 -c "import urllib.request; print(urllib.request.urlopen('https://ipinfo.io/json').read().decode())" |
Default handlers read proxy env vars. |
| aiohttp (default) | 3.13.5 | not transparent | Tested internally: aiohttp.ClientSession() without trust_env |
Did not use proxy env vars. Returned direct IP. |
aiohttp (trust_env=True) |
3.13.5 | explicit configuration | Tested internally: aiohttp.ClientSession(trust_env=True) |
Requires trust_env=True or explicit proxy. |
| Node fetch | v25.8.2 | automatic | shellroute run US -- node -e "fetch('https://ipinfo.io/json').then(r=>r.json()).then(console.log)" |
Shellroute sets NODE_USE_ENV_PROXY=1 automatically. Supported: Node 24.0+ and 22.21+. Not supported: Node 20, 21, 22.0–22.20, 23. Opt out: NODE_USE_ENV_PROXY=0. |
Node fetch (NODE_USE_ENV_PROXY=0) |
v25.8.2 | not transparent | NODE_USE_ENV_PROXY=0 shellroute run US -- node -e "fetch('https://ipinfo.io/json').then(r=>r.json()).then(console.log)" |
User opt-out. Fetch goes direct, returns direct IP. |
| Node http/https | v25.8.2 | automatic | shellroute run US -- node -e "const https=require('https'); https.get('https://ipinfo.io/json', r=>{let d=''; r.on('data',c=>d+=c); r.on('end',()=>console.log(d))})" |
Supported: Node 24.5+ and 22.21+. Not supported: Node 20, 21, 22.0–22.20, 23, 24.0–24.4. Uses default global agents; custom agents can bypass. |
Go http.Client (default) |
go1.26.2 | automatic | Tested internally: http.Get(url) with default transport |
Default transport reads proxy env vars. |
Go http.Client (custom) |
go1.26.2 | not transparent | Tested internally: Transport{Proxy: nil} |
Custom transport bypassed proxy. Returned direct IP. |
| Playwright | 1.60.0 | explicit configuration | Tested internally: npx playwright test with proxy in config |
Requires proxy: { server: process.env.HTTP_PROXY } in playwright.config.ts. |
| Puppeteer | 25.1.0 | explicit configuration | Tested internally: Puppeteer with --proxy-server arg |
Requires --proxy-server=${process.env.HTTP_PROXY} in launch args. |
| SSH | — | not tested | /ssh user@host in interactive mode |
Direct ssh does not read proxy env vars. Use shellroute's /ssh helper. Not harness-testable (requires interactive mode + SSH server). |
| npm test runner | — | not tested | — | Conditional on the test suite's HTTP clients. Not harness-testable (no single representative fixture). |
- automatic: the client uses the injected
HTTP_PROXY/HTTPS_PROXYenvironment without additional shellroute-specific application configuration. - explicit configuration: works only after documented client option or environment opt-in.
- conditional: default transports or child clients work, but the named umbrella command is not sufficient to predict routing.
- not transparent: shellroute's HTTP proxy environment does not route this protocol/client by itself.
- not tested: no current executable evidence. Expected outcome noted.
Each tested combination runs through this procedure:
- Capture a direct control request (without shellroute) to
https://ipinfo.io/json. The direct IP is redacted and not committed. - Run the same request inside
shellroute run <country> -- <command>. - A passing result requires:
- The child command succeeded.
- The observed public exit IP differs from the redacted direct control.
- The endpoint reports the selected country.
- The session shuts down cleanly.
- Negative tests (e.g.,
trust_env=False,NODE_USE_ENV_PROXY=0) verify the request bypasses the proxy without publishing the direct IP. - Provider failures are retried. A client is not labeled incompatible because of an upstream failure.
Shellroute sets NODE_USE_ENV_PROXY=1 which makes Node's global HTTP agents read proxy env vars. This affects all libraries using the default agents:
- Axios <=1.18.0: can double-proxy because both Axios and Node process
HTTP_PROXY/HTTPS_PROXY. Workaround: setNODE_USE_ENV_PROXY=0so only Axios handles the proxy. - Axios >=1.18.1: defers env proxy handling to Node, avoiding the known double-proxy conflict. Not tested with shellroute.
- Got: default HTTP/1.1 path uses Node's global agent and routes correctly. Custom agents and HTTP/2 mode are not guaranteed to proxy.
- Not all Node HTTP libraries automatically work. Libraries that create their own sockets or agents may bypass the proxy.
- Results apply to the tested versions on the tested platform. Other versions or platforms may differ.
- A successful proxy route proves the request used the expected exit IP. It does not prove target-side localized content, region selection, or anti-bot bypass.
- An HTTP CONNECT proxy tunnels TLS bytes. It does not replace the client's TLS fingerprint.
To retest, log in with shellroute login, then run each client through shellroute run <country> -- <command> against https://ipinfo.io/json. Compare the exit IP and country to a direct control.