
복원력 테스트 및 시뮬레이션된 네트워크 조건을 위한 해킹 가능한 HTTP 프록시
현재 적극적으로 유지 관리되지 않으며, 최신 node.js 런타임에서 작동하지 않을 수 있습니다. toxy 유지 관리에 관심이 있으시면 이슈를 열어주십시오.
해킹 가능한 HTTP 프록시로 서버 장애 시나리오, 시스템 복원력 테스트 및 예상치 못한 네트워크 조건을 시뮬레이션하기 위해 node.js 용으로 구축되었습니다.
이 도구는 주로 장애 저항 테스트를 위해 설계되었으며, toxy는 특히 지연 허용 네트워크 및 서비스 지향 아키텍처에서 시스템의 내결함성 및 복원력 기능을 다루는 데 유용합니다. 이러한 환경에서 toxy는 서비스 간 MitM 프록시 역할을 하여 장애를 주입할 수 있습니다.
toxy를 사용하면 포이즌을 플러그인하고 선택적으로 규칙으로 필터링할 수 있습니다. 이는 본질적으로 필요에 따라 HTTP 흐름을 가로채고 변경하여 대역폭 제한, 네트워크 패킷 지연, 네트워크 지터 지연 주입 또는 사용자 정의 오류 또는 상태 코드로 응답하는 등 중간에서 여러 악의적인 작업을 수행할 수 있습니다.
주로 L7에서 작동하지만 L3 네트워크 조건을 시뮬레이션할 수 있습니다.
toxy는 프로그래밍 방식 또는 HTTP API를 통해 유연하게 사용할 수 있습니다.
rocky 위에 구축되었으며, connect/express에서 표준 미들웨어로 플러그인 가능합니다.
node.js +4가 필요합니다.
시장에는 toxy와 유사한 다른 솔루션이 있지만, 대부분은 적절한 프로그래밍 제어를 제공하지 않으며 일반적으로 해킹하거나 구성하기 어렵거나 확장이 직접적으로 차단되어 있습니다.
또한 이러한 솔루션의 대부분은 TCP L3 레벨 스택에서만 작동하며, toxy가 제공하려는 것처럼 HTTP L7 프로토콜의 특정 도메인과 특성에서 공통 요구 사항을 다루기 위한 고수준 추상화를 제공하지 않습니다.
toxy는 편리한 추상화와 함께 강력하고 해킹 가능하며 확장 가능한 솔루션을 제공하지만, HTTP 프로토콜 기본 요소를 쉽게 처리할 수 있는 적절한 저수준 인터페이스 기능을 잃지 않습니다.
toxy는 구성, 단순성 및 확장성의 원칙을 기반으로 설계되었습니다. 내장된 계층적 도메인별 미들웨어 계층을 통해 toxy 기능을 자신의 필요에 맞게 쉽게 확장할 수 있습니다.
toxy는 두 가지 지시어를 도입합니다: 포이즌(poisons)과 규칙(rules).
포이즌은 수신 또는 발신 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')
## Benchmark
자세한 내용은 [toxy/benchmark](https://github.com/h2non/toxy/tree/master/benchmark)를 참조하세요.
## 포이즌
포이즌은 프록시 서버에서 HTTP 트랜잭션을 가로채고 변경, 래핑, 수정 및/또는 취소하는 특정 로직을 호스팅합니다.
포이즌은 들어오는 트래픽, 나가는 트래픽 또는 둘 모두에 적용될 수 있습니다([포이즈닝 단계](#poisoning-phases) 참조).
포이즌은 다양한 HTTP 시나리오에 대해 구성 및 재사용이 가능합니다.
FIFO 순서로 비동기적으로 실행됩니다.
### 포이즈닝 범위
`toxy`는 `global`과 `route`라는 두 가지 범위를 기반으로 하는 계층적 설계를 가지고 있습니다.
**Global** 범위는 HTTP 메서드나 경로와 관계없이 프록시 서버가 수신하는 모든 들어오는 HTTP 트래픽을 대상으로 합니다.
**Route** 범위는 특정 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>Name</b></td><td>latency</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 흐름을 감염시킵니다.
**인수**:
- **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 또는 string 가능string - 본문 인코딩. 기본값 `utf8````js
toxy.poison(toxy.poisons.inject({
code: 503,
body: '{"error": "toxy injected error"}',
headers: {'Content-Type': 'application/json'}
}))#### Bandwidth
<table>
<tr>
<td><b>이름</b></td><td>bandwidth</td>
</tr>
<tr>
<td><b>중독 단계</b></td><td>수신 / 송신</td>
</tr>
<tr>
<td><b>서버에 도달</b></td><td>true</td>
</tr>
</table>
특정 시간 동안 발신 HTTP 트래픽에서 네트워크를 통해 전송되는 바이트 수를 제한합니다.
이 중독은 기본적으로 [throttle](#throttle)의 별칭입니다.
**인수**:
- **options** `object`
- **bytes** `number` - 전송할 바이트 청크의 양. 기본값 `1024`
- **threshold** `number` - 패킷 시간 프레임(밀리초). 기본값 `1000````js
toxy.poison(toxy.poisons.bandwidth({ bytes: 512 }))
| 이름 | rateLimit |
| 오염 단계 | 수신 / 발신 |
| 서버에 도달 | true |
프록시가 특정 임계 시간 프레임 내에 수신하는 요청 수를 제한합니다. API 제한을 테스트하도록 설계되었습니다. 일반적인 X-RateLimit-* 헤더를 노출합니다.
이는 매우 간단한 속도 제한 구현이며, 실제로 제한은 메모리 내에 저장되므로 완전히 휘발성입니다. npm에는 오염으로 연결할 수 있는 다양하고 일관된 속도 제한 구현이 많이 있습니다. 토큰 버킷 알고리즘에도 관심이 있을 수 있습니다.
인수:
object
number - 총 요청 수입니다. 기본값: 10number - 제한 시간 프레임(밀리초)입니다. 기본값: 1000string - 제한에 도달했을 때의 선택적 오류 메시지입니다.number - 제한에 도달했을 때의 HTTP 상태 코드입니다. 기본값: 429.```js
toxy.poison(toxy.poisons.rateLimit({ limit: 5, threshold: 10 * 1000 }))#### Slow read
<table>
<tr>
<td><b>이름</b></td><td>slowRead</td>
</tr>
<tr>
<td><b>중독 단계</b></td><td>incoming</td>
</tr>
<tr>
<td><b>서버 도달 여부</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 }))
이름: 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 연결을 중단합니다. 저수준 관점에서, 이는 서버의 소켓을 파괴하며, HTTP 애플리케이션 레벨 데이터를 전송하지 않고 TCP 레벨에서만 작동합니다.
**인수**:
- **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 |
응답 타임아웃을 정의합니다. 잠재적으로 느린 서버로 전달할 때 유용합니다.
Arguments:
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 순서로 실행됩니다. 평가 로직은 JavaScript의 `Array#every()`와 동일합니다: 모든 규칙이 통과해야 포이즈닝이 진행됩니다.
### 내장 규칙
#### 확률
<table>
<tr>
<td><b>이름</b></td><td>probability</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 |
| 포이즈닝 단계 | incoming / outgoing |
특정 시간 임계값과 지속 시간을 기준으로 포이즈닝을 활성화하는 간단한 규칙입니다. 예를 들어, 시간 임계값(예: 1분) 내에서 특정 시간(예: 1초) 동안 특정 포이즈닝을 활성화할 수 있습니다.
인수:
object
number - 활성화 시간 간격(밀리초)입니다. 기본값은 1000입니다.number - 포이즈닝을 다시 활성화하기 전에 대기할 시간 임계값(밀리초)입니다. 기본값은 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>헤더</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>incoming / outgoing</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 |
| 포이즌 단계 | outgoing |
주어진 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` - 상태 비교를 `lower than` 연산으로 수행. 기본값 `null`.
- **higher** `number` - 상태 비교를 `higher than` 연산으로 수행. 기본값 `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을 환영합니다.
규칙은 비동기적으로 boolean 값으로 해석되는 간단한 미들웨어 함수로, 주어진 HTTP 트랜잭션이 포이즈닝 시 무시되어야 하는지 결정합니다.
규칙은 미들웨어에서 next(err, shouldIgnore) 함수를 호출하여 boolean 매개변수로 해석되어야 합니다. 규칙이 일치하지 않아 독을 적용하지 말아야 하며, 따라서 다음 미들웨어 스택으로 계속 진행하려면 true 값을 전달합니다.
다음은 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)
For featured real examples, take a look to the built-in rules implementation
toxy API is completely built on top the rocky API. In other words, you can use any of the methods, features and middleware layer natively provided by rocky.
Create a new toxy proxy.
For supported options, please see rocky documentation```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
내장된 독소(poisons)의 맵을 노출합니다. 프로토타입 별칭: `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)
새 재생 서버(replay server)를 정의합니다.
여러 재생 서버를 정의하려면 이 메소드를 여러 번 호출할 수 있습니다.
자세한 내용은 [rocky 문서](https://github.com/h2non/rocky#programmatic-api)를 참조하세요.
#### toxy#use(middleware)
사용자 정의 미들웨어를 플러그인합니다.
자세한 내용은 [rocky 문서](https://github.com/h2non/rocky#middleware-layer)를 참조하세요.
#### toxy#useResponse(middleware)
응답 트래픽(outgoing) 미들웨어를 플러그인합니다.
자세한 내용은 [rocky 문서](https://github.com/h2non/rocky#middleware-layer)를 참조하세요.
#### toxy#useReplay(middleware)
재생 트래픽 미들웨어를 플러그인합니다.
자세한 내용은 [rocky 문서](https://github.com/h2non/rocky#middleware-layer)를 참조하세요.
#### toxy#requestBody(middleware)
수신 요청 본문(body)을 가로챕니다. 실시간으로 수정하는 데 유용합니다.
자세한 내용은 [rocky 문서](https://github.com/h2non/rocky#programmatic-api)를 참조하세요.
#### toxy#responseBody(middleware)
응답 본문(outgoing response body)을 가로챕니다. 실시간으로 수정하는 데 유용합니다.
자세한 내용은 [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`
[수신(incoming)](#poisoning-phases) 트래픽을 감염시키기 위한 새 독소(poison)를 등록합니다.
#### toxy#outgoingPoison(poison)
별칭: `useOutgoingPoison`, `responsePoison`
[송신(outgoing)](#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`
스택에서 이름 식별자로 등록된 `incoming` 독소를 검색하여 반환합니다.
#### toxy#getOutgoingPoison(name)
반환: `Directive|null`
스택에서 이름 식별자로 등록된 `outgoing` 독소를 검색하여 반환합니다.
#### toxy#getPoisons()
반환: `array<Directive>`
등록된 독소의 배열을 반환합니다.
#### toxy#getIncomingPoisons()
반환: `array<Directive>`
등록된 `incoming` 독소의 배열을 반환합니다.
#### toxy#getOutgoingPoisons()
반환: `array<Directive>`
등록된 `outgoing` 독소의 배열을 반환합니다.
#### 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의 시맨틱 버전(semantic version)입니다.
### ToxyRoute
`ToxyRoute`는 `Toxy` 전역 인터페이스와 동일한 인터페이스를 노출하며, 몇 가지 경로 수준의 [추가 메소드](https://github.com/h2non/rocky#routepath)를 제공합니다.
`ToxyRoute` API에 대해 수행하는 추가 작업은 경로 수준(중첩)에만 적용됩니다. 즉, 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)
toxy HTTP API는 리소스 기반 하이퍼미디어 링크를 포함한 JSON API 규칙을 따릅니다.
특별한 사용 사례는 admin server 예제를 참조하세요.```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-Key` 또는 `Authorization` HTTP 헤더를 통해 API 키 토큰을 정의해야 합니다.
이를 활성화하려면 `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`
예제 페이로드:```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
### Route poisons
#### GET /servers/:id/routes/:id/poisons
#### POST /servers/:id/routes/:id/poisons
Accepts: `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 ])
반환값: `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 인스턴스를 찾습니다. toxy 서버 ID 또는 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 - Tomas Aparicio
[](https://sourcegraph.com/github.com/h2non/toxy)