Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

aioduct http

A curl-style HTTP client with familiar flags and a real-time verbose TUI for inspecting request lifecycles.

Basic Usage

# GET request
aioduct http https://httpbin.org/get

# POST with JSON body
aioduct http -X POST -d '{"key":"value"}' \
  -H 'Content-Type: application/json' \
  https://httpbin.org/post

# Form POST
aioduct http -F 'user=adam' -F 'action=deploy' https://httpbin.org/post

# Upload binary file
aioduct http -X PUT --data-binary @./artifact.tar.gz \
  -H 'Content-Type: application/octet-stream' \
  https://storage.example.com/uploads/artifact.tar.gz

# HEAD request — show response headers only
aioduct http -I https://example.com

Verbose Mode

The -v flag activates verbose output showing the full request lifecycle.

When stdout is a terminal, verbose mode launches a ratatui TUI with a 6-tab interface navigated via Tab / Shift+Tab:

Tabs

TabContent
OverviewPhase timeline waterfall chart with per-phase durations
TraceDNS resolution, TCP connect, TLS handshake, request/response headers, timing
HeadersFull request and response headers with filter
BodyResponse body preview (binary detection with hex dump fallback, SSE streaming)
EventsChronological event log of every phase transition, redirect, retry, and error
SummaryTransfer metrics, redirect/retry history, trailers, timings

Controls

KeyAction
Tab / Shift+TabNext / previous tab
Scroll
cCopy visible content to clipboard
/Filter / search within current tab
hToggle help overlay
qQuit

Features

  • Binary body detection: Binary content types (images, gzip, protobuf, etc.) are auto-detected; headers are redacted and body shown as hex dump instead of garbled text.
  • Trailer display: HTTP trailers received after the body appear in the Headers and Summary tabs.
  • SSE tracking: Server-Sent Events are parsed; event count, first/last timestamps, and gaps are tracked.
  • Error state rendering: Failed phases show the error reason inline in the Timeline and Trace tabs.
  • Redirect & retry panels: The Summary tab shows redirect chains and retry attempts with backoff durations and reasons.
  • Event log sanitization: ANSI escapes are stripped, newlines collapsed, control characters replaced for safe TUI rendering.

When stdout is not a terminal (piped), verbose output falls back to colored stderr text:

# TUI mode (terminal)
aioduct http -v https://example.com

# Force plain text verbose (always stderr, even on a terminal)
aioduct http --verbose-plain https://example.com

# Pipe-friendly: body to stdout, verbose to stderr
aioduct http -v https://api.example.com/data | jq .

Authentication

# HTTP Basic auth
aioduct http -u admin:secret https://httpbin.org/basic-auth/admin/secret

# Bearer token
aioduct http --oauth2-bearer eyJhbGciOi... https://api.example.com/protected

Output Control

# Save response body to file
aioduct http -o page.html https://example.com

# Save using filename from URL
aioduct http -O https://releases.example.com/v2.1/archive.tar.gz

# Dump response headers to file
aioduct http -D headers.txt https://example.com

# Include response headers in stdout
aioduct http -i https://example.com

# Write-out format (status code for scripting)
aioduct http -s -o /dev/null -w '%{http_code}\n' https://example.com

Redirects & Retries

# Follow redirects (up to 10 hops by default)
aioduct http -L https://httpbin.org/redirect/3

# Custom redirect limit
aioduct http -L --max-redirs 5 https://httpbin.org/redirect/3

# Retry on failure with exponential backoff
aioduct http --retry 5 --retry-max-time 120 https://flaky-service.example.com/health

Transport

# Force HTTP/2 prior knowledge
aioduct http --http2 https://example.com

# Request compressed response
aioduct http --compressed https://cdn.example.com/large-payload.json

# Limit download speed
aioduct http --limit-rate 1M https://cdn.example.com/file.bin

# HTTP proxy
aioduct http -x http://proxy:8080 https://example.com

# HTTPS proxy (TLS-wrapped connection to proxy)
aioduct http -x https://proxy:443 https://example.com

# SOCKS5 proxy (local DNS)
aioduct http -x socks5://127.0.0.1:1080 https://example.com

