
Модифицируемый HTTP-прокси для тестирования устойчивости и имитации сетевых условий.
Не поддерживается активно, может не работать с последними версиями node.js. Если вы заинтересованы в поддержке toxy, пожалуйста, откройте issue.
Гибкий HTTP-прокси для симуляции сценариев отказов сервера, тестирования устойчивости систем и неожиданных сетевых условий, созданный для node.js.
Он был в первую очередь разработан для тестирования устойчивости к отказам, когда toxy становится особенно полезным для проверки возможностей отказоустойчивости и устойчивости системы, особенно в сетях, устойчивых к сбоям и сервис-ориентированных архитектурах, где toxy может выступать в качестве прокси-посредника (MitM) между сервисами для внедрения сбоев.
toxy позволяет подключать яды, опционально фильтруемые с помощью правил, которые по сути могут перехватывать и изменять HTTP-поток по вашему усмотрению, выполняя множество злонамеренных действий в середине этого процесса, таких как ограничение пропускной способности, задержка сетевых пакетов, внесение джиттера (дрожания) задержки или ответ с пользовательской ошибкой или кодом состояния. Он в основном работает на L7, хотя может симулировать сетевые условия L3.
toxy можно легко использовать программно или через HTTP API. Он построен на основе rocky, полнофункционального HTTP-прокси, ориентированного на промежуточное ПО, и также подключаем в connect/express как стандартное промежуточное ПО.
Требуется node.js +4.
На рынке существуют и другие похожие решения, подобные toxy, но большинство из них не предоставляют должного программного контроля и, как правило, сложны в настройке, либо непосредственно закрыты для расширения.
Более того, большинство этих решений работают только на уровне стека TCP L3, вместо того чтобы предоставлять высокоуровневые абстракции для покрытия типичных потребностей в специфической области и природе протокола HTTP L7, как это пытается сделать toxy.
toxy предлагает мощное, легко расширяемое решение с удобной абстракцией, не теряя при этом возможностей низкоуровневого интерфейса для простой работы с примитивами HTTP-протокола.
toxy был спроектирован на основе принципов композиции, простоты и расширяемости. Благодаря встроенному иерархическому доменному уровню промежуточного ПО вы можете легко расширять возможности toxy под свои нужды.
toxy вводит две директивы: яды и правила.
Яды — это конкретная логика, которая заражает входящую или исходящую HTTP-транзакцию (например, внесение задержки, ответ с ошибкой). Одна HTTP-транзакция может быть отравлена одним или несколькими ядами, и эти яды также можно настроить на заражение трафика как на глобальном уровне, так и на уровне маршрута.
Правила — это своего рода фильтры валидации совпадений, которые проверяют HTTP-запрос/ответ, чтобы определить, на основе определённых правил, должна ли HTTP-транзакция быть отравлена или нет (например, если заголовки совпадают, параметры запроса, метод, тело...). Правила можно повторно использовать и применять как к входящему, так и к исходящему потоку трафика, включая различные области действия: глобальная, на уровне маршрута или на уровне яда.
↓ ( 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
## Использование
### Установка```
npm install toxy
См. в каталоге examples дополнительные примеры использования.```js 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')
## Бенчмарк
Подробнее см. в [toxy/benchmark](https://github.com/h2non/toxy/tree/master/benchmark).
## Яды
Яды содержат специфическую логику, которая перехватывает, изменяет, оборачивает, модифицирует и/или отменяет HTTP-транзакции на прокси-сервере.
Яды могут применяться к входящему или исходящему трафику, а также к обоим потокам (см. [фазы отравления](#poisoning-phases)).
Яды могут быть скомпонованы и повторно использованы для различных HTTP-сценариев.
Они выполняются в порядке FIFO и асинхронно.
### Области отравления
`toxy` имеет иерархическую структуру, основанную на двух различных областях: `global` (глобальная) и `route` (маршрут).
**Глобальная** область относится ко всему входящему HTTP-трафику, принимаемому прокси-сервером, независимо от HTTP-метода или пути.
**Маршрут** относится к любому входящему трафику, который соответствует определённому HTTP-глаголу и пути URI.
Яды могут быть подключены к обеим областям, что позволяет работать с большей точностью и ограничивать область отравления.
Например, вы можете захотеть применить отравление ограничением пропускной способности только к определённым маршрутам, таким как `/download` или `/images`.
См. [routes.js](https://github.com/h2non/toxy/blob/master/examples/routes.js) для примера.
### Фазы отравления
Яды могут быть подключены к входящим или исходящим потокам трафика, а также к обоим одновременно.
**Входящее** отравление применяется, когда трафик получен прокси,
но ещё не передан целевому серверу.
**Исходящее** отравление относится к трафику, который был передан целевому серверу,
и когда прокси получает ответ от него, но этот ответ ещё не отправлен клиенту.
Это означает, что, по сути, вы можете подключать свои яды для заражения HTTP-трафика
до или после того, как запрос передан целевому HTTP-серверу или отправлен клиенту.
Это позволяет применять более точное и правильное отравление на основе запроса или ответа сервера.
Например, учитывая природу некоторых ядов, таких как `inject error`,
вы можете захотеть включить его в зависимости от ответа целевого сервера (например, наличие или отсутствие некоторого заголовка).
См. [poison-phases.js](https://github.com/h2non/toxy/blob/master/examples/poison-phases.js) для примера.
### Встроенные яды
#### Задержка (Latency)
<table>
<tr>
<td><b>Имя</b></td><td>latency</td>
</tr>
<tr>
<td><b>Фаза отравления</b></td><td>входящая / исходящая</td>
</tr>
<tr>
<td><b>Достигает сервера</b></td><td>true</td>
</tr>
</table>
Заражает HTTP-поток, добавляя дрожание задержки (jitter) в ответ.
**Аргументы**:
- **options** `object`
- **jitter** `number` - Значение дрожания в миллисекундах
- **max** `number` - Максимальное значение случайного дрожания
- **min** `number` - Минимальное значение случайного дрожания```js
toxy.poison(toxy.poisons.latency({ jitter: 1000 }))
// Or alternatively using a random value
toxy.poison(toxy.poisons.latency({ max: 1000, min: 100 }))
| Имя | inject |
| Фаза отравления | входящий / исходящий |
| Достигает сервера | false (только как входящее отравление) |
Внедряет пользовательский ответ, перехватывая запрос перед отправкой на целевой сервер. Полезно для внедрения ошибок, возникших на сервере.
Аргументы:
object
number — Код состояния HTTP ответа. По умолчанию 500object — Необязательные заголовки для отправкиmixed — Необязательные данные тела для отправки. Может быть buffer или stringstring — Кодировка тела. По умолчанию `utf8````js
toxy.poison(toxy.poisons.inject({
code: 503,
body: '{"error": "toxy injected error"}',
headers: {'Content-Type': 'application/json'}
}))#### Bandwidth
<table>
<tr>
<td><b>Name</b></td><td>bandwidth</td>
</tr>
<tr>
<td><b>Poisoning Phase</b></td><td>incoming / outgoing</td>
</tr>
<tr>
<td><b>Reaches the server</b></td><td>true</td>
</tr>
</table>
Ограничивает количество байтов, отправляемых по сети в исходящем HTTP-трафике за определенный промежуток времени.
Этот poison является псевдонимом для [throttle](#throttle).
**Аргументы**:
- **options** `object`
- **bytes** `number` - Размер блока байтов для отправки. По умолчанию `1024`
- **threshold** `number` - Временной интервал между пакетами в миллисекундах. По умолчанию `1000````js
toxy.poison(toxy.poisons.bandwidth({ bytes: 512 }))
| Имя | rateLimit |
| Фаза отравления | входящий / исходящий |
| Достигает сервера | true |
Ограничивает количество запросов, полученных прокси, в заданном временном интервале. Предназначено для тестирования лимитов API. Отображает типичные заголовки X-RateLimit-*.
Обратите внимание, что это очень простая реализация ограничения скорости: лимиты хранятся in-memory и поэтому полностью энергозависимы. Существует множество функциональных и согласованных реализаций ограничителей скорости в npm, которые можно подключить в качестве яда. Вам также может быть интересен алгоритм токеновой корзины.
Аргументы:
object
number - Общее количество запросов. По умолчанию 10number - Временной интервал в миллисекундах. По умолчанию 1000string - Необязательное сообщение об ошибке при достижении лимита.number - HTTP-статус код при достижении лимита. По умолчанию 429.```js
toxy.poison(toxy.poisons.rateLimit({ limit: 5, threshold: 10 * 1000 }))#### Медленное чтение
<table>
<tr>
<td><b>Name</b></td><td>slowRead</td>
</tr>
<tr>
<td><b>Poisoning Phase</b></td><td>входящий</td>
</tr>
<tr>
<td><b>Reaches the server</b></td><td>true</td>
</tr>
</table>
Медленно считывает входящие пакеты данных полезной нагрузки. Допустимо только для запросов, не являющихся GET.
**Аргументы**:
- **options** `object`
- **chunk** `number` - Размер фрагмента пакета в байтах. По умолчанию: `1024`
- **threshold** `number` - Ограничить временной порог в миллисекундах. По умолчанию: `1000````js
toxy.poison(toxy.poisons.slowRead({ chunk: 2048, threshold: 1000 }))
Name: slowOpen
| Имя | slowOpen |
| Фаза отравления | incoming |
| Достигает сервера | true |
Задерживает состояние готовности HTTP-соединения.
Аргументы:
object
number - Задержка соединения в миллисекундах. По умолчанию `1000````js
toxy.poison(toxy.poisons.slowOpen({ delay: 2000 }))#### Медленное закрытие
<table>
<tr>
<td><b>Имя</b></td><td>slowClose</td>
</tr>
<tr>
<td><b>Фаза отравления</b></td><td>входящий / исходящий</td>
</tr>
<tr>
<td><b>Достигает сервера</b></td><td>true</td>
</tr>
</table>
Задерживает сигнал закрытия HTTP-соединения (EOF).
**Аргументы**:
- **options** `object`
- **delay** `number` - Время задержки в миллисекундах. По умолчанию `1000````js
toxy.poison(toxy.poisons.slowClose({ delay: 2000 }))
| Имя | throttle |
| Фаза отравления | incoming / outgoing |
| Достигает сервера | true |
Ограничивает количество пакетов, отправляемых по сети в течение заданного временного интервала.
Аргументы:
object
number - Размер фрагмента пакета в байтах. По умолчанию 1024object - Временной интервал задержки фрагмента данных в миллисекундах. По умолчанию `100````js
toxy.poison(toxy.poisons.throttle({ chunk: 2048, threshold: 1000 }))#### Прерывание соединения
<table>
<tr>
<td><b>Имя</b></td><td>abort</td>
</tr>
<tr>
<td><b>Фаза отравления</b></td><td>входящий / исходящий</td>
</tr>
<tr>
<td><b>Достигает сервера</b></td><td>false (только как входящий яд)</td>
</tr>
</table>
Прерывает TCP-соединение. С низкоуровневой точки зрения это уничтожает сокет на сервере, работая только на уровне TCP без отправки каких-либо данных на уровне приложения HTTP.
**Аргументы**:
- **options** `object`
- **delay** `number` - Прерывает TCP-соединение после ожидания указанного количества миллисекунд. По умолчанию `0`
- **next** `boolean` - Если `true`, соединение будет прервано, если целевой сервер отвечает дольше, чем значение параметра `delay`. По умолчанию `false`
- **error** `Error` - Пользовательская внутренняя ошибка node.js, используемая при уничтожении сокета. По умолчанию `null````js
// Basic connection abort
toxy.poison(toxy.poisons.abort())
// Abort after a delay
toxy.poison(toxy.poisons.abort(1000))
// In this case, the socket will be closed if
// the target server takes more than
// 2 seconds to respond
toxy.poison(toxy.poisons.abort({ delay: 2000, next: true }))
| Имя | timeout |
| Фаза отравления | incoming / outgoing |
| Достигает сервера | true |
Определяет таймаут ответа. Полезно при пересылке на потенциально медленные серверы.
Аргументы:
number — Лимит таймаута в миллисекундах.```js
toxy.poison(toxy.poisons.timeout(5000))### Как писать яды
Яды реализованы как стандартные функции промежуточного ПО с тем же интерфейсом, что и промежуточное ПО connect/express.
Некоторые яды нетривиальны в реализации, поэтому вам нужно быть знакомым с модулем node.js [http](https://nodejs.org/api/http.html) и его API.
Вот простой пример яда задержки сервера:```js
var toxy = require('toxy')
function customLatencyPoison (delay) {
// We name the function since toxy uses it as identifier to get/disable/remove it in the future
return function customLatency (req, res, next) {
var timeout = setTimeout(process, delay)
req.once('close', onClose)
function onClose () {
clearTimeout(timeout)
next('client connection closed')
}
function process () {
req.removeListener('close', onClose)
next()
}
}
}
var proxy = toxy()
// Register and enable the poison
proxy
.get('/foo')
.poison(customLatencyPoison(2000))
Вы можете дополнительно расширить встроенные яды собственными ядами:```js toxy.addPoison(customLatency)
// Then you can use it as a built-in poison proxy .get('/foo') .poison(toxy.poisons.customLatency)
В качестве наглядного реального примера обратитесь к реализации [встроенных ядов](https://github.com/h2non/toxy/tree/master/lib/poisons).
## Правила
Правила — это простые проверочные фильтры, которые анализируют входящий или исходящий HTTP-трафик, чтобы определить, учитывая определённые правила (например, соответствие методу, заголовкам, параметрам запроса, телу...), должна ли текущая HTTP-транзакция быть отравлена на основе значения разрешения правила.
Правила полезны для компоновки, развязывания и повторного использования логики в различных сценариях отравления.
Правила могут применяться к глобальной области, маршруту или даже к области яда, и это также относится к обеим [фазам отравления](#poisoning-phases).
Правила выполняются в порядке FIFO. Их логика оценки эквивалентна `Array#every()` в JavaScript: все правила должны пройти, чтобы продолжить отравление.
### Встроенные правила
#### Вероятность
<table>
<tr>
<td><b>Имя</b></td><td>вероятность</td>
</tr>
<tr>
<td><b>Фаза отравления</b></td><td>входящий / исходящий</td>
</tr>
</table>
Включает правило по случайной вероятности. Полезно для случайного отравления.
**Аргументы**:
- **percentage** `number` - Процент фильтрации. По умолчанию `50````js
var rule = toxy.rules.probability(85)
toxy.rule(rule)
| Имя | timeThreshold |
| Фаза отравления | входящий / исходящий |
Простое правило для включения отравлений на основе определённого временного порога и длительности. Например, вы можете включить определённые отравления на заданный промежуток времени (например, 1 секунду) в пределах временного порога (например, 1 минуты).
Аргументы:
object
number — Длительность интервала включения в миллисекундах. По умолчанию 1000number — Временной порог в миллисекундах ожидания перед повторным включением отравления. По умолчанию `10000````js
// Enable the poisoning only 100 milliseconds per each 10 seconds
proxy.rule(toxy.rules.timeThreshold(100))
// Enable poisoning during 1 second every minute
proxy.rule(toxy.rules.timeThreshold({ duration: 1000, period: 1000 * 60 }))#### Метод
<table>
<tr>
<td><b>Имя</b></td><td>method</td>
</tr>
<tr>
<td><b>Фаза отравления</b></td><td>входящие / исходящие</td>
</tr>
</table>
Фильтрует по HTTP-методу.
**Аргументы**:
- **method** `string|array` - Метод или методы для фильтрации.```js
var method = toxy.rules.method(['GET', 'POST'])
toxy.rule(method)
Фильтрует по заголовку типа содержимого. Он должен присутствовать.
Аргументы:
string|regexp - Значение заголовка для сопоставления.```js
var rule = toxy.rules.contentType('application/json')
toxy.rule(rule)#### Заголовки
<table>
<tr>
<td><b>Название</b></td><td>headers</td>
</tr>
<tr>
<td><b>Фаза отравления</b></td><td>входящие / исходящие</td>
</tr>
</table>
Фильтрация по заголовкам запроса.
**Аргументы**:
- **headers** `object` - Заголовки для сопоставления по паре ключ-значение. `value` может быть строкой, регулярным выражением, `boolean` или `function(headerValue, headerName) => boolean````js
var matchHeaders = {
'content-type': /^application/\json/i,
'server': true, // meaning it should be present,
'accept': function (value, key) {
return value.indexOf('text') !== -1
}
}
var rule = toxy.rules.headers(matchHeaders)
toxy.rule(rule)
| Имя | responseHeaders |
| Фаза отравления | outgoing |
Фильтр по заголовкам ответа от целевого сервера. Аналогично правилу headers, но оценивает исходящий запрос.
Аргументы:
object - Заголовки для сопоставления по паре ключ-значение. value может быть string, regexp, boolean или `function(headerValue, headerName) => boolean````js
var matchHeaders = {
'content-type': /^application/\json/i,
'server': true, // meaning it should be present,
'accept': function (value, key) {
return value.indexOf('text') !== -1
}
}var rule = toxy.rules.responseHeaders(matchHeaders) toxy.rule(rule)
#### Тело
<table>
<tr>
<td><b>Имя</b></td><td>body</td>
</tr>
<tr>
<td><b>Фаза отравления</b></td><td>входящий / исходящий</td>
</tr>
</table>
Совпадение входящего тела запроса по заданной `string`, `regexp` или пользовательской функции `function`.
Это правило довольно простое, поэтому для сложного сопоставления тела (например, проверки по JSON схеме)
вам, вероятно, следует написать собственное правило.
**Аргументы**:
- **match** `string|regexp|function` - Содержимое тела для сопоставления
- **limit** `string` - Необязательно. Ограничение на размер тела в человекочитаемом формате. Например: `5mb`
- **encoding** `string` - Кодировка тела. По умолчанию `utf8`
- **length** `number` - Длина тела. По умолчанию берется из заголовка `Content-Length````js
var rule = toxy.rules.body('"hello":"world"')
toxy.rule(rule)
// Or using a filter function returning a boolean
var rule = toxy.rules.body(function contains(body) {
return body.indexOf('hello') !== -1
})
toxy.rule(rule)
| Имя | responseBody |
| Фаза отравления | исходящий |
Сопоставление исходящего тела полезной нагрузки по заданной string, regexp или пользовательской функции function.
Аргументы:
string|regexp|function - Тело содержимого для сопоставленияstring - Кодировка тела. По умолчанию utf8number - Длина тела. По умолчанию из заголовка `Content-Length````js
var rule = toxy.rules.responseBody('"hello":"world"')
toxy.rule(rule)// Or using a filter function returning a boolean var rule = toxy.rules.responseBody(function contains(body) { return body.indexOf('hello') !== -1 }) toxy.rule(rule)
#### Статус ответа
<table>
<tr>
<td><b>Имя</b></td><td>responseStatus</td>
</tr>
<tr>
<td><b>Фаза отравления</b></td><td>outgoing</td>
</tr>
</table>
Оценивает статус ответа от целевого сервера.
Применимо только к исходящим отравлениям.
**Аргументы**:
- **range** `array` - Пара диапазона кодов состояния для сопоставления. По умолчанию `[200, 300]`.
- **lower** `number` - Сравнивать статус как операцию `меньше, чем`. По умолчанию `null`.
- **higher** `number` - Сравнивать статус как операцию `больше, чем`. По умолчанию `null`.
- **value** `number` - Код состояния для точного сравнения (строгое равенство). По умолчанию `null`.
- **include** `array` - Неупорядоченный список кодов состояния для сопоставления. Полезно для указания пользовательского статуса. По умолчанию `null````js
// Strict evaluation of the status code
toxy.rule(toxy.rules.responseBody(200))
// Using a range of valid status
toxy.rule(toxy.rules.responseBody([200, 204]))
// Using relational comparison
toxy.rule(toxy.rules.responseBody({ higher: 199, lower: 400 }))
// Custom unordered status code to match
toxy.rule(toxy.rules.responseBody({ include: [200, 204, 400, 404] }))
Список доступных правил сторонних разработчиков, предоставленных сообществом. Принимаются PR.
Правила — это простые middleware-функции, которые асинхронно разрешаются с boolean значением, чтобы определить, следует ли игнорировать данный HTTP-запрос при отравлении.
Ваше правило должно разрешаться с параметром boolean, вызывая функцию next(err, shouldIgnore) в middleware, передавая значение true, если правило не совпадает и не должно применять отравление, и, следовательно, продолжать со следующим стеком middleware.
Вот пример простого правила, сопоставляющего HTTP-метод для определения:```js var toxy = require('toxy')
function customMethodRule(matchMethod) { /**
var proxy = toxy()
// Register and enable the rule proxy .get('/foo') .rule(customMethodRule('GET')) .poison(/* ... */)
Вы можете дополнить встроенные правила своими собственными правилами:```js
toxy.addRule(customMethodRule)
// Then you can use it as a built-in poison
proxy
.get('/foo')
.rules(toxy.rules.customMethodRule)
Для реальных примеров с демонстрацией возможностей посмотрите на встроенные правила implementation
API toxy полностью построено поверх rocky API. Другими словами, вы можете использовать любые методы, функции и промежуточный слой, изначально предоставляемые rocky.
Создайте новый прокси toxy.
Поддерживаемые опции см. в документации rocky.```js var toxy = require('toxy')
toxy({ forward: 'http://server.net', timeout: 30000 })
toxy .get('/foo') .poison(toxy.poisons.latency(1000)) .withRule(toxy.rules.contentType('json')) .forward('http://foo.server')
toxy .post('/bar') .poison(toxy.poisons.bandwidth({ bps: 1024 })) .withRule(toxy.rules.probability(50)) .forward('http://bar.server')
toxy .post('/boo') .outgoingPoison(toxy.poisons.bandwidth({ bps: 1024 })) .withRule(toxy.rules.method('GET')) .forward('http://boo.server')
toxy.all('/*')
toxy.listen(3000)
#### toxy#get(path, [ middleware... ])
Возвращает: `ToxyRoute`
Регистрирует новый маршрут для метода `GET`.
#### toxy#post(path, [ middleware... ])
Возвращает: `ToxyRoute`
Регистрирует новый маршрут для метода `POST`.
#### toxy#put(path, [ middleware... ])
Возвращает: `ToxyRoute`
Регистрирует новый маршрут для метода `PUT`.
#### toxy#patch(path, [ middleware... ])
Возвращает: `ToxyRoute`
#### toxy#delete(path, [ middleware... ])
Возвращает: `ToxyRoute`
Регистрирует новый маршрут для метода `DELETE`.
#### toxy#head(path, [ middleware... ])
Возвращает: `ToxyRoute`
Регистрирует новый маршрут для метода `HEAD`.
#### toxy#all(path, [ middleware... ])
Возвращает: `ToxyRoute`
Регистрирует новый маршрут для любого метода.
#### toxy#poisons `=>` Object
Предоставляет карту встроенных ядов. Псевдоним прототипа для `toxy.poisons`
#### toxy#rules `=>` Object
Предоставляет карту встроенных ядов. Псевдоним прототипа для `toxy.rules`
#### toxy#forward(url)
Определяет URL для перенаправления входящего трафика, полученного прокси.
#### toxy#balance(urls)
Перенаправляет на несколько серверов с балансировкой между ними.
Для получения дополнительной информации см. [документацию rocky](https://github.com/h2non/rocky#programmatic-api)
#### toxy#replay(url)
Определяет новый сервер воспроизведения.
Вы можете вызывать этот метод несколько раз для определения нескольких серверов воспроизведения.
Для получения дополнительной информации см. [документацию rocky](https://github.com/h2non/rocky#programmatic-api)
#### toxy#use(middleware)
Подключает пользовательское промежуточное ПО.
Для получения дополнительной информации см. [документацию rocky](https://github.com/h2non/rocky#middleware-layer).
#### toxy#useResponse(middleware)
Подключает промежуточное ПО для исходящего трафика ответов.
Для получения дополнительной информации см. [документацию rocky](https://github.com/h2non/rocky#middleware-layer).
#### toxy#useReplay(middleware)
Подключает промежуточное ПО для трафика воспроизведения.
Для получения дополнительной информации см. [документацию rocky](https://github.com/h2non/rocky#middleware-layer)
#### toxy#requestBody(middleware)
Перехватывает тело входящего запроса. Полезно для изменения на лету.
Для получения дополнительной информации см. [документацию rocky](https://github.com/h2non/rocky#programmatic-api)
#### toxy#responseBody(middleware)
Перехватывает тело исходящего ответа. Полезно для изменения на лету.
Для получения дополнительной информации см. [документацию rocky](https://github.com/h2non/rocky#programmatic-api)
#### toxy#middleware()
Возвращает стандартное промежуточное ПО для использования с connect/express.
#### toxy#host(host)
Переопределяет заголовок `Host` пользовательским значением. Аналогично опции `forwardHost`.
#### toxy#redirect(url)
Перенаправляет трафик на указанный URL.
#### toxy#findRoute(routeIdOrPath, [ method ])
Находит маршрут по ID или пути и методу.
#### toxy#listen(port)
Запускает встроенный HTTP-сервер, прослушивающий определённый TCP-порт.
#### toxy#close([ callback ])
Закрывает HTTP-сервер.
#### toxy#poison(poison)
Псевдоним: `usePoison`, `useIncomingPoison`
Регистрирует новый яд для заражения [входящего](#poisoning-phases) трафика.
#### toxy#outgoingPoison(poison)
Псевдоним: `useOutgoingPoison`, `responsePoison`
Регистрирует новый яд для заражения [исходящего](#poisoning-phases) трафика.
#### toxy#rule(rule)
Псевдоним: `useRule`
Регистрирует новое правило.
#### toxy#withRule(rule)
Псевдонимы: `ifRule`, `whenRule`, `poisonRule`, `poisonFilter`
Применяет новое правило для последнего зарегистрированного яда.
#### toxy#enable(poison)
Включает яд по имени идентификатора.
#### toxy#disable(poison)
Отключает яд по имени идентификатора.
#### toxy#remove(poison)
Возвращает: `boolean`
Удаляет яд входящего трафика по имени идентификатора или ссылке на объект.
#### toxy#removeOutgoing(poison)
Возвращает: `boolean`
Удаляет яд исходящего трафика по имени идентификатора или ссылке на объект.
#### toxy#isEnabled(poison)
Возвращает: `boolean`
Проверяет, включён ли яд по имени идентификатора.
#### toxy#disableAll()
Псевдоним: `disablePoisons`
Отключает все зарегистрированные яды.
#### toxy#getPoison(name)
Возвращает: `Directive|null`
Ищет и извлекает зарегистрированный яд в стеке по имени идентификатора.
#### toxy#getIncomingPoison(name)
Возвращает: `Directive|null`
Ищет и извлекает зарегистрированный `входящий` яд в стеке по имени идентификатора.
#### toxy#getOutgoingPoison(name)
Возвращает: `Directive|null`
Ищет и извлекает зарегистрированный `исходящий` яд в стеке по имени идентификатора.
#### toxy#getPoisons()
Возвращает: `array<Directive>`
Возвращает массив зарегистрированных ядов.
#### toxy#getIncomingPoisons()
Возвращает: `array<Directive>`
Возвращает массив зарегистрированных `входящих` ядов.
#### toxy#getOutgoingPoisons()
Возвращает: `array<Directive>`
Возвращает массив зарегистрированных `исходящих` ядов.
#### toxy#flush()
Псевдоним: `flushPoisons`
Удаляет все зарегистрированные яды для потоков входящего и исходящего трафика.
#### toxy#enableRule(rule)
Включает правило по имени идентификатора.
#### toxy#disableRule(rule)
Отключает правило по имени идентификатора.
#### toxy#removeRule(rule)
Возвращает: `boolean`
Удаляет правило по имени идентификатора.
#### toxy#disableRules()
Отключает все зарегистрированные правила.
#### toxy#isRuleEnabled(rule)
Возвращает: `boolean`
Проверяет, включено ли указанное правило по имени идентификатора.
#### toxy#getRule(rule)
Возвращает: `Directive|null`
Ищет и извлекает зарегистрированное правило в стеке по имени идентификатора.
#### toxy#getRules()
Возвращает: `array<Directive>`
Возвращает массив зарегистрированных правил, обёрнутых как `Directive`.
#### toxy#flushRules()
Удаляет все правила.
### toxy.addPoison(name, fn)
Расширяет встроенные яды.
### toxy.addRule(name, fn)
Расширяет встроенные правила.
### toxy.poisons `=>` Object
Предоставляет карту встроенных ядов.
### toxy.rules `=>` Object
Предоставляет карту встроенных правил.
### toxy.VERSION `=>` String
Текущая семантическая версия toxy.
### ToxyRoute
`ToxyRoute` предоставляет тот же интерфейс, что и глобальный интерфейс `Toxy`, с добавлением некоторых [дополнительных методов](https://github.com/h2non/rocky#routepath) уровня маршрута.
Дальнейшие действия, выполняемые через API `ToxyRoute`, будут применяться только на уровне маршрута (вложенные). Иными словами: API вы уже знаете.
Этот пример, вероятно, прояснит возможные вопросы:```js
var toxy = require('toxy')
var proxy = toxy()
// Now using the global API
proxy
.forward('http://server.net')
.poison(toxy.poisons.bandwidth({ bps: 1024 }))
.rule(toxy.rules.method('GET'))
// Now create a route
var route = proxy
.get('/foo')
.toPath('/bar') // Route-level API method
.host('server.net') // Route-level API method
.forward('http://new.server.net')
// Now using the ToxyRoute interface
route
.poison(toxy.poisons.bandwidth({ bps: 512 }))
.rule(toxy.rules.contentType('json'))
Удобная обёртка, используемая внутри для ядов и правил.
Обычно вам не нужно знать этот интерфейс, но для взлома или более низкоуровневых действий он может быть полезен.
Возвращает: boolean
Возвращает: boolean
Возвращает: boolean
Псевдоним: filter
Возвращает: function(req, res, next)
HTTP API toxy следует соглашениям JSON API, включая гипермедийные ссылки на основе ресурсов.
Для показательного примера использования см. пример административного сервера.```js const toxy = require('toxy')
// Create the toxy admin server var admin = toxy.admin({ cors: true }) admin.listen(9000)
// Create the toxy proxy var proxy = toxy() proxy.listen(3000)
// Add the toxy instance to be managed by the admin server admin.manage(proxy)
// Then configure the proxy proxy .forward('http://my.target.net')
proxy .get('/slow') .poison(toxy.poisons.bandwidth({ bps: 1024 }))
// Handle the rest of the traffic proxy .all('/*') .poison(toxy.poisons.bandwidth({ bps: 1024 * 5 }))
console.log('toxy proxy listening on port:', 3000) console.log('toxy admin server listening on port:', 9000)
Для получения дополнительных сведений о программном API администратора см. [ниже](#programmatic-api-1).
### Авторизация
HTTP API может быть защищён от неавторизованных клиентов. Авторизованные клиенты должны определить токен ключа API через HTTP-заголовки `API-Key` или `Authorization`.
Чтобы включить это, вы должны просто передать следующие параметры серверу администрирования `toxy`:```js
const toxy = require('toxy')
const opts = { apiKey: 's3cr3t' }
var admin = toxy.admin(opts)
admin.listen(9000)
console.log('protected toxy admin server listening on port:', 9000)
Иерархия:
toxy
Принимает: application/json
Пример полезной нагрузки:```js { "name": "method", "options": "GET" }
#### DELETE /servers/:id/rules
#### GET /servers/:id/rules/:id
#### DELETE /servers/:id/rules/:id
### Яды
#### GET /servers/:id/poison
#### POST /servers/:id/poisons
Принимает: `application/json`
Пример payload:```js
{
"name": "latency",
"phase": "outgoing",
"options": { "jitter": 1000 }
}
Принимает: application/json
Пример полезной нагрузки:```js { "name": "method", "options": "GET" }
#### DELETE /servers/:id/poisons/:id/rules
#### GET /servers/:id/poisons/:id/rules/:id
#### DELETE /servers/:id/poisons/:id/rules/:id
### Маршруты
#### GET /servers/:id/routes
#### POST /servers/:id/routes
Принимает: `application/json`
Пример данных:```js
{
"path": "/foo", // Required
"method": "GET", // use ALL for all the methods
"forward": "http://my.server", // Optional custom forward server URL
}
Принимает: application/json
Пример полезной нагрузки:```js { "name": "method", "options": "GET" }
#### DELETE /servers/:id/routes/:id/rules
#### GET /servers/:id/routes/:id/rules/:id
#### DELETE /servers/:id/routes/:id/rules/:id
### Отравления маршрутов
#### GET /servers/:id/routes/:id/poisons
#### POST /servers/:id/routes/:id/poisons
Принимает: `application/json`
Пример полезной нагрузки:```js
{
"name": "latency",
"phase": "outgoing",
"options": { "jitter": 1000 }
}
Принимает: application/json
Пример полезной нагрузки:```js { "name": "method", "options": "GET" }
#### DELETE /servers/:id/routes/:id/poisons/:id/rules
#### GET /servers/:id/routes/:id/poisons/:id/rules/:id
#### DELETE /servers/:id/routes/:id/poisons/:id/rules/:id
### Программный API
Встроенный HTTP-административный сервер также предоставляет простой интерфейс, открытый для расширения и хакерских целей.
Например, вы можете подключить дополнительное промежуточное ПО к административному серверу или зарегистрировать новые маршруты.
#### toxy.admin([ opts ])
Returns: `Admin`
**Поддерживаемые опции**:
- **apiKey** `string` - Необязательный API-ключ для защиты сервера
- **port** `number` - Необязательный. TCP-порт для прослушивания
- **cors** `boolean` - Включить CORS для доступа из веб-браузера
- **middleware** `array<function>` - Подключить дополнительное промежуточное ПО
- **ssl** `object` - Node.js HTTPS сервер [Параметры TLS](https://nodejs.org/api/tls.html#tls_tls_createserver_options_secureconnectionlistener).
##### Admin#listen([ port, host ])
Начать прослушивание в сети.
##### Admin#manage(toxy)
Управлять экземпляром сервера `toxy`.
##### Admin#find(toxy)
Найти экземпляр toxy. Принимает ID сервера toxy или экземпляр toxy.
##### Admin#remove(toxy)
Прекратить управление экземпляром toxy.
##### Admin#use(...middleware)
Зарегистрировать промежуточное ПО.
##### Admin#param(...middleware)
Зарегистрировать параметрическое промежуточное ПО.
##### Admin#get(path, [ ...middleware ])
Зарегистрировать GET-маршрут.
##### Admin#post(path, [ ...middleware ])
Зарегистрировать POST-маршрут.
##### Admin#put(path, [ ...middleware ])
Зарегистрировать PUT-маршрут.
##### Admin#delete(path, [ ...middleware ])
Зарегистрировать DELETE-маршрут.
##### Admin#patch(path, [ ...middleware ])
Зарегистрировать PATCH-маршрут.
##### Admin#all(path, [ ...middleware ])
Зарегистрировать маршрут, принимающий любой HTTP-метод.
##### Admin#middleware(req, res, next)
Промежуточное ПО для подключения с connect/express.
##### Admin#close(cb)
Остановить сервер.
## Лицензия
MIT - Томас Апарисио
[](https://sourcegraph.com/github.com/h2non/toxy)