# cURL through a proxy: every option that matters, with examples

cURL is the fastest way to prove a proxy works and the reference every library imitates. Learn its five proxy flags and you can debug any client.


## The one-liner

```bash
curl -x http://USER-cc-us:PASS@res.proxshift.com:9000 https://api.ipify.org
```

`-x` (or `--proxy`) takes the proxy URL with credentials embedded. cURL tunnels HTTPS destinations with CONNECT automatically, and asks the proxy to resolve the hostname.


## Flags worth knowing

| Flag | Purpose |
| --- | --- |
| -x, --proxy URL | The proxy: scheme, host, port, optional credentials |
| -U, --proxy-user user:pass | Credentials separately, useful when the password has special characters |
| --proxy-basic | Force Basic proxy authentication (the default when a password is given) |
| -v | Show the CONNECT exchange, proxy status codes and the response headers |
| --noproxy '*' | Ignore proxy environment variables for this call |
| -w '%{time_total}\n' | Print timing to compare exits |


## SOCKS5 and remote DNS

```bash
# Hostname resolved at the exit (recommended)
curl -x socks5h://USER-cc-de:PASS@res.proxshift.com:9001 https://api.ipify.org

# Hostname resolved locally, then the IP is sent to the proxy (leaks the lookup)
curl -x socks5://USER-cc-de:PASS@res.proxshift.com:9001 https://api.ipify.org
```


## Environment variables

Tools that shell out to cURL, and many others, honour `http_proxy`, `https_proxy` and `no_proxy`. Export them once for a session of work.

```bash
export https_proxy="http://USER-cc-us:PASS@res.proxshift.com:9000"
export http_proxy="$https_proxy"
export no_proxy="localhost,127.0.0.1"
curl https://api.ipify.org   # proxied without -x
```


## Reading a failure

```bash
curl -v -x http://USER:WRONG@res.proxshift.com:9000 https://api.ipify.org 2>&1 | grep -E "CONNECT|HTTP/1.1 4|HTTP/1.1 5"
# < HTTP/1.1 407 Proxy Authentication Required  -> credentials
# < HTTP/1.1 400 Bad Request                    -> a username parameter is wrong
# < HTTP/1.1 502 Bad Gateway                    -> no exit for that location; widen it
```

A status on the CONNECT line comes from the gateway; a status after `Connection established` comes from the destination. The [errors page](https://proxshift.com/docs/errors) maps every gateway code.


## Rotating sessions in a loop

```bash
for i in $(seq 1 5); do
  curl -s -x "http://USER-cc-us-sid-run$i-ttl-5m:PASS@res.proxshift.com:9000" https://api.ipify.org
  echo
done   # five different United States exits, each reusable for five minutes under its id
```


## Questions

**Does cURL need a special flag for HTTPS through the proxy?**

No. With an http:// proxy URL cURL issues CONNECT for https:// destinations automatically; --proxytunnel only matters for forcing a tunnel on plain HTTP.

**My password contains @ or : and cURL fails.**

Pass the credentials with -U user:pass instead of embedding them in the URL, or URL-encode the special characters.

Source: https://proxshift.com/guides/curl-proxy-options
