Open-Source Wikis

/

curl

/

Features

/

Proxies

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 origin
graph 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-proxy reuses the HTTP/2 stack from lib/http2.c.
  • DNS: SOCKS5h ("h" variant) defers name resolution to the proxy; SOCKS5 resolves locally. Selection by CURLPROXY_SOCKS5 vs CURLPROXY_SOCKS5_HOSTNAME.

Entry points for modification

  • New proxy auth quirk → lib/http_proxy.c plus lib/vauth/ if scheme-specific.
  • New SOCKS variant → lib/socks.c and a new CURLPROXY_* enum value.
  • HAProxy protocol changes → lib/cf-haproxy.c.
  • HTTP/2 CONNECT semantics → lib/cf-h2-proxy.c (close cousin of lib/http2.c).

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Proxies – curl wiki | Factory