HTTP File Runner
A simple command-line tool written in Rust that parses .http files and executes HTTP requests, providing colored output with emojis to indicate success or failure.
Note: This project was originally written in Zig. The Zig implementation has been moved to a separate repository: christianhelle/httprunner-zig. This repository now contains only the Rust implementation, which is actively maintained and recommended for all use cases.
Features
- 🚀 Parse and execute HTTP requests from
.httpfiles - 📁 Support for multiple
.httpfiles in a single run - 🔍
--discovermode to recursively find and run all.httpfiles - 📝
--verbosemode for detailed request and response information - 📋
--logmode to save all output to a file for analysis and reporting - ✅ Color-coded output (green for success, red for failure)
- 📊 Summary statistics showing success/failure counts (per file and overall)
- 🌐 Support for various HTTP methods (GET, POST, PUT, DELETE, PATCH)
- 📝 Custom headers support with full request header implementation
- 🎯 Detailed error reporting with status codes
- 🛡️ Robust error handling for network issues
- 🔍 Response assertions for status codes, body content, and headers
- 🔧 Variables support with substitution in URLs, headers, and request bodies
- 🔧 Request Variables for chaining requests and passing data between HTTP calls
- 📋 Semantic versioning with git tag and commit information
- 🔍 Build-time version generation with automatic git integration
Version Information
The application includes comprehensive version information accessible via:
# or
This displays:
- Application version (semantic versioning)
- Git tag information
- Git commit hash
- Build timestamp
The version information is automatically generated at build time using git repository data.
Installation
Option 1: Quick Install Script (Recommended)
Linux/macOS:
|
Windows (PowerShell):
irm https://christianhelle.com/httprunner/install.ps1 | iex
The install scripts will:
- Automatically detect your platform and architecture
- Download the latest release from GitHub
- Install the binary to an appropriate location
- Add it to your PATH (if desired)
Custom installation directory:
# Linux/macOS
INSTALL_DIR=/.local/bin |
# Windows
|
Option 2: Manual Download
Download the latest release for your platform from the GitHub Releases page:
- Linux x86_64:
httprunner-linux-x86_64.tar.gz - macOS x86_64:
httprunner-macos-x86_64.tar.gz - macOS ARM64:
httprunner-macos-aarch64.tar.gz - Windows x86_64:
httprunner-windows-x86_64.zip
Extract the archive and add the binary to your PATH.
Option 3: Install from Crates.io
If you have Rust tooling installed, you can install httprunner directly from Crates.io:
This will download, compile, and install the latest version of httprunner. The binary will be installed to ~/.cargo/bin/ (or %USERPROFILE%\.cargo\bin\ on Windows), which should already be in your PATH if you installed Rust via rustup.
Option 4: Install from Snap Store
Option 5: Build from Source
Make sure you have Rust installed (version 1.70 or later).
The binary will be at target/release/httprunner (or httprunner.exe on Windows).
Option 6: Use Docker
The httprunner is available as a Docker image on Docker Hub at christianhelle/httprunner.
# Pull the latest image
Upgrading
Quick Upgrade
If you have httprunner already installed, you can easily upgrade to the latest version using the built-in upgrade command:
# Upgrade to the latest version
The upgrade command will:
- Automatically detect your platform (Windows, Linux, macOS)
- Download and run the appropriate install script
- Update httprunner to the latest version available
- Preserve your existing installation location
What it runs under the hood:
- Linux/macOS:
curl -fsSL https://christianhelle.com/httprunner/install | bash - Windows:
irm https://christianhelle.com/httprunner/install.ps1 | iex
After upgrading, you may need to restart your terminal to use the updated version.
Manual Upgrade
Alternatively, you can always re-run the installation scripts manually:
Linux/macOS:
|
Windows (PowerShell):
irm https://christianhelle.com/httprunner/install.ps1 | iex
Usage
If installed via Snap
# Run a single .http file
# Run a single .http file with verbose output
# Run a single .http file and save output to a log file
# Run a single .http file with verbose output and save to a custom log file
# Run multiple .http files
# Run multiple .http files and log output
# Discover and run all .http files recursively
# Discover and run all .http files with verbose output
# Discover and run all .http files and save output to log
# Discover and run all .http files with verbose output and logging
If built from source
Windows PowerShell Users
For proper emoji display in PowerShell, set UTF-8 encoding:
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
.\target\release\httprunner.exe <http-file>
# Run with verbose output
.\target\release\httprunner.exe <http-file> --verbose
# Run and save output to a log file
.\target\release\httprunner.exe <http-file> --log
# Run with verbose output and save to a custom log file
.\target\release\httprunner.exe <http-file> --verbose --log results.txt
# Run multiple files
.\target\release\httprunner.exe examples\simple.http examples\basic.http
# Run multiple files and log output
.\target\release\httprunner.exe examples\simple.http examples\basic.http --log execution.log
# Discover all .http files
.\target\release\httprunner.exe --discover
# Discover all .http files with verbose output
.\target\release\httprunner.exe --discover --verbose
# Discover all .http files and save output to log
.\target\release\httprunner.exe --discover --log discovery.log
# Discover all .http files with verbose output and logging
.\target\release\httprunner.exe --discover --verbose --log detailed_results.txt
Command Line
# Run a single .http file
# Run a single .http file with verbose output
# Run a single .http file and save output to a log file
# Run a single .http file with verbose output and save to a custom log file
# Run multiple .http files
# Run multiple .http files and log output
# Discover and run all .http files recursively from current directory
# Discover and run all .http files with verbose output
# Discover and run all .http files and save output to log
# Discover and run all .http files with verbose output and logging
Examples
# Test basic functionality
# Test basic functionality with verbose output
# Test basic functionality and save output to log
# Test basic functionality with verbose output and custom log file
# Test various APIs
# Test various APIs and log results
# Test different HTTP status codes
# Test different HTTP status codes with verbose logging
# Test basic GET requests
# Run multiple files at once
# Run multiple files with verbose output
# Run multiple files and log output
# Run multiple files with verbose output and logging
# Discover and run all .http files in the project
# Discover and run all .http files with verbose output
# Discover and run all .http files and save output to log
# Discover and run all .http files with verbose output and logging
# Run all files in a specific directory (using shell globbing)
# Run all files in a specific directory and log output
If using Docker
# Run with a single .http file (mount current directory)
# Run with a single .http file with verbose output
# Run with a single .http file and save output to log
# Run with a single .http file with verbose output and custom log file
# Run multiple .http files
# Run multiple .http files and log output
# Discover and run all .http files in current directory
# Discover and run all .http files with verbose output
# Discover and run all .http files and save output to log
# Discover and run all .http files with verbose output and logging
# Alternative: Create an alias for easier usage
Note: The Docker container mounts your current directory as /app in read-only mode to access your .http files. Make sure your .http files are in the current directory or subdirectories.
.http File Format
The HTTP File Runner supports a simple format for defining HTTP requests:
# Comments start with #
# Basic GET request
GET https://api.github.com/users/octocat
# Request with headers
GET https://httpbin.org/headers
User-Agent: HttpRunner/1.0
Accept: application/json
# POST request with body
POST https://httpbin.org/post
Content-Type: application/json
{
"name": "test",
"value": 123
}
Variables
The HTTP File Runner supports variables to make your .http files more flexible and reusable. Variables are defined using the @ syntax and can be referenced using double curly braces {{variable_name}}.
Variable Definition
Variables are defined at the beginning of a line with the syntax @VariableName=Value:
@hostname=localhost
@port=8080
@protocol=https
Variable Usage
Variables can be referenced in URLs, headers, and request bodies using double curly braces:
@hostname=localhost
@port=44320
GET https://{{hostname}}:{{port}}/
# Request with variable in headers
GET https://{{hostname}}:{{port}}/api/users
Authorization: Bearer {{token}}
# Request with variables in body
POST https://{{hostname}}:{{port}}/api/users
Content-Type: application/json
{
"host": "{{hostname}}",
"endpoint": "https://{{hostname}}:{{port}}/profile"
}
Variable Composition
Variables can be defined using values of other variables that were defined earlier in the file:
@hostname=localhost
@port=44320
@host={{hostname}}:{{port}}
@baseUrl=https://{{host}}
GET {{baseUrl}}/api/search/tool
Note: Variables must be defined before they can be used. The order of definition matters.
Environment Files
To give variables different values in different environments, create a file named http-client.env.json. This file should be located in the same directory as the .http file or in one of its parent directories.
Environment File Format
The environment file is a JSON file that contains one or more named environments. Here's an example:
Using Environment Variables
Variables from an environment file are referenced the same way as other variables:
# This will use the HostAddress from the specified environment
GET {{HostAddress}}/api/search/tool
Authorization: Bearer {{ApiKey}}
X-Environment: {{Environment}}
Specifying Environment
Use the --env flag to specify which environment to use:
# Use development environment
# Use production environment
Variable Override Behavior
If a variable is defined in both the .http file and the environment file:
- Environment variables are loaded first
- Variables in .http file override environment variables with the same name
- This allows you to have environment defaults while still being able to override them per request file
Request Variables
Request Variables allow you to chain HTTP requests by passing data from one request to another within the same .http file. This feature enables powerful workflows like authentication flows, data extraction, and response chaining.
Request Variable Syntax
The syntax for request variables follows this pattern:
{{<request_name>.(request|response).(body|headers).(*|JSONPath|XPath|<header_name>)}}
Where:
request_name: The name of a previous request (defined with# @name)request|response: Whether to extract from the request or responsebody|headers: Whether to extract from body or headers*|JSONPath|XPath|header_name: The extraction path
Authentication Flow Example
# @name authenticate
POST https://httpbin.org/post
Content-Type: application/json
{
"username": "admin@example.com",
"password": "secure123",
"access_token": "jwt_token_here",
"refresh_token": "refresh_jwt_here",
"user_id": "admin_001",
"role": "administrator"
}
###
# @name get_admin_data
GET https://httpbin.org/get
Authorization: Bearer {{authenticate.response.body.$.json.access_token}}
X-User-Role: {{authenticate.response.body.$.json.role}}
X-User-ID: {{authenticate.response.body.$.json.user_id}}
###
# @name create_audit_log
POST https://httpbin.org/post
Content-Type: application/json
{
"action": "admin_data_access",
"user_id": "{{authenticate.response.body.$.json.user_id}}",
"original_request": {
"username": "{{authenticate.request.body.$.username}}",
"timestamp": "2025-07-01T21:16:46Z"
},
"response_content_type": "{{get_admin_data.response.headers.Content-Type}}"
}
Supported Extraction Patterns
For JSON bodies:
$.property_name- Extract top-level properties$.nested.property- Extract nested properties$.json.property- Extract from "json" field (like httpbin.org responses)*- Extract entire body
For headers:
header_name- Extract specific header value (case-insensitive)
For request data:
- Same patterns as response, but extracts from the original request data
Request Variable Benefits
- Authentication Workflows: Extract tokens from login responses
- Data Chaining: Pass IDs or data between sequential requests
- Dynamic Headers: Use response headers in subsequent requests
- Request Auditing: Reference original request data in follow-up calls
- API Testing: Create comprehensive test flows with dependent requests
Note: Request variables can only reference requests that appear earlier in the same .http file and have been named with # @name.
Response Assertions
The HTTP File Runner supports assertions to validate HTTP responses. You can assert on status codes, response body content, and response headers.
Assertion Syntax
EXPECTED_RESPONSE_STATUS- Assert on HTTP status codeEXPECTED_RESPONSE_BODY- Assert that response body contains specific textEXPECTED_RESPONSE_HEADERS- Assert that response headers contain specific header-value pairs
Assertion Examples
# Status code assertion
GET https://httpbin.org/status/200
EXPECTED_RESPONSE_STATUS 200
# Status code and response body assertion
GET https://httpbin.org/status/404
EXPECTED_RESPONSE_STATUS 404
EXPECTED_RESPONSE_BODY "Not Found"
# Response header assertion
GET https://httpbin.org/json
EXPECTED_RESPONSE_STATUS 200
EXPECTED_RESPONSE_HEADERS "Content-Type: application/json"
# Multiple assertions on the same request
GET https://httpbin.org/json
EXPECTED_RESPONSE_STATUS 200
EXPECTED_RESPONSE_BODY "slideshow"
EXPECTED_RESPONSE_HEADERS "Content-Type: application/json"
Assertion Behavior
- ✅ Status Code: Exact match with expected HTTP status code
- ✅ Response Body: Checks if response body contains the expected text (substring match)
- ✅ Response Headers: Checks if the specified header exists and contains the expected value (substring match)
- 🔍 Assertion Results: Detailed output shows which assertions passed/failed
- ⚠️ Request Success: A request is considered successful only if all assertions pass (in addition to 2xx status code)
When assertions are present, the HTTP runner will:
- Always capture response headers and body (even in non-verbose mode)
- Evaluate all assertions against the response
- Display detailed assertion results
- Mark the request as failed if any assertion fails
Supported Features
- Methods: GET, POST, PUT, DELETE, PATCH
- Headers: Key-value pairs separated by
:(fully supported and sent with requests) - Body: Content after headers (separated by empty line)
- Comments: Lines starting with
#
Example Files
The examples/ directory contains several sample .http files:
simple.http- Basic requests for quick testing (4 requests)basic.http- Various GET requests to different websitesapis.http- Requests to public APIs (7 requests)status-codes.http- Tests different HTTP status codes (15 requests)request-variables.http- Demonstrates request chaining with variables (5 requests)variables.http- Shows variable usage and environment filescomprehensive.http- Complete feature demonstration
Output
The tool provides colored output with emojis:
- ✅ Green: Successful requests (2xx status codes)
- ❌ Red: Failed requests (4xx, 5xx status codes, or connection errors)
- 🚀 Blue: Informational messages
- ⚠️ Yellow: Warnings
Example Output
🚀 HTTP File Runner - Processing file: examples/simple.http
==================================================
Found 4 HTTP request(s)
✅ GET https://httpbin.org/status/200 - Status: 200
❌ GET https://httpbin.org/status/404 - Status: 404
✅ GET https://api.github.com/zen - Status: 200
✅ GET https://jsonplaceholder.typicode.com/users/1 - Status: 200
==================================================
Summary: 3/4 requests succeeded
Verbose Mode
The --verbose flag provides detailed information about HTTP requests and responses, including headers and response bodies. This is useful for debugging and detailed analysis of API interactions.
What verbose mode shows:
- 📤 Request Details: Method, URL, headers, and request body
- 📥 Response Details: Status code, duration, response headers, and response body
- ⏱️ Timing Information: Response times in milliseconds
Logging Mode
The --log flag enables output logging to a file, which is essential for:
- Automation & CI/CD: Save test results for build reports and analysis
- Debugging: Preserve detailed output for later review
- Documentation: Generate test reports and API documentation
- Monitoring: Track API performance and reliability over time
- Auditing: Keep records of API testing activities
How to use logging:
--logwithout filename: Saves to a file named 'log' in the current directory--log filename.txt: Saves to the specified filename- Works with all other flags:
--verbose --log,--discover --log, etc. - Combines with verbose mode for detailed logged output
Log file contents include:
- All terminal output (colored text is preserved)
- HTTP request and response details (when using --verbose)
- Success/failure indicators with emojis
- Summary statistics
- Error messages and diagnostics
- Timestamps and execution duration
Command Line Help
When running httprunner without any arguments, the following help text is displayed:
HTTP File Runner v0.1.9
Usage:
httprunner <http-file> [http-file2] [...] [--verbose] [--log [filename]] [--env <environment>]
httprunner [--verbose] [--log [filename]] [--env <environment>] --discover
httprunner --version | -v
httprunner --upgrade
httprunner --help | -h
Arguments:
<http-file> One or more .http files to process
--discover Recursively discover and process all .http files from current directory
--verbose Show detailed HTTP request and response information
--log [file] Log output to a file (defaults to 'log' if no filename is specified)
--env <env> Specify environment name to load variables from http-client.env.json
--version, -v Show version information
--upgrade Update httprunner to the latest version
--help, -h Show this help message
Practical Logging Examples
Here are common scenarios for using the --log functionality:
Basic Logging:
# Save output to default 'log' file
# Save output to custom file
Verbose Logging for Debugging:
# Detailed logging for debugging API issues
# Log discovery results with full details
CI/CD Integration:
# Generate test reports for build systems
# Daily API health checks
Performance Monitoring:
# Track API performance over time
# Load testing documentation
Example Log File Output:
When using --log, the log file will contain the exact same output as displayed in the terminal:
🚀 HTTP File Runner - Processing file: examples/simple.http
==================================================
Found 4 HTTP request(s)
✅ GET https://httpbin.org/status/200 - Status: 200
❌ GET https://httpbin.org/status/404 - Status: 404
✅ GET https://api.github.com/zen - Status: 200
✅ GET https://jsonplaceholder.typicode.com/users/1 - Status: 200
==================================================
Summary: 3/4 requests succeeded
When combined with --verbose, the log file includes full request and response details, making it invaluable for debugging and documentation purposes.
Verbose Mode Output
When using --verbose, you'll see detailed request and response information:
🚀 HTTP File Runner - Processing file: examples/simple.http
==================================================
Found 4 HTTP request(s)
📤 Request Details:
Method: GET
URL: https://httpbin.org/status/200
------------------------------
✅ GET https://httpbin.org/status/200 - Status: 200 - 145ms
📥 Response Details:
Status: 200
Duration: 145ms
Headers:
content-type: text/html; charset=utf-8
content-length: 0
server: gunicorn/19.9.0
access-control-allow-origin: *
access-control-allow-credentials: true
Body:
------------------------------
📤 Request Details:
Method: GET
URL: https://httpbin.org/status/404
------------------------------
❌ GET https://httpbin.org/status/404 - Status: 404 - 203ms
📥 Response Details:
Status: 404
Duration: 203ms
Headers:
content-type: text/html; charset=utf-8
content-length: 0
server: gunicorn/19.9.0
access-control-allow-origin: *
access-control-allow-credentials: true
Body:
------------------------------
==================================================
Summary: 3/4 requests succeeded
Multiple Files Output
When running multiple files or using --discover, you'll see a summary for each file plus an overall summary:
🔍 Discovering .http files recursively...
Found 7 .http file(s):
📄 .\examples\apis.http
📄 .\examples\basic.http
📄 .\examples\simple.http
📄 .\examples\quick.http
🚀 HTTP File Runner - Processing file: .\examples\simple.http
==================================================
Found 4 HTTP request(s)
✅ GET https://httpbin.org/status/200 - Status: 200
❌ GET https://httpbin.org/status/404 - Status: 404
✅ GET https://api.github.com/zen - Status: 200
✅ GET https://jsonplaceholder.typicode.com/users/1 - Status: 200
==================================================
File Summary: 3/4 requests succeeded
🚀 HTTP File Runner - Processing file: .\examples\quick.http
==================================================
Found 2 HTTP request(s)
✅ GET https://httpbin.org/status/200 - Status: 200
❌ GET https://httpbin.org/status/404 - Status: 404
==================================================
File Summary: 1/2 requests succeeded
🎯 Overall Summary:
Files processed: 2
Total requests: 4/6
Status Code Examples
From examples/status-codes.http:
- 2xx Success: Status 200, 201, 202 - shown in green ✅
- 3xx Redirects: Status 301, 302 - automatically followed, shown as 200 ✅
- 4xx Client Errors: Status 400, 401, 403, 404, 429 - shown in red ❌
- 5xx Server Errors: Status 500, 502, 503 - shown in red ❌
Error Handling
The tool handles various error conditions gracefully:
- File not found: Clear error message with red indicator
- Invalid URLs: Proper error reporting
- Network issues: Connection timeouts, unknown hosts, etc.
- Invalid HTTP methods: Validation and error reporting
Current Limitations
- Only basic authentication methods supported
Future Enhancements
- Authentication (Basic, Bearer tokens)
- Request timeouts configuration
- JSON response formatting
- Export results to different formats
Code Structure
The codebase is organized into multiple modules for better maintainability:
src/
├── main.rs # Main application entry point
├── cli.rs # Command-line interface parsing
├── types.rs # Data structures (HttpRequest, HttpResult, etc.)
├── colors.rs # Terminal color output
├── parser.rs # HTTP file parsing functionality
├── runner.rs # HTTP request execution logic
├── processor.rs # Request processing and output management
├── discovery.rs # Recursive .http file discovery
├── assertions.rs # Response assertion validation
├── request_variables.rs # Request chaining and variable extraction
├── environment.rs # Environment variable handling
├── log.rs # Logging functionality
└── upgrade.rs # Self-update feature
Module Overview
main.rs: Application entry point that orchestrates the overall workflowcli.rs: Handles command-line argument parsing usingclaptypes.rs: Defines the core data structures includingHttpRequestandHttpResultcolors.rs: Contains color output using thecoloredcrateparser.rs: Handles parsing of.httpfiles into structured requestsrunner.rs: Manages HTTP request execution usingreqwestprocessor.rs: Processes requests, manages logging, and handles output formattingdiscovery.rs: Implements recursive file system traversal usingwalkdirassertions.rs: Validates response assertions (status, body, headers)request_variables.rs: Handles request chaining and JSONPath extractionenvironment.rs: Loads and processes environment fileslog.rs: Manages file logging with timestampsupgrade.rs: Implements self-update functionality
This modular structure makes the code easier to understand, test, and extend.
CI/CD Pipeline
This project uses GitHub Actions for continuous integration and deployment:
Workflows
-
CI Pipeline (
build.yml): Runs on every push and pull request- Multi-platform builds (Linux, Windows, macOS)
- Code formatting checks
- Unit tests
- Security scanning with Trivy
-
Release Pipeline (
release.yml): Triggered on version tags- Cross-platform binary builds
- Automated GitHub releases
- Container image publishing to GitHub Container Registry
-
Security Scanning (
codeql.yml): Weekly security analysis- CodeQL static analysis
- Dependency vulnerability scanning
-
Dependency Updates: Automated dependency updates via Renovate
- Automated pull requests for Cargo dependency updates
Release Process
- Update version in relevant files
- Create and push a git tag:
git tag v1.0.0 && git push origin v1.0.0 - GitHub Actions automatically creates a release with binaries
- Container images are published to
ghcr.io/christianhelle/httprunner
Development Workflow
The project follows standard GitHub flow:
- Fork the repository
- Create a feature branch
- Make changes and ensure tests pass
- Submit a pull request
- CI checks run automatically
- Merge after review and approval
Installer Scripts
The project includes installer scripts for easy deployment:
install.sh- Bash installer script for Linux and macOSinstall.ps1- PowerShell installer script for Windows- Both scripts automatically detect platform/architecture and download the latest release
- Scripts are deployed to GitHub Pages and accessible at:
Testing the Installer Scripts
# Test the installer scripts locally
Development
Prerequisites
- Rust 1.70 or later (https://rustup.rs/)
- Git (for version generation)
Building
# Debug build
# Release build (optimized)
# Run tests
# Run with example
# Run with verbose mode
Dev Containers
For the easiest development experience, this repository includes a dev container configuration that provides a pre-configured environment with Rust and VS Code extensions.
GitHub Codespaces:
- Open the repository on GitHub
- Click the green "Code" button → "Codespaces" → "Create codespace on main"
- Wait for the environment to set up automatically
- Start coding! 🚀
Local Development with VS Code:
- Install the Dev Containers extension
- Clone this repository:
git clone https://github.com/christianhelle/httprunner.git - Open in VS Code:
code httprunner - When prompted, click "Reopen in Container" or use Command Palette: "Dev Containers: Reopen in Container"
What's included:
- Rust toolchain (stable) pre-installed
- PowerShell Core for build scripts
- VS Code Rust extensions (rust-analyzer)
- All dependencies ready for development
Manual Setup
For development, testing, and debugging without dev containers:
- Use
cargo buildfor debug builds with symbols - Use
cargo build --releasefor optimized release builds - Run tests with
cargo test - Format code with
cargo fmt - Lint code with
cargo clippy
Debugging Tips
- Use
println!()or thelogcrate for logging - Use VS Code's Rust debugging with rust-analyzer extension
- Use
cargo test -- --nocaptureto see test output - Check
target/debug/ortarget/release/for build artifacts
Testing
Tests are located in the same files as the code (Rust convention) and can be run with:
# Run all tests
# Run tests with output
# Run specific test
Legacy Zig Implementation
The original Zig implementation has been moved to a separate repository: christianhelle/httprunner-zig. The Zig version is no longer maintained in this repository. Please use the Rust implementation for all projects.
License
This project is open source and available under the MIT License
For tips and tricks on software development, check out my blog
If you find this useful and feel a bit generous then feel free to buy me a coffee ☕