# SOCKS5h proxy (remote DNS — proxy resolves hostnames)
aioduct http -x socks5h://proxy:1080 https://internal.corp

# SOCKS4/SOCKS4a proxy
aioduct http -x socks4a://localhost:1080 https://example.com

# Multi-hop proxy chaining (repeated -x)
aioduct http -x socks5://internal-gateway:1080 -x http://corp-proxy:3128 \
  https://example.com

# Proxy with explicit authentication
aioduct http -x http://proxy:8080 --proxy-user admin:secret \
  https://example.com

# Proxy bypass for specific hosts
aioduct http -x http://proxy:8080 --noproxy localhost,127.0.0.1,.internal \
  https://example.com

# Use system proxy settings (HTTP_PROXY / HTTPS_PROXY / NO_PROXY)
aioduct http --system-proxy https://example.com

# Skip TLS verification
aioduct http -k https://self-signed.example.com

# Timeouts
aioduct http --connect-timeout 5 --max-time 30 https://slow-server.example.com

Flags Reference

FlagLongDescription
-X--requestHTTP method
-d--dataRequest body (implies POST); prefix @ to read from file
--data-binaryBinary body; prefix @ to read from file
-F--formURL-encoded form field (repeatable)
-H--headerExtra header (repeatable)
-A--user-agentUser-Agent string
-e--refererReferer URL
-u--userBasic auth (user:password)
--oauth2-bearerBearer token
-L--locationFollow redirects
--max-redirsMax redirect hops (default: 10)
-I--headHEAD request, show headers only
-i--includeInclude response headers in output
-v--verboseVerbose mode (TUI on terminal, plain text otherwise)
--verbose-plainForce plain-text verbose to stderr
-s--silentSilent mode
-S--show-errorShow errors in silent mode
-o--outputWrite body to file
-O--remote-nameSave using filename from URL
-D--dump-headerDump response headers to file
-w--write-outFormat string (%{http_code}, %{response_code})
-m--max-timeTotal request timeout (seconds)
--connect-timeoutConnection timeout (seconds)
--retryRetry count
--retry-max-timeMax backoff between retries (default: 60s)
-x--proxyProxy URL (repeatable for multi-hop chaining)
--proxy-userProxy auth (user:password)
--noproxyBypass proxy for listed hosts (comma-separated)
--system-proxyUse proxy from env vars (HTTP_PROXY, HTTPS_PROXY, NO_PROXY)
-k--insecureSkip TLS verification
--http2Force HTTP/2 prior knowledge
--limit-rateMax download speed (supports K/M/G)
--rawDisable decompression
--compressedRequest compressed response

Exit Codes

CodeMeaning
0Success
1Generic error
3Invalid URL
7Connection / I/O error
22HTTP 4xx/5xx response
23Output write error
28Timeout
60TLS error

Examples

# Query an LLM API with bearer auth and parse the JSON response
aioduct http -X POST \
  --oauth2-bearer sk-abc123 \
  -H 'Content-Type: application/json' \
  -d '{"model":"claude-3","prompt":"Hello"}' \
  https://api.anthropic.com/v1/messages | jq .content

# CI health check — exit non-zero on failure
aioduct http -s -o /dev/null -w '%{http_code}' \
  --max-time 5 --retry 3 \
  https://production.example.com/healthz

# Upload a release artifact through a corporate proxy
aioduct http -X PUT --data-binary @./build/release.tar.gz \
  -H 'Content-Type: application/gzip' \
  -x http://corporate-proxy:3128 \
  -u deploy:token \
  https://artifacts.example.com/releases/v2.1/release.tar.gz

# Inspect TLS and timing details with verbose plain output
aioduct http --verbose-plain --http2 https://example.com 2>&1 | grep -E 'TLS|RESP'

# Download with speed limit and save to specific file
aioduct http --limit-rate 500K -o large-file.bin \
  https://cdn.example.com/datasets/training-data.bin

# Silent mode with write-out for monitoring scripts
aioduct http -s -o /dev/null \
  -w 'status=%{http_code}\n' \
  --max-time 10 \
  https://api.example.com/status