Skip to content

Make your first proxy connection with a check you can repeat

Prove the route before testing a real service.

Configure the client that sends the request, then check both the response and the route. This local exercise invokes curl with configuration on stdin, keeps credentials out of command arguments, and compares authenticated traffic with a wrong-password and a direct-bypass control. It requires no paid proxy, account or external endpoint.

Reviewed:

curl sends an authenticated request through the local proxy to the local origin; paired request counts confirm traversal. A separate direct path reaches the origin without the proxy.
A valid response can also arrive directly. The proxy record is what separates the intended route from the bypass control.
Open full-size figure

Prepare the two public files

  1. Check the installed runtimes

    This recipe was verified with Node.js 24.14.0 and curl 8.13.0 on Windows. It uses only Node built-ins and curl, with no package installation. Confirm node --version and curl.exe --version in PowerShell/cmd; use curl --version in a POSIX shell.

  2. Save the local fixture

    Save the linked local-first-connection-v1.mjs file in a new directory. Save the full “Request example” below as example.mjs beside it. Read both files before running; this runner is not a sandbox for arbitrary code.

  3. Run from that directory

    Use the launch command below in PowerShell, cmd or a POSIX shell. The runner starts a proxy and an origin on loopback with temporary ports and sends synthetic input privately to example.mjs.

  4. Read the control results

    An overall exit of 0 means the success, wrong-credential and bypass controls matched. The runner closes both listeners. Any nonzero overall exit needs investigation; a missing client is not an authentication rejection.

Download the bounded fixture

The fixture forwards only GET to its own exact local /echo address and does not support CONNECT. It never calls a platform, changes an account or installs a client. No real credential or protected-config file is needed for the exercise.

The downloaded runner supplies proxy, username, password, target and bypass to the example on stdin. The example passes curl configuration through a private pipe as `curl -q --config -`; -q is the first curl argument so a default curlrc cannot silently change the request. On Windows it selects curl.exe, not a PowerShell alias. CURL_BIN can select an already trusted curl executable.

Launch all three controls

Scroll horizontally with the arrow keys to read all content.

node local-first-connection-v1.mjs example.mjs

Run in the directory holding the two saved files. This command uses no shell input redirection and works in PowerShell, cmd and POSIX shells.

Checked with a local fixture

Request example

Scroll horizontally with the arrow keys to read all content.

import { readFileSync } from 'node:fs'
import { spawn } from 'node:child_process'

let cfg
try {
  cfg = JSON.parse(readFileSync(0, 'utf8'))
  if (!cfg || typeof cfg.bypass !== 'boolean' ||
      ['proxy','username','password','target'].some(key =>
        typeof cfg[key] !== 'string' || /[\r\n]/.test(cfg[key]))) throw new Error()
} catch {
  console.log(JSON.stringify({error:'invalid-input'}))
  process.exit(1)
}
const quote = value => {
  return '"' + value.replaceAll('\\', '\\\\').replaceAll('"', '\\"') + '"'
}
const curl = process.env.CURL_BIN || (process.platform === 'win32' ? 'curl.exe' : 'curl')
const config = [
  'proxy = ' + quote(cfg.proxy),
  'proxy-user = ' + quote(cfg.username + ':' + cfg.password),
  'noproxy = ' + quote(cfg.bypass ? '*' : ''),
  'url = ' + quote(cfg.target),
  'silent',
  'fail',
  'connect-timeout = 3',
  'max-time = 5',
  'write-out = "\\n%{http_code}"',
].join('\n')
const child = spawn(curl, ['-q', '--config', '-'], { stdio: ['pipe','pipe','pipe'], windowsHide:true })
let output = '', startFailed = false
child.stdout.setEncoding('utf8')
child.stdout.on('data', chunk => { output += chunk })
child.stderr.resume()
child.stdin.on('error', () => {})
child.on('error', () => {
  startFailed = true
  console.log(JSON.stringify({error:'runtime-unavailable'}))
  process.exitCode = 1
})
child.on('close', code => {
  if (startFailed) return
  const match = output.match(/\n(\d{3})$/)
  if (!match) {
    console.log(JSON.stringify({error:'runtime-invalid'}))
    process.exitCode = 1
    return
  }
  const http_status = Number(match[1])
  const body = output.slice(0, match.index)
  const marker = body === 'first-connection-fixture'
  console.log(JSON.stringify({http_status,curl_exit:code,marker}))
  process.exitCode = code === 0 && http_status === 200 && marker ? 0 : 1
})
child.stdin.end(config)

