Send raw HTTP requests over TCP or TLS with complete control.
What makes htreq different: Unlike curl which abstracts the request, or Hurl which uses its own syntax, htreq sends exactly what you write - raw HTTP bytes over the wire. No hidden headers, no automatic behaviors, just your request exactly as specified.
- HTTP/1.1 - Full support including chunked encoding
- HTTP/2 - With ALPN negotiation and frame inspection
- HTTP/3 - QUIC protocol support for modern low-latency connections
- WebSocket - Interactive protocol upgrade and messaging
- TLS - Auto-detection for port 443, certificate inspection
- Unix sockets - Connect to Docker API and other socket services
- Basic authentication - Automatic header generation with
--user - Environment variables - Expand
$VARin request files - Colored output - Syntax highlighting (auto-disabled when piped)
- Request timing - Detailed breakdown of connection phases
- Automatic retries - Configurable retry logic for transient failures
- Redirect following - Automatic HTTP redirect handling with
--follow
Download from releases:
wget https://github.com/BasicAcid/htreq/releases/latest/download/htreq_VERSION_amd64.deb
sudo dpkg -i htreq_VERSION_amd64.debRequires Go 1.24+:
git clone https://github.com/BasicAcid/htreq
cd htreq
make
sudo make installCreate a request file request.http:
GET /get HTTP/1.1
Host: httpbin.org
Accept: application/jsonSend it:
htreq -f request.httpThat's it. The target is extracted from the Host header, and TLS is auto-enabled for port 443.
File: get.http
GET /json HTTP/1.1
Host: httpbin.org
Accept: application/jsonCommand:
htreq -f get.httpFile: post.http
POST /post HTTP/1.1
Host: httpbin.org
Content-Type: application/json
Content-Length: 27
{"name": "Alice", "age": 30}Command:
htreq -f post.http --body | jq .Create .env:
API_TOKEN=your-secret-token
File: api.http
GET /api/data HTTP/1.1
Host: api.example.com
Authorization: Bearer $API_TOKEN
Accept: application/jsonCommand:
htreq --env-file .env -f api.httpFile: auth.http
GET /basic-auth/myuser/mypass HTTP/1.1
Host: httpbin.org
Connection: closeCommand:
htreq -f auth.http --user myuser:mypassThe --user flag automatically generates the Authorization: Basic header with base64-encoded credentials.
Warning: Basic auth should only be used over TLS/HTTPS to avoid sending credentials in plain text.
File: http2.http
GET / HTTP/1.1
Host: cloudflare.comCommand:
htreq --http2 -f http2.httpFile: http3.http
GET / HTTP/1.1
Host: google.com
User-Agent: htreq/1.0
Connection: closeCommand:
htreq --http3 -f http3.httpHTTP/3 uses QUIC protocol (UDP-based) for improved performance and reduced latency. Most modern services like Google, Cloudflare, and Facebook support HTTP/3.
File: websocket.http
GET /chat HTTP/1.1
Host: websocket.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13Command:
htreq --websocket -f websocket.httpType messages and press Enter to send. Press Ctrl+C to exit.
File: docker.http
GET /containers/json HTTP/1.1
Host: localhostCommand:
sudo htreq --unix-socket /var/run/docker.sock -f docker.httphtreq -f request.http --timingShows detailed breakdown:
[*] Timing breakdown:
DNS lookup: 21.796ms
TCP connect: 33.709ms
TLS handshake: 27.184ms
Request send: 10µs
Server processing: 36.667ms
Content download: 101µs
Total: 119.501ms
htreq -f request.http --retry 3 --retry-delay 2sUsage: htreq [target] [options]
Arguments:
target host[:port] (optional if Host header present)
Options:
-f, --file FILE Request file (default: stdin)
--unix-socket PATH Connect to Unix socket
--env Expand environment variables ($VAR or ${VAR})
--env-file FILE Load environment variables from file
--tls Force TLS (auto-enabled for port 443)
--no-tls Disable TLS
--no-verify Skip TLS certificate verification
--dump-tls Show TLS session and certificate info
--http2 Use HTTP/2 protocol
--http3 Use HTTP/3 protocol (QUIC)
--websocket, --ws Use WebSocket protocol
--dump-frames Show HTTP/2 frames (requires --http2)
--retry N Number of retries on failure (default: 0)
--retry-delay DURATION Delay between retries (default: 1s)
--follow, -L Follow HTTP redirects
--max-redirects N Maximum redirects to follow (default: 10)
--timeout DURATION Socket timeout (default: 10s)
--max-bytes N Limit response output to N bytes
--user USER:PASS Basic authentication credentials
--print-request Show request being sent
--timing Show detailed request/response timing
--head Show only response headers
--body Show only response body
--no-color Disable colored output
-q, --quiet Suppress informational messages
-v, --verbose Verbose output
Standard HTTP format:
METHOD /path HTTP/1.1
Header-Name: value
Content-Type: application/json
Content-Length: 27
Request body content hereNotes:
- Line endings are automatically normalized (CRLF or LF accepted)
- Environment variables with
--env: Use$VARor${VAR}syntax - Target can be specified in the
Hostheader or as a command-line argument
The examples/ directory contains ready-to-use request files:
htreq -f examples/get-https.http
htreq -f examples/post-json.http
htreq --http2 -f examples/http2-example.http
htreq --websocket -f examples/websocket-echo.httpSee examples/README.md for complete documentation.
GNU General Public License v3.0 - see LICENSE file.