curl/curl
Proxies
Active contributors: Daniel Stenberg, Stefan Eissing, Viktor Szakats
Purpose
curl supports a wide variety of proxy mechanisms — and uniquely supports stacking them, so an HTTPS-to-origin connection can run inside an HTTP/2 CONNECT tunnel through an HTTPS-to-proxy connection. Each kind is implemented as a connection filter under lib/.
| Proxy kind | Filter source | Notes |
|---|---|---|
| HTTP/1 proxy (CONNECT) | lib/cf-h1-proxy.c |
The classic CONNECT host:port tunnel |
| HTTP/2 proxy (CONNECT streams) | lib/cf-h2-proxy.c |
Each tunneled connection is a stream on the proxy connection |
| HTTPS proxy (TLS to proxy) | lib/cf-https-connect.c + TLS filter |
TLS handshake to the proxy itself |
| SOCKS4 / SOCKS4a / SOCKS5 | lib/socks.c |
The classic SOCKS variants |
| SOCKS5 with GSSAPI / SSPI | lib/socks_gssapi.c, lib/socks_sspi.c |
Kerberos-authenticated SOCKS |
| HAProxy PROXY protocol prefix | lib/cf-haproxy.c |
A small header-prefix sender |
| Plain-text HTTP forward proxy | lib/http_proxy.c + handler |
Standard HTTP/1.1 forward proxy (no CONNECT for plain HTTP) |
The user-visible options are CURLOPT_PROXY / --proxy / https_proxy=…, plus the CURLOPT_PROXYTYPE selector and noproxy via CURLOPT_NOPROXY (lib/noproxy.c).
Stacking model
A complete HTTPS-through-HTTPS-proxy connection looks like:
cf_socket ← TCP to proxy
cf_tls(proxy backend) ← TLS to proxy
cf_h1_proxy or cf_h2_proxy ← CONNECT host:port
cf_tls(origin backend) ← TLS to origin (layered through tunnel)
cf_http2 (if ALPN says h2) ← HTTP/2 mux to origingraph TD
A[application] --> B[http.c]
B --> C[cf_http2 origin]
C --> D[cf_tls origin]
D --> E[cf_h1_proxy / cf_h2_proxy]
E --> F[cf_tls proxy]
F --> G[cf_socket]
G --> H[(network)]Because each piece is a generic cfilter, the protocol handler in lib/http.c does not know it is talking through any of this — it just calls Curl_conn_send and Curl_conn_recv.
SOCKS
SOCKS sits closer to the bottom of the stack. The order is:
cf_socket
cf_socks (with the chosen variant: 4, 4a, 5, 5h)
... origin TLS / HTTP/2 / etc above ...lib/socks.c does the SOCKS handshake; if --socks5-gssapi is enabled, the GSSAPI/SSPI variants take over. The selection is via CURLOPT_PROXYTYPE.
HAProxy PROXY protocol
The PROXY protocol is a single-line preamble that lets a load balancer forward the original client address. lib/cf-haproxy.c writes it once after cf_socket connects and then becomes transparent. Enabled via CURLOPT_HAPROXYPROTOCOL (--haproxy-protocol).
CONNECT for HTTP/2 streams
A subtle but important feature: when the proxy negotiates HTTP/2 (over TLS, with h2 ALPN), each CONNECT becomes a stream on the proxy's HTTP/2 connection rather than a standalone TCP connection. This lets curl multiplex many tunneled origin connections over a single proxy TCP connection. Implementation: lib/cf-h2-proxy.c. Tested via the http2_proxy test cluster in tests/data/.
Non-CONNECT (forward) HTTP proxy
For plain http:// URLs, the proxy is told the absolute URL in the request line — no tunnel. The protocol handler issues request lines like GET http://origin/path HTTP/1.1 and the proxy retrieves the resource. lib/http_proxy.c handles the proxy-side request rewriting and proxy-authentication challenge handling.
Authentication
Proxy authentication is parallel to origin authentication. CURLOPT_PROXYUSERPWD, CURLOPT_PROXYAUTH, --proxy-user, --proxy-anyauth, etc. The same auth backends in lib/vauth/ are used; the difference is which header (Proxy-Authorization vs Authorization) is rendered. See Authentication.
Environment variables
curl honours the standard http_proxy, https_proxy, ftp_proxy, all_proxy, and no_proxy environment variables (lib/url.c::checkAndAcceptProxyEnv and lib/noproxy.c). Special-case: lower-case names are checked everywhere; upper-case names are checked everywhere except for HTTP_PROXY (where it conflicts with the legacy CGI variable).
Integration points
- Connection filters: every proxy variant is a cfilter; see Connection filters.
- TLS: HTTPS-to-proxy is just an extra TLS filter beneath the CONNECT filter; see TLS backends.
- HTTP/2:
cf-h2-proxyreuses the HTTP/2 stack fromlib/http2.c. - DNS: SOCKS5h ("h" variant) defers name resolution to the proxy; SOCKS5 resolves locally. Selection by
CURLPROXY_SOCKS5vsCURLPROXY_SOCKS5_HOSTNAME.
Entry points for modification
- New proxy auth quirk →
lib/http_proxy.cpluslib/vauth/if scheme-specific. - New SOCKS variant →
lib/socks.cand a newCURLPROXY_*enum value. - HAProxy protocol changes →
lib/cf-haproxy.c. - HTTP/2 CONNECT semantics →
lib/cf-h2-proxy.c(close cousin oflib/http2.c).
Related pages
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.