A curl-like HTTP client with performance testing capabilities, written in Rust.
- HTTP Methods: GET, POST, PUT, DELETE, PATCH, HEAD
- Custom Headers:
-H "Content-Type: application/json" - Request Body: Inline (
-d) or from file (-f) - Follow Redirects:
-L - Verbose Output:
-v - Performance Testing: Concurrent requests with latency metrics
You can install the pre-compiled binary (for Apple Silicon/Intel Macs and Linux) via our shell script:
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/dursunkoc/hurley/releases/latest/download/hurley-installer.sh | shYou can install the pre-compiled binary via our PowerShell script:
powershell -ExecutionPolicy ByPass -c "irm https://github.com/dursunkoc/hurley/releases/latest/download/hurley-installer.ps1 | iex"Standalone binaries for Windows, macOS, and Linux are available on the Releases page. Simply download the archive for your system, extract it, and place the hurley executable in your system's PATH.
If you have Rust and Cargo installed, you can build and install directly:
cargo install hurleygit clone https://github.com/dursunkoc/hurley.git
cd hurley
cargo build --release# Simple GET request
hurley https://httpbin.org/get
# POST with JSON body
hurley -X POST https://httpbin.org/post \
-H "Content-Type: application/json" \
-d '{"name": "test", "value": 123}'
# Include response headers
hurley -i https://httpbin.org/get
# Verbose output
hurley -v https://httpbin.org/get
# Follow redirects
hurley -L https://httpbin.org/redirect/3# 100 requests with 10 concurrent connections
hurley https://httpbin.org/get -c 10 -n 100
# Performance test with dataset
hurley https://httpbin.org --perf requests.json -c 20 -n 500
# JSON output for programmatic use
hurley https://httpbin.org/get -c 5 -n 50 --output jsonhurley supports data-driven test scenarios using the --data-file flag with CSV or JSON datasets and request templates containing {{column_name}} placeholders.
Features:
- Data Files:
--data-fileaccepts CSV (with headers) or JSON array of objects. - Substitution: Placeholders like
{{user_id}}are substituted in URL paths, headers, and request bodies. - Sequential Cycling: Requests cycle sequentially through dataset rows, allowing deterministic load simulation.
# Parameterized load test with CSV data
hurley -X POST https://api.example.com/users/{{user_id}} \
-H "Authorization: Bearer {{api_token}}" \
-d '{"role": "{{role}}"}' \
--data-file users.csv -c 10 -n 1000# users.csv
user_id,api_token,role
101,abc123token,admin
102,def456token,user
103,ghi789token,viewer# Single parameterized request (no -n or -c, creates one request per data row)
hurley https://api.example.com/users/{{user_id}} --data-file users.csvhurley supports running multi-step execution workflows based on conditional responses. By passing a JSON file to --workflow, you can execute dependent requests dynamically.
hurley --workflow flow.json https://httpbin.orgflow.json format:
{
"steps": [
{
"id": "get_user",
"request": {
"method": "GET",
"path": "/json"
}
},
{
"id": "conditional_step",
"condition": "responses.get_user.slideshow.author == \"Yours Truly\"",
"request": {
"method": "POST",
"path": "/post",
"body": {"message": "Success! The author matched."}
}
}
]
}The condition is evaluated against JSON responses of previous steps. Use responses.<step_id>.<json_path> to query values.
Create a JSON file with request definitions:
[
{"method": "GET", "path": "/users"},
{"method": "POST", "path": "/users", "body": {"name": "test"}},
{"method": "GET", "path": "/users/1", "headers": {"Authorization": "Bearer token"}}
]The performance test output includes:
- Request Summary: Total, successful, failed requests
- Timing: Total duration, requests/second
- Latency Distribution: Min, max, avg, p50, p95, p99
- Endpoint Breakdown: Detailed metrics for each unique endpoint (when using datasets)
═══════════════════════════════════════════════════════════
PERFORMANCE RESULTS
═══════════════════════════════════════════════════════════
📊 Request Summary
Total Requests: 100
Successful: 98
Failed: 2
Error Rate: 2.00%
⏱️ Timing
Total Duration: 5234.12 ms
Requests/sec: 19.11
📈 Latency Distribution
Min: 45.23 ms
Max: 312.45 ms
Avg: 89.67 ms
p50 (Median): 78.34 ms
p95: 198.23 ms
p99: 287.12 ms
═══════════════════════════════════════════════════════════
ENDPOINT BREAKDOWN
═══════════════════════════════════════════════════════════
📍 GET /users
───────────────────────────────────────────────────────────
📊 Request Summary
Total Requests: 60
Successful: 60
Failed: 0
Error Rate: 0.00%
⏱️ Timing
Total Duration: 3120.45 ms
Requests/sec: 19.23
📈 Latency Distribution
Min: 45.23 ms
Max: 150.12 ms
Avg: 75.34 ms
p50 (Median): 72.10 ms
p95: 120.45 ms
p99: 140.23 ms
📍 POST /users
───────────────────────────────────────────────────────────
📊 Request Summary
Total Requests: 40
Successful: 38
Failed: 2
Error Rate: 5.00%
⏱️ Timing
Total Duration: 2113.67 ms
Requests/sec: 18.92
📈 Latency Distribution
Min: 80.12 ms
Max: 312.45 ms
Avg: 110.23 ms
p50 (Median): 95.67 ms
p95: 250.34 ms
p99: 287.12 ms
═══════════════════════════════════════════════════════════
MIT License - see LICENSE for details.
Dursun Koc - @dursunkoc
