Toxy
Hackable HTTP proxy for resiliency testing and simulated network conditions
Install / Use
/learn @h2non/ToxyREADME
toxy

Not actively maintained, may not work with latest node.js runtimes. If you are interested in maintaining toxy, please open an issue.
Hackable HTTP proxy to simulate server failure scenarios, systems resiliency testing and unexpected network conditions, built for node.js.
<img align="right" height="180" src="http://s8.postimg.org/ikc9jxllh/toxic.jpg" />It was mainly designed for failure resistance testing, when toxy becomes particularly useful in order to cover fault tolerance and resiliency capabilities of a system, especially in disruption-tolerant networks and service-oriented architectures, where toxy may act as MitM proxy among services in order to inject failure.
toxy allows you to plug in poisons, optionally filtered by rules, which essentially can intercept and alter the HTTP flow as you need, performing multiple evil actions in the middle of that process, such as limiting the bandwidth, delaying network packets, injecting network jitter latency or replying with a custom error or status code. It primarily operates at L7, although it can simulate L3 network conditions.
toxy can be fluently used programmatically or via HTTP API. It was built on top of rocky, a full-featured middleware-oriented HTTP proxy, and it's also pluggable in connect/express as standard middleware.
Requires node.js +4.
Contents
Features
- Full-featured HTTP/S proxy (backed by rocky and http-proxy)
- Hackable and elegant programmatic API (inspired on connect/express)
- Admin HTTP API for external management and dynamic configuration
- Featured built-in router with nested configuration
- Hierarchical and composable poisoning with rule based filtering
- Hierarchical middleware layer (both global and route scopes)
- Easily augmentable via middleware (based on connect/express middleware)
- Supports both incoming and outgoing traffic poisoning
- Built-in poisons (bandwidth, error, abort, latency, slow read...)
- Rule-based poisoning (probabilistic, HTTP method, headers, body...)
- Supports third-party poisons and rules
- Built-in balancer and traffic interceptor via middleware
- Inherits API and features from rocky
- Compatible with connect/express (and most of their middleware)
- Able to run as standalone HTTP proxy
Introduction
Why toxy?
There're some other similar solutions like toxy in the market, but most of them do not provide a proper programmatic control and usually are not easy to hack, configure or are directly closed to extensibility.
Furthermore, the majority of those solutions only operates at TCP L3 level stack instead of providing high-level abstractions to cover common requirements in the specific domain and nature of the HTTP L7 protocol, like toxy tries to provide
toxy brings a powerful hackable and extensible solution with a convenient abstraction, but without losing a proper low-level interface capabilities to deal with HTTP protocol primitives easily.
toxy was designed based on the rules of composition, simplicity and extensibility. Via its built-in hierarchical domain specific middleware layer you can easily augment toxy features to your own needs.
Concepts
toxy introduces two directives: poisons and rules.
Poisons are the specific logic which infects an incoming or outgoing HTTP transaction (e.g: injecting a latency, replying with an error). One HTTP transaction can be poisoned by one or multiple poisons, and those poisons can be also configured to infect both global or route level traffic.
Rules are a kind of match validation filters that inspects an HTTP request/response in order to determine, given a certain rules, if the HTTP transaction should be poisoned or not (e.g: if headers matches, query params, method, body...). Rules can be reused and applied to both incoming and outgoing traffic flows, including different scopes: global, route or poison level.
How it works
↓ ( Incoming request ) ↓
↓ ||| ↓
↓ +-------------+ ↓
↓ | Toxy Router | ↓ -> Match the incoming request
↓ +-------------+ ↓
↓ ||| ↓
↓ +--------------------+ ↓
↓ | Incoming phase | ↓ -> The proxy receives the request from the client
↓ |~~~~~~~~~~~~~~~~~~~~| ↓
↓ | ---------------- | ↓
↓ | | Exec Rules | | ↓ -> Apply configured rules for the incoming request
↓ | ---------------- | ↓
↓ | ||| | ↓
↓ | ---------------- | ↓
↓ | | Exec Poisons | | ↓ -> If all rules passed, then poison the HTTP flow
↓ | ---------------- | ↓
↓ +~~~~~~~~~~~~~~~~~~~~+ ↓
↓ / \ ↓
↓ \ / ↓
↓ +--------------------+ ↓
↓ | HTTP dispatcher | ↓ -> Forward the HTTP traffic to the target server, either poisoned or not
↓ +--------------------+ ↓
↓ / \ ↓
↓ \ / ↓
↓ +--------------------+ ↓
↓ | Outgoing phase | ↓ -> Receives response from target server
↓ |~~~~~~~~~~~~~~~~~~~~| ↓
↓ | ---------------- | ↓
↓ | | Exec Rules | | ↓ -> Apply configured rules for the outgoing request
↓ | ---------------- | ↓
↓ | ||| | ↓
↓ | ---------------- | ↓
↓ | | Exec Poisons | | ↓ -> If all rules passed, then poison the HTTP flow before send it to the client
↓ | ---------------- | ↓
↓ +~~~~~~~~~~~~~~~~~~~~+ ↓
↓ ||| ↓
↓ ( Send to the client ) ↓ -> Finally, send the request to the client, either poisoned or not
Usage
Installation
npm install toxy
Examples
See examples directory for more use cases.
var toxy = require('toxy')
var poisons = toxy.poisons
var rules = toxy.rules
// Create a new toxy proxy
var proxy = toxy()
// Default server to forward incoming traffic
proxy
.forward('http://httpbin.org')
// Register global poisons and rules
proxy
.poison(poisons.latency({ jitter: 500 }))
.rule(rules.probability(25))
// Register multiple routes
proxy
.get('/download/*')
.forward('http://files.myserver.net')
.poison(poisons.bandwidth({ bps: 1024 }))
.withRule(rules.headers({'Authorization': /^Bearer (.*)$/i }))
// Infect outgoing traffic only (after the server replied properly)
proxy
.get('/image/*')
.outgoingPoison(poisons.bandwidth({ bps: 512 }))
.withRule(rules.method('GET'))
.withRule(rules.timeThreshold({ duration: 1000, threshold: 1000 * 10 }))
.withRule(rules.responseStatus({ range: [ 200, 400 ] }))
proxy
.all('/api/*')
.poison(poisons.rateLimit({ limit: 10, threshold: 1000 }))
.withRule(rules.method(['POST', 'PUT', 'DELETE']))
// And use a different more permissive poison for GET requests
.poison(poisons.rateLimit({ limit: 50, threshold: 1000 }))
.withRule(rules.method('GET'))
// Handle the rest of the traffic
proxy
.all('/*')
.poison(poisons.slowClose({ delay: 1000 }))
.poison(poisons.slowRead({ bps: 128 }))
.withRule(rules.probability(50))
proxy.listen(3000)
console.log('Server listening on port:', 3000)
console.log('Test it:', 'http://localhost:3000/image/jpeg')
Benchmark
See toxy/benchmark for details.
Poisons
Poisons host specific logic which intercepts and mutates, wraps, modify and/or cancel an HTTP transaction in the proxy server. Poisons can be applied to incoming or outgoing, or even both traffic flows (see poison phases).
Poisons can be composed and reused for different HTTP scenarios. They are executed in FIFO order and asynchronously.
Poisoning scopes
toxy has a hierarchical design based on two different scopes: global and route.
Global scope points to all the incoming HTTP
Related Skills
gh-issues
339.3kFetch GitHub issues, spawn sub-agents to implement fixes and open PRs, then monitor and address PR review comments. Usage: /gh-issues [owner/repo] [--label bug] [--limit 5] [--milestone v1.0] [--assignee @me] [--fork user/repo] [--watch] [--interval 5] [--reviews-only] [--cron] [--dry-run] [--model glm-5] [--notify-channel -1002381931352]
node-connect
339.3kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
83.9kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
Writing Hookify Rules
83.9kThis skill should be used when the user asks to "create a hookify rule", "write a hook rule", "configure hookify", "add a hookify rule", or needs guidance on hookify rule syntax and patterns.
