Skip to content

caddytest.py — Traffic Generator

caddytest.py is a configurable HTTP traffic generator. It mixes legitimate and malicious payloads against a target URL to exercise WAF rules and to stress-test request handling. The script is intended for local benchmarking and rule validation, not as part of an automated CI suite — for the latter use test.py (see testing.md).

Capabilities

  • A library of attack payloads covering SQLi, XSS, command injection, LFI, RCE, CRLF injection, SSRF, XXE, XPath, NoSQL, HTTP smuggling, Shellshock, LDAP, and RFI.
  • "Composite" requests that mix legitimate and malicious parameters in the same call.
  • Configurable behaviour profiles (constant, burst-then-calm, stealth) that change the request mix and pacing over the run.
  • Random HTTP method, random path segment, and random cookie generation.
  • Concurrency via a configurable thread count, retries, and timeouts.
  • Latency metrics (mean, stdev, min/max, median, p95, p99), response-size metrics, status-code distribution, and throughput.
  • Optional JSON summary file for machine consumption.

Installation

bash
pip install requests tqdm

Invocation

bash
python3 caddytest.py [OPTIONS]

Options

OptionDefaultDescription
--urlhttp://localhost:8080Target base URL.
--methodGETDefault HTTP method (GET, POST, PUT, DELETE, OPTIONS).
--num-requests100Total number of requests to send.
--delay1.0Base delay between requests (seconds).
--delay-jitter0.0Maximum jitter added to / subtracted from --delay.
--attack-typeallAttack key to use (or all for the full set).
--legit-percent0.0Percentage of requests that should be legitimate.
--compositeoffMix legitimate and malicious parameters per request.
--max-errors3Maximum errors before aborting.
--timeout5.0HTTP timeout per request (seconds).
--max-retries0Retries on failure.
--retry-delay0.1Delay between retries (seconds).
--seednoneRandom seed for reproducibility.
--proxynoneOutbound proxy URL.
--threads1Concurrent worker threads.
--random-methodoffRandomise the HTTP method per request.
--random-cookiesoffAdd random cookie headers.
--random-pathoffAppend a random path segment to --url.
--jsonoffSend payloads as JSON instead of form-encoded.
--log-filenoneFile for log output.
--progressoffDisplay a tqdm progress bar.
--scoreoffCompute a pass / fail score against the expected status codes below.
--expected-status-legit200Expected status code for legitimate requests.
--expected-status-malicious403Expected status code for malicious requests.
--expected-status-composite200Expected status code for composite requests.
--behaviordefaultOne of default, burst_calm, stealth.
--insecureoffDisable TLS verification.
--json-summary-filenonePath to write a JSON summary at the end.

Behaviour profiles

ProfileWhat it does
defaultUses the supplied options unchanged.
burst_calmFirst 30% of the run: rapid all-malicious burst with minimal delay. Next 30%: slower pace with the user-configured legitimate percentage and increased delay. Last 40%: forced GET requests against scanning-style endpoints (/admin, /config, /login, …).
stealthBumps the legitimate percentage, slows pacing, restricts methods to GET / POST.

Examples

bash
# 1000 default requests
python3 caddytest.py --num-requests 1000

# 1000 mostly-legitimate requests, four threads, no delay, stealth profile
python3 caddytest.py --num-requests 1000 --threads 4 --delay 0 \
    --legit-percent 100 --behavior stealth --progress

# 500 composite requests with the burst-then-calm profile
python3 caddytest.py --num-requests 500 --composite --behavior burst_calm --progress

# 200 random-method, random-cookie requests; write JSON summary
python3 caddytest.py --num-requests 200 --random-method --random-cookies \
    --json-summary-file summary.json --progress

Output

A representative end-of-run summary:

--- Test Summary ---
Total Requests        : 1000
Passed                : 574 (57.40% success)
Errors                : 0   (0.00% error)
Avg Latency           : 0.002 s
Std Latency           : 0.001 s
Min / Max Latency     : 0.001 s / 0.008 s
Median / P95 / P99    : 0.002 s / 0.003 s / 0.004 s
Throughput            : 2070.09 requests/s

Avg / Min / Max Body  : 5 / 0 / 12 bytes
Median / P95 / P99    : 0 / 12 / 12 bytes

Status Code Distribution: {403: 614, 200: 386}
Total Duration        : 0.48 s

When --json-summary-file is provided, the same data is also written as JSON.

Notes

  • The script uses Python's requests library; for HTTP/2 traffic generation use a different tool (e.g. h2load).
  • Concurrency is thread-based and, on CPython, bound by the GIL for parsing work. The script is I/O-bound in practice and scales reasonably to a few dozen threads.
  • Always run the generator from a host you control against a target you control. The payloads are intentionally malicious.