Tracing, proxies and name resolution

curl · Expert · 12 min

Corporate proxies, odd DNS and 'the server says my body is wrong' bugs need byte-level visibility.

-v shows headers, but not bodies or exact bytes. For that:

  • --trace-ascii trace.txt (or - for stdout) logs everything sent and received, including request and response bodies, in readable form; --trace gives a hex dump. Add --trace-time for timestamps.
  • Remember that trace files contain tokens and cookies; scrub them before sharing.

Proxies. -x http://proxy.corp:3128 routes the request through a proxy (socks5h:// for SOCKS with remote DNS). curl also reads proxy settings from environment variables: https_proxy, all_proxy, and lowercase-only http_proxy (uppercase HTTP_PROXY is ignored on purpose, because CGI environments let a request header set it). no_proxy=localhost,.internal lists hosts that bypass the proxy, and --noproxy '*' disables proxies for one command. For HTTPS through an HTTP proxy, curl sends a CONNECT and tunnels TLS end to end; -v shows the CONNECT exchange and the proxy's answer.

Name resolution. -4 / -6 force IPv4 or IPv6, which isolates the classic "slow first request" caused by an unreachable IPv6 route. --dns-servers (needs a c-ares build) picks resolvers, and --doh-url https://dns.example/dns-query resolves via DNS-over-HTTPS. %{remote_ip} in -w confirms where you actually connected.

Example

curl -sS --trace-ascii - --json '{"a":1}' https://api.example.com/echo | head -20
# => Send header, 154 bytes ...  => Send data, 7 bytes: {"a":1}
curl -sS -x http://proxy.corp:3128 https://example.com -o /dev/null -v 2>&1 | grep CONNECT
# > CONNECT example.com:443 HTTP/1.1
export https_proxy=http://proxy.corp:3128 no_proxy=localhost,.internal
curl -sS https://example.com -o /dev/null            # via proxy
curl -sS http://wiki.internal/ -o /dev/null           # direct (no_proxy)
curl -sS --noproxy '*' https://example.com -o /dev/null   # direct this time
curl -4 -sS -o /dev/null -w '%{remote_ip} %{time_connect}\n' https://example.com
curl -x socks5h://localhost:1080 http://grafana.internal:3000/   # DNS via proxy

Remember

  • --trace-ascii shows full bodies and exact bytes
  • -x or https_proxy/http_proxy (lowercase) route via a proxy; no_proxy bypasses
  • -4/-6 and %{remote_ip} isolate DNS and IP-version problems

Watch out for

  • Setting HTTP_PROXY in uppercase and wondering why curl ignores it for http:// URLs.

Check yourself

  1. curl ignores your `HTTP_PROXY=...` setting for http:// URLs. Why?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: curl.se/docs/manpage.html#-x

Builds on

Unlocks

Nothing builds on this yet.