Skip to main content
Cordon works transparently with any HTTP client that respects the HTTPS_PROXY / HTTP_PROXY environment variables. Some languages and SDKs use custom HTTP implementations or different proxy mechanisms that need additional configuration.

Compatibility matrix

Language / RuntimeSDK / LibraryWorks with env vars?Workaround
CLIcurlPartialHTTP: only lowercase http_proxy. HTTPS: both cases work. (see below)
CLIwgetPartialOnly reads lowercase http_proxy and https_proxy (see below)
Gonet/httpYesNone needed
RustreqwestYesNone needed
PythonrequestsYesNone needed
PythonhttpxYesNone needed
PythonurllibYesNone needed
Rubynet/httpPartialHTTP: prefers lowercase http_proxy. HTTPS: not supported via env vars (see below)
C# / .NETHttpClientYesNone needed
Javajava.net.httpNoUses JVM system properties (see below)
PHPcurl_init()PartialHTTP: only lowercase http_proxy. HTTPS: both cases work. (see below)
PHPGuzzleYes (CLI only)Reads uppercase HTTP_PROXY in CLI mode
Node.jsundici.fetch()Yes (with register)--import @c6o/cordon/register
Node.jsbuilt-in fetchYes (with register)--import @c6o/cordon/register
Node.jsnode-fetchNoUse http-proxy-agent package
Node.jsaxiosYes (with helper)@c6o/cordon/axios
Node.jsgotYesRespects env vars natively

Language-specific notes

curl

The curl CLI uses libcurl, which deliberately ignores uppercase HTTP_PROXY as a security measure against the httpoxy vulnerability (CVE-2016-5385) — only lowercase http_proxy is read. For HTTPS requests, both HTTPS_PROXY and https_proxy are accepted (the httpoxy attack vector does not apply to HTTPS).

wget

wget has its own HTTP implementation (it does not use libcurl). It only reads lowercase environment variables for both protocols: http_proxy and https_proxy. Uppercase variants (HTTP_PROXY, HTTPS_PROXY) are ignored entirely.
cordon setup sets both uppercase and lowercase proxy variables automatically. If you configure the proxy manually, make sure to set lowercase http_proxy and https_proxy in addition to their uppercase counterparts.

Java

Java’s built-in java.net.http.HttpClient does not read HTTP_PROXY or HTTPS_PROXY environment variables. Instead, it uses JVM system properties:
java -Dhttp.proxyHost=127.0.0.1 -Dhttp.proxyPort=6790 \
     -Dhttps.proxyHost=127.0.0.1 -Dhttps.proxyPort=6790 \
     -jar your-app.jar

PHP

PHP’s curl_init() uses libcurl. For HTTP requests, it deliberately ignores uppercase HTTP_PROXY as a security measure against the httpoxy vulnerability (CVE-2016-5385) — only lowercase http_proxy is read. For HTTPS requests, both HTTPS_PROXY and https_proxy are accepted. Guzzle (the most popular PHP HTTP client) handles this differently — it reads uppercase HTTP_PROXY at the application layer and explicitly sets CURLOPT_PROXY, but only in CLI mode (PHP_SAPI === 'cli'). In web/CGI contexts, Guzzle ignores HTTP_PROXY for the same httpoxy security reasons.
For HTTP traffic: set both HTTP_PROXY and http_proxy to cover raw PHP curl and Guzzle. For HTTPS traffic: HTTPS_PROXY works for both raw curl and Guzzle.

Ruby

Ruby’s net/http only supports proxy env vars for HTTP requests. It prefers the lowercase form http_proxy and will warn when uppercase HTTP_PROXY is used:
warning: The environment variable HTTP_PROXY is discouraged. Use http_proxy.
For HTTPS requests, Ruby’s net/http does not automatically read HTTPS_PROXY or https_proxy from the environment. HTTPS proxy support requires explicit configuration in code:
proxy_uri = URI.parse(ENV['HTTPS_PROXY'])
Net::HTTP.new(uri.host, uri.port, proxy_uri.host, proxy_uri.port).start do |http|
  http.use_ssl = true
  response = http.request(Net::HTTP::Get.new(uri))
end
Ruby applications making HTTPS requests will not route through the proxy via environment variables alone. This may require code changes in Ruby applications that need HTTPS proxy support.

Streaming support

Cordon streams response bodies through without buffering, so SSE (Server-Sent Events) and chunked transfer encoding responses work correctly. This is critical for AI API integrations that use stream: true — tokens are forwarded to the client as they arrive from the upstream API, with no added latency.

AI / LLM SDKs

The major AI SDKs use custom fetch implementations and do not respect HTTPS_PROXY env vars or undici’s global dispatcher on their own. However, @c6o/cordon/register patches globalThis.fetch to inject a proxy dispatcher transparently — no code changes needed. Add the register import to your Node.js entry point:
NODE_OPTIONS="--import @c6o/cordon/register" npm run dev
Or as a direct import (must be the first import in your entry file):
import '@c6o/cordon/register';
This works for the Anthropic SDK, OpenAI SDK, and any other library that uses globalThis.fetch internally.

Manual (if register import is not an option)

Both the Anthropic and OpenAI SDKs support explicit proxy configuration via fetchOptions.dispatcher:
import Anthropic from '@anthropic-ai/sdk';
import * as undici from 'undici';

const client = new Anthropic({
  fetchOptions: {
    dispatcher: new undici.ProxyAgent('http://127.0.0.1:6790'),
  },
});
import OpenAI from 'openai';
import * as undici from 'undici';

const client = new OpenAI({
  fetchOptions: {
    dispatcher: new undici.ProxyAgent('http://127.0.0.1:6790'),
  },
});
Both the Anthropic and OpenAI SDKs are generated by Stainless, which acquires globalThis.fetch at client constructor time. Any other Stainless-generated SDK (e.g., Cloudflare, Lithic, Modern Treasury) will work the same way with @c6o/cordon/register — no code changes needed.

Other AI SDKs

SDKStatus
Vercel AI SDKNot yet tested
LangChain.jsNot yet tested
Google Generative AINot yet tested
AWS BedrockNot yet tested
CohereNot yet tested
MistralNot yet tested
We’re actively testing more SDKs. If you’ve tested one not listed here, let us know.

Node.js register import

The @c6o/cordon/register import patches globalThis.fetch to inject a proxy dispatcher into all outbound requests. It also sets undici’s global dispatcher for code that uses undici.fetch() directly.
node --import @c6o/cordon/register your-app.js
Or via NODE_OPTIONS:
NODE_OPTIONS="--import @c6o/cordon/register" npm run dev
Or as a direct import in your entry file (must be the first import):
import '@c6o/cordon/register';
This works for applications using globalThis.fetch, undici.fetch(), and fetch-based SDKs like Anthropic and OpenAI. Libraries with their own HTTP stack still need their own integration path: axios has @c6o/cordon/axios, while clients like node-fetch still require explicit proxy-agent configuration.