README
¶
HTTP Client Tool
A command-line HTTP client written in Go that processes .http files, validates requests against HTTP standards, and sends them over TCP with colored output.
File Formats
This tool supports two HTTP request formats and automatically detects which one you're using:
HTP Format (HTTP Template Protocol)
Our friendly, human-readable format with preprocessing support:
- Comments: Lines starting with
#or// - Environment variables:
${VAR_NAME}or$VAR_NAME - Shell commands:
$(command) - Line endings: Standard newlines (
\n) - Detection: Automatically used when file doesn't contain
\r\n - Use case: Writing request templates with dynamic content
Example HTP file:
# API Request Template
POST https://api.example.com/data HTTP/1.1
Host: api.example.com
Authorization: Bearer ${API_TOKEN}
X-Request-ID: $(uuidgen)
{"user": "$(whoami)"}
(Note: HTP format files use standard \n (LF) line endings, allowing text editors to easily edit them.)
RFC Compliant Format
Standard HTTP protocol format ready to send over the wire:
- No preprocessing: Pure HTTP request format
- Line endings: CRLF (
\r\n) as per RFC specification - Detection: Automatically used when file contains
\r\n - Use case: Saved/exported requests, sharing exact requests, production templates
Example RFC compliant file:
POST https://api.example.com/data HTTP/1.1
Host: api.example.com
Authorization: Bearer abc123token
Content-Length: 15
{"user": "john"}
(Note: In the actual RFC compliant file, each line would end with \r\n (CRLF), not just \n (LF) as shown above. This is the key difference that enables format auto-detection.)
Format Comparison
| Feature | HTP Format | RFC Compliant Format |
|---|---|---|
| Line endings | \n |
\r\n |
| Comments | Yes (#, //) |
No |
| Env variables | Yes (${VAR}, $VAR) |
No |
| Shell commands | Yes ($(cmd)) |
No |
| Preprocessing | Yes | No |
| Auto-detection | No \r\n in file |
Contains \r\n |
Use with -f |
✅ Yes | ✅ Yes |
| Use with stdin | ✅ Yes | ✅ Yes |
Features
- 🚀 HTTP & HTTPS Support: Send requests over plain HTTP or secure HTTPS
- ✅ Request Validation: Validates requests against HTTP RFC standards with colored error/warning output to stderr
- 📝 Dual Format Support: HTP format (human-friendly with preprocessing) and RFC compliant format
- 🔧 Preprocessing:
- Comments (# or //)
- Environment variable substitution (${VAR} or $VAR)
- Shell command execution $(command)
- Automatically disabled in strict mode
- 💾 Save/Load Requests: Save preprocessed RFC compliant requests to files and load them later
- 🔒 Strict Mode: Enforce full RFC compliance by failing on validation warnings and disabling preprocessing
- 🎨 Colored Output: Beautiful colored output for requests, responses, and validation
- 📥 stdin/stdout: Reads from stdin and writes to stdout for easy piping
- 🔍 RFC Output Mode: Output RFC compliant requests without sending for inspection or saving
- ⚙️ Port Override: Explicitly set port with
--portflag, overriding URL defaults
Installation
Pre-built Binaries
Download pre-built binaries from the Releases page.
# Example: Linux AMD64
wget https://github.com/adamijak/http/releases/latest/download/http-linux-amd64
chmod +x http-linux-amd64
sudo mv http-linux-amd64 /usr/local/bin/http
Build from Source
go build -o http
Or install directly:
go install github.com/adamijak/http@latest
Usage
Basic Usage
# From stdin
cat request.http | ./http
# From file (supports both HTP and RFC compliant formats)
./http -f request.http
# From heredoc
./http <<EOF
GET https://api.github.com/users/octocat HTTP/1.1
User-Agent: http-client/1.0
EOF
Command-Line Options
./http [OPTIONS]
Options:
-f, --file FILE Read request from FILE (auto-detects HTP or RFC compliant format)
--no-send Output the RFC compliant request to stdout without sending
--no-color Disable colored output
--no-secure Send request in plain HTTP instead of HTTPS
--port PORT Explicitly set the port (overrides URL and default ports)
--strict Strict mode: fail on any validation warnings (RFC compliance enforcement)
-v, --verbose Verbose output
--version Show version information
HTP Format (HTTP Template Protocol)
HTP is our friendly, human-readable request format with preprocessing support. Files in this format use standard newlines (\n) and can contain:
Simple GET Request
GET https://api.example.com/users HTTP/1.1
Host: api.example.com
User-Agent: MyClient/1.0
Path-Only Request (RFC Standard)
You can use just the path and specify the host in the Host header:
GET /users HTTP/1.1
Host: api.example.com
User-Agent: MyClient/1.0
Scheme Detection: By default, path-only requests use HTTPS. To force plain HTTP, use the --no-secure flag:
cat request.http | ./http --no-secure
Port Detection: The tool automatically uses the default port for the detected scheme:
- HTTPS: port 443 (default)
- HTTP: port 80 (default)
You can override the port explicitly with the --port flag:
cat request.http | ./http --port 8080
POST Request with Body
POST https://api.example.com/users HTTP/1.1
Host: api.example.com
Content-Type: application/json
{
"name": "John Doe",
"email": "john@example.com"
}
Using Comments
# This is a comment
// This is also a comment
GET https://api.example.com/status HTTP/1.1
# Comments can appear anywhere
Host: api.example.com
Environment Variables
# Using ${VAR} syntax
GET https://api.example.com/users HTTP/1.1
Host: api.example.com
Authorization: Bearer ${API_TOKEN}
# Using $VAR syntax
X-API-Key: $API_KEY
Set environment variables:
export API_TOKEN="your-token-here"
export API_KEY="your-key-here"
cat request.http | ./http
Shell Command Execution
GET https://api.example.com/request HTTP/1.1
Host: api.example.com
X-Request-ID: $(uuidgen)
X-Timestamp: $(date +%s)
Complete Example
# API Request Example
# Make sure to set API_TOKEN environment variable
POST https://api.example.com/data HTTP/1.1
Host: api.example.com
Content-Type: application/json
Authorization: Bearer ${API_TOKEN}
X-Request-ID: $(uuidgen)
User-Agent: http-client/1.0
{
"timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
"message": "Hello from http client"
}
Examples
Output RFC Compliant Request
Output the RFC compliant request to stdout without sending:
cat request.http | ./http --no-send
Output:
GET https://api.example.com/data HTTP/1.1
Host: api.example.com
Content-Type: application/json
Authorization: Bearer abc123token
X-Request-ID: 550e8400-e29b-41d4-a716-446655440000
Content-Length: 42
{"message":"Hello from http client"}
The output is in RFC compliant format with CRLF line endings (\r\n), ready to send over the wire or save to a file.
Working with Both Formats
The tool automatically detects whether your input is in HTP or RFC compliant format:
# Read HTP format from file (will preprocess)
./http -f template.http
# Read RFC compliant format from file (no preprocessing needed)
./http -f saved-request.http
# Read from stdin (supports both formats)
cat request.http | ./http
Output RFC Compliant Request
Convert HTP format to RFC compliant format and output to stdout:
# Output RFC compliant request (env vars substituted, comments removed)
cat template.http | ./http --no-send
# Save to file using shell redirection
./http -f template.http --no-send > saved-request.http
# Or pipe to other tools (use -a to handle CRLF line endings)
./http -f template.http --no-send | grep -a "Authorization"
# Pipeline: convert and then send
./http -f template.http --no-send | ./http
# Or save and send later
./http -f template.http --no-send > request.http
./http -f request.http
The output is in RFC compliant format with:
- Environment variables substituted
- Shell commands executed
- Comments removed
- Proper CRLF (
\r\n) line endings - Auto-added headers (Content-Length, Host)
- Ready to send over the wire or pipe to another tool
Load and Send Any Format
Load requests from file in either format:
# Load HTP format (will preprocess)
./http -f template.http
# or using long form
./http --file template.http
# Load RFC compliant format (no preprocessing)
./http -f saved-request.http
# Preview RFC compliant request without sending
./http -f request.http --no-send
# Send with strict validation
./http -f request.http --strict
# Override port explicitly
./http -f request.http --port 8080
# Use verbose output
./http -f request.http --verbose
# or shorthand
./http -f request.http -v
Format Detection: The tool automatically detects the format:
- HTP format: Contains standard newlines (
\n) - will preprocess - RFC compliant: Contains CRLF (
\r\n) - used as-is
This is useful for:
- Writing request templates with dynamic content (HTP format)
- Converting templates to production-ready requests (RFC compliant)
- Sharing exact requests between team members
- Version controlling request templates (both formats)
- Piping requests to other tools for analysis
Strict RFC Compliance Mode
Use strict mode to enforce full RFC compliance (fails on warnings):
# This will fail if request has any validation warnings
cat request.http | ./http -strict
# Combine with --no-send for validation-only mode
cat request.http | ./http --no-send -strict > validated.http
Important: Strict mode disables HTP preprocessing features (comments, environment variables, shell commands). It requires RFC-compliant format only. This ensures that the request being validated is exactly what will be sent over the wire.
Example output:
Validation Warnings:
[WARN] Content-Type header is recommended when sending a body
Strict mode: Request has validation warnings and cannot be sent
Strict mode is useful for:
- Ensuring production requests are fully RFC compliant
- CI/CD pipelines where warnings should be treated as errors
- Testing request templates for compliance
- Validating saved/exported requests without preprocessing
Send Request with Validation
cat request.http | ./http
Output with colors showing:
- ✓ Green for successful validation
- ⚠️ Yellow for warnings
- ❌ Red for errors
- Cyan for request/response metadata
- Yellow for headers
Disable Colors
cat request.http | ./http -no-color
Verbose Mode
cat request.http | ./http -v
Send Plain HTTP Request
Use the --no-secure flag to force plain HTTP instead of HTTPS:
# Force HTTP for a path-only request
cat <<EOF | ./http --no-secure
GET /api/users HTTP/1.1
Host: example.com
EOF
# Force HTTP even when URL has https://
cat <<EOF | ./http --no-secure
GET https://example.com/api/users HTTP/1.1
Host: example.com
EOF
Validation Rules
The tool validates requests against HTTP standards:
Errors (Must Fix)
- Missing or invalid URL
- Missing scheme (http:// or https://) when using full URL format
- Missing Host header when using path-only URL (e.g.,
/api/users) - Missing host in URL
- Invalid URL format
- Missing Host header for HTTP/1.1
Warnings (Should Review)
- Non-standard HTTP methods
- Non-standard HTTP versions
- Non-standard URL schemes
- Methods with unexpected body (e.g., GET with body)
- Missing Content-Type when body is present
- Missing Content-Length (auto-added)
Architecture
The project is designed to be AI-agent-friendly with clear separation of concerns:
.
├── main.go # Entry point and CLI handling
└── internal/
├── models/ # Data structures
│ ├── request.go # HTTPRequest model
│ └── response.go # HTTPResponse model
├── parser/ # .http file parsing
│ └── parser.go # Parsing and preprocessing logic
├── validator/ # Request validation
│ └── validator.go # RFC compliance validation
└── client/ # HTTP client
└── client.go # TCP-based request sending
AI Agent Maintenance Notes
Each package is self-contained with:
- Clear comments explaining purpose and functionality
- Simple, linear logic flow
- Separated concerns (parsing, validation, sending)
- No complex abstractions or inheritance
- Standard library only (no external dependencies for core functionality)
HTTP Standards Supported
- HTTP/1.0, HTTP/1.1, HTTP/2, HTTP/3
- Standard HTTP methods: GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS, CONNECT, TRACE
- Custom HTTP methods (with warnings)
- Both HTTP and HTTPS protocols
- Chunked transfer encoding
- Content-Length based body reading
Development
Build
go build -o http
Test
Run the test suite:
./test.sh
Or use Make:
# Run all checks (format, lint, test)
make check
# Individual commands
make format # Format code with gofmt
make lint # Run go vet
make test # Run example tests
Contributing
Before submitting a pull request:
- Format your code:
make formatorgofmt -w . - Lint your code:
make lintorgo vet ./... - Run all tests:
./test.sh - Verify everything:
make check
See CONTRIBUTING.md for detailed guidelines.
Manual Testing
# Create a test request
cat > test.http <<EOF
GET https://httpbin.org/get HTTP/1.1
Host: httpbin.org
User-Agent: http-client-test/1.0
EOF
# Test it
cat test.http | ./http
Add to PATH
# Build
go build -o http
# Move to PATH location
sudo mv http /usr/local/bin/
# Now use from anywhere
echo "GET https://httpbin.org/get HTTP/1.1
Host: httpbin.org" | http
License
See LICENSE file for details.
Documentation
¶
There is no documentation for this package.