Proxy Configuration
Goose supports routing traffic through HTTP, HTTPS, and SOCKS proxies by leveraging reqwest’s proxy capabilities. This is useful for testing applications through corporate proxies, debugging with tools like Burp Suite or OWASP ZAP, or routing traffic through specific network paths.
HTTP/HTTPS Proxies (No Setup Required)
HTTP and HTTPS proxies work out of the box with Goose - no compile-time changes needed. Simply set environment variables:
Important: HTTP_PROXY controls proxying for http:// URLs and HTTPS_PROXY for https:// URLs, whatever port they use. ALL_PROXY covers both, and HTTP_PROXY or HTTPS_PROXY wins over it when both are set. The proxy server itself typically runs on HTTP regardless of which requests it proxies.
# Set both to handle HTTP and HTTPS traffic
export HTTPS_PROXY=http://proxy.example.com:8080
export HTTP_PROXY=http://proxy.example.com:8080
# With authentication
export HTTPS_PROXY=http://username:[email protected]:8080
export HTTP_PROXY=http://username:[email protected]:8080
# Run your load test (no Cargo.toml changes needed)
cargo run --example simple -- --host https://example.com
SOCKS Proxy Support (Requires Setup)
To use SOCKS proxies with Goose, you need to enable SOCKS support in your project’s reqwest dependency.
Dependencies Setup
Add reqwest with the socks feature to your Cargo.toml:
[dependencies]
goose = "^0.19"
tokio = "^1"
reqwest = { version = "0.13", default-features = false, features = ["socks"] }
Note: Cargo automatically unifies features across all dependencies. Goose turns off reqwest’s default features and enables default-tls, form, gzip and json (and cookies with Goose’s default cookies feature), so adding socks in your own dependency results in reqwest being compiled with those features plus socks. Keep default-features = false on your reqwest line if you don’t want reqwest’s own defaults, such as http2 and system-proxy, added to the build.
Environment Variables
Configure SOCKS proxy using environment variables:
# Set both to handle HTTP and HTTPS traffic
export HTTPS_PROXY=socks5h://127.0.0.1:1080
export HTTP_PROXY=socks5h://127.0.0.1:1080
# Run your load test
cargo run --example simple -- --host https://example.com
SOCKS5 vs SOCKS5h
socks5://- DNS resolution happens locally, only network traffic goes through proxysocks5h://- Both DNS resolution and network traffic go through the proxy (recommended)
Use socks5h:// when you need DNS queries to be resolved through the SOCKS proxy, which is typically the case for accessing internal networks or when you want all traffic routed through the proxy.
Common Use Cases
Security Testing with Burp Suite
export HTTPS_PROXY=http://127.0.0.1:8080
export HTTP_PROXY=http://127.0.0.1:8080
cargo run --example simple -- --host https://target.example.com
SSH SOCKS Tunnel
# Set up SSH tunnel with SOCKS proxy
ssh -D 1080 -N [email protected]
# In another terminal, run load test through tunnel
export HTTPS_PROXY=socks5h://127.0.0.1:1080
export HTTP_PROXY=socks5h://127.0.0.1:1080
cargo run --example simple -- --host https://internal-app.example.com
Corporate Proxy
# Set both to proxy all traffic through corporate proxy
export HTTPS_PROXY=http://corporate-proxy.example.com:8080
export HTTP_PROXY=http://corporate-proxy.example.com:8080
cargo run --example simple -- --host https://external-site.com
Example Load Test
HTTP/HTTPS Proxy Example (Simple)
Cargo.toml (no special dependencies needed):
[package]
name = "my-loadtest"
version = "0.1.0"
edition = "2021"
[dependencies]
goose = "^0.19"
tokio = { version = "^1", features = ["macros", "rt-multi-thread"] }
# No special reqwest configuration needed for HTTP/HTTPS proxies
src/main.rs:
use goose::prelude::*;
#[tokio::main]
async fn main() -> Result<(), GooseError> {
GooseAttack::initialize()?
.register_scenario(scenario!("LoadTest")
.register_transaction(transaction!(homepage))
)
.set_default(GooseDefault::Host, "https://example.com")?
.execute()
.await?;
Ok(())
}
async fn homepage(user: &mut GooseUser) -> TransactionResult {
let _goose_metrics = user.get("/").await?;
Ok(())
}
Running with HTTP proxy:
export HTTPS_PROXY=http://proxy.example.com:8080
export HTTP_PROXY=http://proxy.example.com:8080
cargo run
SOCKS Proxy Example (Requires Setup)
Cargo.toml (with socks feature):
[package]
name = "my-loadtest"
version = "0.1.0"
edition = "2021"
[dependencies]
goose = "^0.19"
tokio = { version = "^1", features = ["macros", "rt-multi-thread"] }
# Add the socks feature; Cargo unifies it with the features Goose enables
reqwest = { version = "0.13", default-features = false, features = ["socks"] }
src/main.rs (same as above):
use goose::prelude::*;
#[tokio::main]
async fn main() -> Result<(), GooseError> {
GooseAttack::initialize()?
.register_scenario(scenario!("LoadTest")
.register_transaction(transaction!(homepage))
)
.set_default(GooseDefault::Host, "https://example.com")?
.execute()
.await?;
Ok(())
}
async fn homepage(user: &mut GooseUser) -> TransactionResult {
let _goose_metrics = user.get("/").await?;
Ok(())
}
Running with SOCKS proxy:
export HTTPS_PROXY=socks5h://127.0.0.1:1080
export HTTP_PROXY=socks5h://127.0.0.1:1080
cargo run
Troubleshooting
DNS Resolution Issues
If you see errors like “failed to lookup address information: No address associated with hostname”, try:
- Use
socks5h://instead ofsocks5://to route DNS through the proxy - Verify your SOCKS proxy is running and accessible
- Test with curl:
curl --proxy socks5h://127.0.0.1:1080 https://example.com
Authentication Issues
For proxies requiring authentication:
- Include credentials in the proxy URL:
socks5h://username:password@proxy:1080 - Ensure special characters in credentials are URL-encoded
Feature Not Available
If you get compilation errors about SOCKS features:
- Verify
reqwest = { version = "0.13", default-features = false, features = ["socks"] }is in your Cargo.toml - Run
cargo cleanand rebuild your project
Additional Resources
For more detailed proxy configuration options, see the official reqwest documentation:
- Reqwest Proxy Documentation - Complete guide to proxy configuration in reqwest
- Environment Variables:
HTTP_PROXY,HTTPS_PROXY,ALL_PROXY,NO_PROXY(and lowercase variants) - Programmatic Configuration: Using
reqwest::Proxyfor advanced proxy setups
Notes
- All GooseUsers in your load test will route through the configured proxy, including users given their own client with
GooseUser::set_client_builder, unless that client calls.no_proxy()or sets its ownreqwest::Proxy - The proxy configuration applies to the entire load test
- Both HTTP and HTTPS requests will use the proxy when configured
- Environment variables (
HTTP_PROXY,HTTPS_PROXY,NO_PROXY) are standard system proxy variables automatically recognized by reqwest, the HTTP client library that Goose uses internally - Goose does not define or manage these environment variables - they are set by you in your shell environment and consumed by reqwest
- Proxies from these environment variables need no reqwest feature: reqwest reads them for every client unless the client calls
.no_proxy(). Reqwest’s separatesystem-proxyfeature, which reads the macOS and Windows system proxy settings, is one of reqwest’s default features and Goose turns it off, so those system settings are not used unless your own reqwest dependency enablessystem-proxy - SOCKS proxy support requires the
socksfeature to be explicitly enabled in your project’s reqwest dependency