Save as example.mjs. Node starts curl with only -q --config - in argv; the synthetic configuration travels on stdin. Error bodies and raw curl diagnostics are not printed.

Checked with a local fixture

Expected local evidence

Scroll horizontally with the arrow keys to read all content.

Expected local evidence
CriterionResponse and exitRequest records
successhttp_status=200, curl_exit=0, marker=trueproxy_requests=1; destination_requests=1
wrong_credentialshttp_status=407, curl_exit=22; expected example failureproxy_requests=1; destination_requests=0
bypasshttp_status=200, curl_exit=0, marker=trueproxy_requests=0; destination_requests=1

The runner itself exits 0 only when all three expected outcomes match. These counters belong to a controlled HTTP fixture, not a production exit check.

Match protocol and authentication

Scroll horizontally with the arrow keys to read all content.

Match protocol and authentication
CriterionMeaning in curlWhat this exercise proves
HTTP proxyproxy-user authenticates to the proxy. Target login or API authorization is separate.Authenticated local HTTP GET only
HTTPS destinationAn HTTP proxy normally uses CONNECT for an HTTPS target; TLS is a separate check.No CONNECT, TLS or certificate validation tested here
SOCKS5 options--socks5 or socks5:// resolves the target name locally; --socks5-hostname or socks5h:// asks the proxy to resolve it.Documented curl option semantics; SOCKS5 not exercised

The DNS distinction describes curl's selected option or URL scheme, not an unconditional property of the SOCKS5 protocol.

When you move to real connection details

Use a read-only endpoint you own or are authorized to test. Obtain the exact protocol, host, port and proxy authentication details from the connection information you are allowed to use. Do not substitute a paid API as a connectivity probe.

For a manually maintained curl config, store proxy and proxy-user in a local file accessible only to your OS user, then pass its filename to curl's --config option. Restrict permissions before adding secrets (owner-only permissions on POSIX; a user-only ACL on Windows), keep it outside shared/synced folders and version control, and remove it when finished. This page does not supply or verify a platform-specific permission command.

Do not expand a password environment variable into command arguments. Avoid verbose/trace output, screenshots of configuration and raw diagnostics. Proxy authentication is separate from destination authorization. A real exit check needs an authorized endpoint's observed client address and the intended proxy record; this local example establishes neither a real country nor third-party compatibility.

Interpret failures before changing an exit

invalid-input

Check: The supplied JSON or a required field is malformed, or a value contains a line break.

Next action: Use the unmodified local runner and the full saved snippet. The example rejects input before starting curl and does not print it.

runtime-unavailable or runtime-invalid

Check: The curl process could not start, or did not produce its expected status output.

Next action: Check the installed binary and version. Do not classify this as a proxy rejection.

407 in the wrong-credential control

Check: The proxy rejected the synthetic password and the destination saw no request.

Next action: That is the expected negative control. A 407 with real settings calls for checking proxy credentials, not the target login.

200 but no proxy request

Check: The bypass control reaches the origin directly.

Next action: For a real test inspect curl's no-proxy settings and environment. A response alone does not prove proxy traversal.

fixture-infrastructure, example-timeout or control-mismatch

Check: Local listener startup, the example process or a control contract failed.

Next action: Stop, check both saved files and local runtime access. Do not infer target-platform behavior.

Choose the next guide

If you only needed to establish a curl route, stop after the paired check. Browser automation and standalone API clients have separate settings. Keep direct access when it already meets the task; a proxy adds another connection to diagnose.

Downloads and setup

Get the browser extension and connection tools

These links share the console’s connection-tool catalogue. Choose the tool for your system, then follow the setup guide for your purchased proxy.

Platform and version listings come from the existing tool catalogue, not a new compatibility test. Check the tool requirements before installing.

Sign in for connection details, mobile apps and more tools ↗

Sources and verification

  1. curl manual: config, proxy-user and SOCKS5 DNS

    Official documentation · Checked:

  2. Local curl first-connection controls

    Local example · Checked:

    Node.js 24.14.0 and curl 8.13.0; actual page snippet runs with the public loopback-only fixture and synthetic stdin credentials; positive, 407 and direct controls.

    Controlled local HTTP only. No paid service, regional exit, external account, TLS/CONNECT, SOCKS or browser integration is verified.