
Proxy HTTP modificabile per test di resilienza e condizioni di rete simulate
Non mantenuto attivamente, potrebbe non funzionare con le ultime versioni di node.js. Se sei interessato a mantenere toxy, apri una issue.
Proxy HTTP hackerabile per simulare scenari di guasto del server, test di resilienza dei sistemi e condizioni di rete impreviste, costruito per node.js.
È stato progettato principalmente per test di resistenza ai guasti, dove toxy diventa particolarmente utile per coprire le capacità di tolleranza ai guasti e resilienza di un sistema, specialmente in reti tolleranti ai ritardi e architetture orientate ai servizi, dove toxy può agire come proxy MitM tra i servizi per iniettare guasti.
toxy ti permette di collegare veleni, opzionalmente filtrati da regole, che possono essenzialmente intercettare e alterare il flusso HTTP come necessario, eseguendo molteplici azioni malvagie nel mezzo di quel processo, come limitare la larghezza di banda, ritardare i pacchetti di rete, iniettare latenza di jitter di rete o rispondere con un codice di errore o stato personalizzato. Opera principalmente a L7, sebbene possa simulare condizioni di rete L3.
toxy può essere utilizzato fluentemente a livello di programmazione o tramite API HTTP. È stato costruito sopra rocky, un proxy HTTP completo orientato al middleware, ed è anche integrabile in connect/express come middleware standard.
Richiede node.js +4.
Esistono altre soluzioni simili a toxy sul mercato, ma la maggior parte non fornisce un adeguato controllo programmatico e di solito non sono facili da hackerare, configurare o sono direttamente chiuse all'estensibilità.
Inoltre, la maggior parte di queste soluzioni opera solo a livello TCP L3 invece di fornire astrazioni di alto livello per coprire requisiti comuni nel dominio specifico e nella natura del protocollo HTTP L7, come toxy cerca di fornire.
toxy offre una soluzione potente, hackerabile ed estensibile con un'astrazione conveniente, ma senza perdere le capacità di interfaccia di basso livello per gestire facilmente le primitive del protocollo HTTP.
toxy è stato progettato basandosi sui principi di composizione, semplicità ed estensibilità. Attraverso il suo strato middleware gerarchico specifico del dominio integrato, puoi facilmente estendere le funzionalità di toxy alle tue esigenze.
toxy introduce due direttive: veleni e regole.
Veleni sono la logica specifica che infetta una transazione HTTP in entrata o in uscita (ad esempio: iniettare una latenza, rispondere con un errore). Una transazione HTTP può essere avvelenata da uno o più veleni, e questi veleni possono anche essere configurati per infettare il traffico a livello globale o di rotta.
Regole sono una sorta di filtri di convalida di corrispondenza che ispezionano una richiesta/risposta HTTP per determinare, date determinate regole, se la transazione HTTP deve essere avvelenata o meno (ad esempio: se le intestazioni corrispondono, parametri di query, metodo, corpo...). Le regole possono essere riutilizzate e applicate sia al flusso di traffico in entrata che in uscita, inclusi diversi ambiti: globale, di rotta o di veleno.
↓ ( 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
## Utilizzo
### Installazione```
npm install toxy
Vedi la directory esempi per ulteriori casi d'uso.```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
See [toxy/benchmark](https://github.com/h2non/toxy/tree/master/benchmark) for details.
## Veleni
I veleni ospitano logiche specifiche che intercettano e mutano, incapsulano, modificano e/o annullano una transazione HTTP nel server proxy.
I veleni possono essere applicati al traffico in entrata o in uscita, o anche a entrambi i flussi (vedi [fasi di avvelenamento](#poisoning-phases)).
I veleni possono essere composti e riutilizzati per diversi scenari HTTP.
Vengono eseguiti in ordine FIFO e in modo asincrono.
### Ambiti di avvelenamento
`toxy` ha un design gerarchico basato su due diversi ambiti: `global` e `route`.
L'ambito **Global** si riferisce a tutto il traffico HTTP in entrata ricevuto dal server proxy, indipendentemente dal metodo HTTP o dal percorso.
L'ambito **Route** si riferisce a qualsiasi traffico in entrata che corrisponde a un verbo HTTP e un percorso URI specifici.
I veleni possono essere collegati a entrambi gli ambiti, il che significa che puoi operare con maggiore precisione e limitare l'ambito dell'avvelenamento, ad esempio potresti voler applicare un avvelenamento da limite di larghezza di banda solo a determinate rotte, come `/download` o `/images`.
See [routes.js](https://github.com/h2non/toxy/blob/master/examples/routes.js) for a featured example.
### Fasi di avvelenamento
I veleni possono essere collegati ai flussi di traffico in entrata o in uscita, o anche a entrambi.
L'avvelenamento **In entrata** viene applicato quando il traffico è stato ricevuto dal proxy ma non è stato ancora inoltrato al server di destinazione.
L'avvelenamento **In uscita** si riferisce al traffico che è stato inoltrato al server di destinazione e quando il proxy riceve la risposta da esso, ma tale risposta non è stata ancora inviata al client.
Ciò significa, essenzialmente, che puoi collegare i tuoi veleni per infettare il traffico HTTP prima o dopo che la richiesta venga inoltrata al server HTTP di destinazione o inviata al client.
Questo ti permette di applicare un avvelenamento migliore e più accurato basato sulla richiesta o sulla risposta del server.
Ad esempio, data la natura di alcuni veleni, come `inject error`, potresti volerlo abilitare in base alla risposta del server di destinazione (ad esempio: se qualche header è presente o meno).
See [poison-phases.js](https://github.com/h2non/toxy/blob/master/examples/poison-phases.js) for a featured example.
### Veleni integrati
#### Latenza
<table>
<tr>
<td><b>Nome</b></td><td>latency</td>
</tr>
<tr>
<td><b>Fase di avvelenamento</b></td><td>in entrata / in uscita</td>
</tr>
<tr>
<td><b>Raggiunge il server</b></td><td>true</td>
</tr>
</table>
Infetta il flusso HTTP iniettando un jitter di latenza nella risposta
**Argomenti**:
- **options** `object`
- **jitter** `number` - Valore del jitter in millisecondi
- **max** `number` - Valore massimo del jitter casuale
- **min** `number` - Valore minimo del jitter casuale```js
toxy.poison(toxy.poisons.latency({ jitter: 1000 }))
// Or alternatively using a random value
toxy.poison(toxy.poisons.latency({ max: 1000, min: 100 }))
| Nome | inject |
| Fase di avvelenamento | in entrata / in uscita |
| Raggiunge il server | falso (solo come veleno in entrata) |
Inietta una risposta personalizzata, intercettando la richiesta prima di inviarla al server di destinazione. Utile per iniettare errori originati dal server.
Argomenti:
object
number - Codice di stato HTTP della risposta. Predefinito 500object - Intestazioni opzionali da inviaremixed - Dati del corpo opzionali da inviare. Può essere un buffer o una stringastring - Codifica del corpo. Predefinito `utf8````js
toxy.poison(toxy.poisons.inject({
code: 503,
body: '{"error": "toxy injected error"}',
headers: {'Content-Type': 'application/json'}
}))#### Bandwidth
<table>
<tr>
<td><b>Nome</b></td><td>bandwidth</td>
</tr>
<tr>
<td><b>Fase di avvelenamento</b></td><td>in entrata / in uscita</td>
</tr>
<tr>
<td><b>Raggiunge il server</b></td><td>true</td>
</tr>
</table>
Limita la quantità di byte inviati sulla rete nel traffico HTTP in uscita per un determinato intervallo di tempo.
Questo veleno è sostanzialmente un alias di [throttle](#throttle).
**Argomenti**:
- **options** `object`
- **bytes** `number` - Quantità di blocchi di byte da inviare. Predefinito `1024`
- **threshold** `number` - Intervallo di tempo dei pacchetti in millisecondi. Predefinito `1000````js
toxy.poison(toxy.poisons.bandwidth({ bytes: 512 }))
| Nome | rateLimit |
| Fase di avvelenamento | incoming / outgoing |
| Raggiunge il server | true |
Limita la quantità di richieste ricevute dal proxy in un intervallo di tempo soglia specifico. Progettato per testare i limiti delle API. Espone tipici header X-RateLimit-*.
Nota che questa è un'implementazione molto semplice del limite di velocità, infatti i limiti sono memorizzati in memoria, quindi sono completamente volatili. Esistono numerose implementazioni complete e coerenti di rate limiter su npm che puoi collegare come veleno. Potresti essere anche interessato all'algoritmo token bucket.
Argomenti:
object
number - Numero totale di richieste. Predefinito a 10number - Intervallo di tempo limite in millisecondi. Predefinito a 1000string - Messaggio di errore opzionale quando il limite viene raggiunto.number - Codice di stato HTTP quando il limite viene raggiunto. Predefinito a 429.```js
toxy.poison(toxy.poisons.rateLimit({ limit: 5, threshold: 10 * 1000 }))#### Lettura lenta
<table>
<tr>
<td><b>Nome</b></td><td>slowRead</td>
</tr>
<tr>
<td><b>Fase di avvelenamento</b></td><td>incoming</td>
</tr>
<tr>
<td><b>Raggiunge il server</b></td><td>true</td>
</tr>
</table>
Legge lentamente i pacchetti di dati del payload in arrivo. Valido solo per richieste non GET.
**Argomenti**:
- **options** `object`
- **chunk** `number` - Dimensione del pezzo del pacchetto in byte. Predefinito a `1024`
- **threshold** `number` - Limite del periodo di tempo di soglia in millisecondi. Predefinito a `1000````js
toxy.poison(toxy.poisons.slowRead({ chunk: 2048, threshold: 1000 }))
Nome: slowOpen
| Nome | slowOpen |
| Fase di avvelenamento | in arrivo |
| Raggiunge il server | true |
Ritarda lo stato di connessione HTTP pronta.
Argomenti:
object
number - Ritardo connessione in millisecondi. Predefinito a `1000````js
toxy.poison(toxy.poisons.slowOpen({ delay: 2000 }))#### Chiusura lenta
<table>
<tr>
<td><b>Nome</b></td><td>slowClose</td>
</tr>
<tr>
<td><b>Fase di avvelenamento</b></td><td>in entrata / in uscita</td>
</tr>
<tr>
<td><b>Raggiunge il server</b></td><td>true</td>
</tr>
</table>
Ritarda il segnale di chiusura della connessione HTTP (EOF).
**Argomenti**:
- **options** `object`
- **delay** `number` - Tempo di ritardo in millisecondi. Predefinito a `1000````js
toxy.poison(toxy.poisons.slowClose({ delay: 2000 }))
| Nome | throttle |
| Fase di Avvelenamento | in entrata / in uscita |
| Raggiunge il server | true |
Limita la quantità di pacchetti inviati sulla rete in uno specifico intervallo di tempo di soglia.
Argomenti:
object
number - Dimensione del chunk di pacchetti in byte. Default 1024object - Intervallo di ritardo del chunk di dati in millisecondi. Default `100````js
toxy.poison(toxy.poisons.throttle({ chunk: 2048, threshold: 1000 }))#### Interruzione connessione
<table>
<tr>
<td><b>Nome</b></td><td>abort</td>
</tr>
<tr>
<td><b>Fase di avvelenamento</b></td><td>in entrata / in uscita</td>
</tr>
<tr>
<td><b>Raggiunge il server</b></td><td>false (solo come veleno in entrata)</td>
</tr>
</table>
Interrompe la connessione TCP. Dal punto di vista di basso livello, questo distruggerà il socket sul server, operando solo a livello TCP senza inviare alcun dato specifico a livello applicativo HTTP.
**Argomenti**:
- **options** `object`
- **delay** `number` - Interrompe la connessione TCP dopo aver atteso i millisecondi indicati. Predefinito a `0`
- **next** `boolean` - Se `true`, la connessione verrà interrotta se il server di destinazione impiega più del parametro `delay` per rispondere. Predefinito a `false`
- **error** `Error` - Errore interno personalizzato di Node.js da utilizzare quando si distrugge il socket. Predefinito a `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 }))
| Name | timeout |
| Fase di avvelenamento | incoming / outgoing |
| Raggiunge il server | true |
Definisce un timeout di risposta. Utile quando si inoltra a server potenzialmente lenti.
Argomenti:
number - Limite di timeout in millisecondi```js
toxy.poison(toxy.poisons.timeout(5000))### Come scrivere i poison
I poison sono implementati come funzioni middleware standard con la stessa interfaccia dei middleware connect/express.
Alcuni poison non sono banali da implementare, quindi devi avere familiarità con il modulo [http](https://nodejs.org/api/http.html) di node.js e la sua API.
Ecco un semplice esempio di un poison di latenza del server:```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))
Puoi opzionalmente estendere i veleni integrati con i tuoi veleni personalizzati:```js toxy.addPoison(customLatency)
// Then you can use it as a built-in poison proxy .get('/foo') .poison(toxy.poisons.customLatency)
Per un esempio reale in primo piano, dai un'occhiata all'implementazione dei [veleni integrati](https://github.com/h2non/toxy/tree/master/lib/poisons).
## Regole
Le regole sono semplici filtri di validazione che ispezionano il traffico HTTP in entrata o in uscita per determinare, date determinate regole (ad es.: corrispondenza del metodo, intestazioni, parametri di query, corpo...), se la transazione HTTP corrente dovrebbe essere avvelenata o meno, in base al valore di risoluzione della regola.
Le regole sono utili per comporre, disaccoppiare e riutilizzare la logica tra diversi scenari di avvelenamento.
Le regole possono essere applicate a livello globale, di route o anche di veleno, e si applicano anche a entrambe le [fasi di avvelenamento](#poisoning-phases).
Le regole vengono eseguite in ordine FIFO. La loro logica di valutazione è equivalente a `Array#every()` in JavaScript: tutte le regole devono essere superate per procedere con l'avvelenamento.
### Regole integrate
#### Probabilità
<table>
<tr>
<td><b>Nome</b></td><td>probability</td>
</tr>
<tr>
<td><b>Fase di avvelenamento</b></td><td>in entrata / in uscita</td>
</tr>
</table>
Abilita la regola in modo probabilistico casuale. Utile per l'avvelenamento casuale.
**Argomenti**:
- **percentage** `number` - Percentuale di filtraggio. Default `50````js
var rule = toxy.rules.probability(85)
toxy.rule(rule)
| Nome | timeThreshold |
| Poison Phase | incoming / outgoing |
Regola semplice per abilitare i poison basati su una specifica soglia temporale e durata. Ad esempio, puoi abilitare determinati poison per una specifica quantità di tempo (es: 1 secondo) all'interno di una soglia temporale (es: 1 minuto).
Argomenti:
object
number - Abilita l'intervallo di tempo in millisecondi. Predefinito a 1000number - Soglia temporale in millisecondi da attendere prima di riabilitare il poison. Predefinito a `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 }))#### Metodo
<table>
<tr>
<td><b>Nome</b></td><td>method</td>
</tr>
<tr>
<td><b>Fase di avvelenamento</b></td><td>in entrata / in uscita</td>
</tr>
</table>
Filtra per metodo HTTP.
**Argomenti**:
- **method** `string|array` - Metodo o metodi da filtrare.```js
var method = toxy.rules.method(['GET', 'POST'])
toxy.rule(method)
Filtra per l'header del tipo di contenuto. Deve essere presente.
Argomenti:
string|regexp - Valore dell'header da confrontare.```js
var rule = toxy.rules.contentType('application/json')
toxy.rule(rule)#### Headers
<table>
<tr>
<td><b>Nome</b></td><td>headers</td>
</tr>
<tr>
<td><b>Poison Phase</b></td><td>incoming / outgoing</td>
</tr>
</table>
Filtra per header delle richieste.
**Argomenti**:
- **headers** `object` - Header da abbinare per coppia chiave-valore. `value` può essere una stringa, regexp, `boolean` o `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)
| Nome | responseHeaders |
| Poison Phase | outgoing |
Filtra per intestazioni di risposta dal server di destinazione. Come la regola headers, ma valuta la richiesta in uscita.
Argomenti:
object - Headers da confrontare per coppia chiave-valore. value può essere una string, regexp, boolean o `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)
#### Corpo
<table>
<tr>
<td><b>Nome</b></td><td>body</td>
</tr>
<tr>
<td><b>Fase di avvelenamento</b></td><td>in entrata / in uscita</td>
</tr>
</table>
Abbina il payload del corpo in entrata tramite una `string`, `regexp` o `function` di filtro personalizzata.
Questa regola è piuttosto semplice, quindi per confronti complessi del corpo (ad esempio: validazione rispetto a uno schema JSON) dovresti probabilmente scrivere la tua regola.
**Argomenti**:
- **match** `string|regexp|function` - Contenuto del corpo da confrontare
- **limit** `string` - Opzionale. Limite del corpo in dimensione umana. Es: `5mb`
- **encoding** `string` - Codifica del corpo. Predefinita a `utf8`
- **length** `number` - Lunghezza del corpo. Predefinita presa dall'intestazione `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)
| Nome | responseBody |
| Fase di avvelenamento | outgoing |
Corrispondi al payload del corpo in uscita tramite una stringa, una regexp o una funzione di filtro personalizzata.
Argomenti:
string|regexp|function - Contenuto del corpo da abbinarestring - Codifica del corpo. Predefinito a utf8number - Lunghezza del corpo. Predefinita presa dall'intestazione `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)
#### Stato della risposta
<table>
<tr>
<td><b>Nome</b></td><td>responseStatus</td>
</tr>
<tr>
<td><b>Fase del veleno</b></td><td>outgoing</td>
</tr>
</table>
Valuta lo stato della risposta dal server di destinazione.
Applicabile solo a veleni in uscita.
**Argomenti**:
- **range** `array` - Coppia di intervallo di codici di stato da confrontare. Predefinito `[200, 300]`.
- **lower** `number` - Confronta lo stato come operazione `minore di`. Predefinito `null`.
- **higher** `number` - Confronta lo stato come operazione `maggiore di`. Predefinito `null`.
- **value** `number` - Codice di stato da confrontare usando un'uguaglianza stretta. Predefinito `null`.
- **include** `array` - Elenco non ordinato di codici di stato da confrontare. Utile per specificare uno stato personalizzato. Predefinito `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] }))
Elenco delle regole di terze parti disponibili fornite dalla comunità. Le PR sono benvenute.
Le regole sono semplici funzioni middleware che risolvono in modo asincrono con un valore boolean per determinare se una determinata transazione HTTP dovrebbe essere ignorata durante l'avvelenamento.
La tua regola deve risolversi con un parametro boolean chiamando la funzione next(err, shouldIgnore) nel middleware, passando un valore true se la regola non ha corrispondenze e non deve applicare l'avvelenamento, e quindi continuare con il successivo stack middleware.
Ecco un esempio di una regola semplice che corrisponde al metodo HTTP per determinare se:```js var toxy = require('toxy')
function customMethodRule(matchMethod) { /**
var proxy = toxy()
// Register and enable the rule proxy .get('/foo') .rule(customMethodRule('GET')) .poison(/* ... */)
Puoi eventualmente estendere le regole integrate con le tue regole:```js
toxy.addRule(customMethodRule)
// Then you can use it as a built-in poison
proxy
.get('/foo')
.rules(toxy.rules.customMethodRule)
Per esempi reali in primo piano, dai un'occhiata all'implementazione delle regole integrate
L'API di toxy è completamente costruita sopra l'API di rocky. In altre parole, puoi utilizzare qualsiasi metodo, funzionalità e livello middleware nativamente fornito da rocky.
Crea un nuovo proxy toxy.
Per le options supportate, consulta la documentazione di 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... ])
Return: `ToxyRoute`
Registra una nuova route per il metodo `GET`.
#### toxy#post(path, [ middleware... ])
Return: `ToxyRoute`
Registra una nuova route per il metodo `POST`.
#### toxy#put(path, [ middleware... ])
Return: `ToxyRoute`
Registra una nuova route per il metodo `PUT`.
#### toxy#patch(path, [ middleware... ])
Return: `ToxyRoute`
#### toxy#delete(path, [ middleware... ])
Return: `ToxyRoute`
Registra una nuova route per il metodo `DELETE`.
#### toxy#head(path, [ middleware... ])
Return: `ToxyRoute`
Registra una nuova route per il metodo `HEAD`.
#### toxy#all(path, [ middleware... ])
Return: `ToxyRoute`
Registra una nuova route per qualsiasi metodo.
#### toxy#poisons `=>` Object
Espone una mappa con i poison integrati. Alias di prototipo per `toxy.poisons`
#### toxy#rules `=>` Object
Espone una mappa con i poison integrati. Alias di prototipo per `toxy.rules`
#### toxy#forward(url)
Definisce un URL per inoltrare il traffico in entrata ricevuto dal proxy.
#### toxy#balance(urls)
Inoltra a più server bilanciando tra di essi.
Per maggiori informazioni, consulta i [rocky docs](https://github.com/h2non/rocky#programmatic-api)
#### toxy#replay(url)
Definisce un nuovo server di replay.
Puoi chiamare questo metodo più volte per definire più server di replay.
Per maggiori informazioni, consulta i [rocky docs](https://github.com/h2non/rocky#programmatic-api)
#### toxy#use(middleware)
Inserisce un middleware personalizzato.
Per maggiori informazioni, consulta i [rocky docs](https://github.com/h2non/rocky#middleware-layer).
#### toxy#useResponse(middleware)
Inserisce un middleware per il traffico in uscita delle risposte.
Per maggiori informazioni, consulta i [rocky docs](https://github.com/h2non/rocky#middleware-layer).
#### toxy#useReplay(middleware)
Inserisce un middleware per il traffico di replay.
Per maggiori informazioni, consulta i [rocky docs](https://github.com/h2non/rocky#middleware-layer)
#### toxy#requestBody(middleware)
Intercetta il corpo della richiesta in entrata. Utile per modificarlo al volo.
Per maggiori informazioni, consulta i [rocky docs](https://github.com/h2non/rocky#programmatic-api)
#### toxy#responseBody(middleware)
Intercetta il corpo della risposta in uscita. Utile per modificarlo al volo.
Per maggiori informazioni, consulta i [rocky docs](https://github.com/h2non/rocky#programmatic-api)
#### toxy#middleware()
Restituisce un middleware standard da usare con connect/express.
#### toxy#host(host)
Sovrascrive l'intestazione `Host` con un valore personalizzato. Simile all'opzione `forwardHost`.
#### toxy#redirect(url)
Reindirizza il traffico all'URL specificato.
#### toxy#findRoute(routeIdOrPath, [ method ])
Trova una route per ID o percorso e metodo.
#### toxy#listen(port)
Avvia il server HTTP integrato, in ascolto su una porta TCP specifica.
#### toxy#close([ callback ])
Chiude il server HTTP.
#### toxy#poison(poison)
Alias: `usePoison`, `useIncomingPoison`
Registra un nuovo poison per infettare il traffico [in entrata](#poisoning-phases).
#### toxy#outgoingPoison(poison)
Alias: `useOutgoingPoison`, `responsePoison`
Registra un nuovo poison per infettare il traffico [in uscita](#poisoning-phases).
#### toxy#rule(rule)
Alias: `useRule`
Registra una nuova regola.
#### toxy#withRule(rule)
Aliases: `ifRule`, `whenRule`, `poisonRule`, `poisonFilter`
Applica una nuova regola per l'ultimo poison registrato.
#### toxy#enable(poison)
Abilita un poison tramite identificatore del nome.
#### toxy#disable(poison)
Disabilita un poison tramite identificatore del nome.
#### toxy#remove(poison)
Return: `boolean`
Rimuove un poison per traffico in entrata tramite identificatore del nome o riferimento all'oggetto.
#### toxy#removeOutgoing(poison)
Return: `boolean`
Rimuove un poison per traffico in uscita tramite identificatore del nome o riferimento all'oggetto.
#### toxy#isEnabled(poison)
Return: `boolean`
Verifica se un poison è abilitato tramite identificatore del nome.
#### toxy#disableAll()
Alias: `disablePoisons`
Disabilita tutti i poison registrati.
#### toxy#getPoison(name)
Return: `Directive|null`
Cerca e recupera un poison registrato nello stack tramite identificatore del nome.
#### toxy#getIncomingPoison(name)
Return: `Directive|null`
Cerca e recupera un poison `incoming` registrato nello stack tramite identificatore del nome.
#### toxy#getOutgoingPoison(name)
Return: `Directive|null`
Cerca e recupera un poison `outgoing` registrato nello stack tramite identificatore del nome.
#### toxy#getPoisons()
Return: `array<Directive>`
Restituisce un array dei poison registrati.
#### toxy#getIncomingPoisons()
Return: `array<Directive>`
Restituisce un array dei poison `incoming` registrati.
#### toxy#getOutgoingPoisons()
Return: `array<Directive>`
Restituisce un array dei poison `outgoing` registrati.
#### toxy#flush()
Alias: `flushPoisons`
Rimuove tutti i poison registrati per i flussi di traffico in entrata e in uscita.
#### toxy#enableRule(rule)
Abilita una regola tramite identificatore del nome.
#### toxy#disableRule(rule)
Disabilita una regola tramite identificatore del nome.
#### toxy#removeRule(rule)
Return: `boolean`
Rimuove una regola tramite identificatore del nome.
#### toxy#disableRules()
Disabilita tutte le regole registrate.
#### toxy#isRuleEnabled(rule)
Return: `boolean`
Verifica se la regola specificata è abilitata tramite identificatore del nome.
#### toxy#getRule(rule)
Return: `Directive|null`
Cerca e recupera una regola registrata nello stack tramite identificatore del nome.
#### toxy#getRules()
Return: `array<Directive>`
Restituisce un array con le regole registrate incapsulate come `Directive`.
#### toxy#flushRules()
Rimuove tutte le regole.
### toxy.addPoison(name, fn)
Estende i poison integrati.
### toxy.addRule(name, fn)
Estende le regole integrate.
### toxy.poisons `=>` Object
Espone una mappa con i poison integrati.
### toxy.rules `=>` Object
Espone una mappa con le regole integrate.
### toxy.VERSION `=>` String
Versione semantica corrente di toxy.
### ToxyRoute
`ToxyRoute` espone la stessa interfaccia dell'interfaccia globale `Toxy`, aggiunge solo alcuni [metodi aggiuntivi](https://github.com/h2non/rocky#routepath) a livello di route.
Ulteriori azioni eseguite sull'API `ToxyRoute` saranno applicabili solo a livello di route (annidato). In altre parole: conosci già l'API.
Questo esempio chiarirà probabilmente eventuali dubbi:```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'))
Un comodo wrapper utilizzato internamente per poison e regole.
Normalmente non è necessario conoscere questa interfaccia, ma per scopi di hacking o azioni di basso livello potrebbe essere utile.
Ritorno: boolean
Ritorno: boolean
Ritorno: boolean
Alias: filter
Ritorno: function(req, res, next)
L'API HTTP di toxy segue le convenzioni JSON API, inclusi i collegamenti ipertestuali basati sulle risorse.
Per un caso d'uso completo, vedere l'esempio del server di amministrazione.```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)
Per maggiori dettagli sull'API programmatica di amministrazione, consulta [sotto](#programmatic-api-1).
### Autorizzazione
L'API HTTP può essere protetta da client non autorizzati.
I client autorizzati devono definire il token della chiave API tramite gli header HTTP `API-Key` o `Authorization`.
Per abilitarla, è sufficiente passare le seguenti opzioni al server di amministrazione `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)
Gerarchia:
toxy gestite
Accetta: application/json
Esempio di payload:```js { "name": "method", "options": "GET" }
#### DELETE /servers/:id/rules
#### GET /servers/:id/rules/:id
#### DELETE /servers/:id/rules/:id
### Avvelenamenti
#### GET /servers/:id/poison
#### POST /servers/:id/poisons
Accetta: `application/json`
Payload di esempio:```js
{
"name": "latency",
"phase": "outgoing",
"options": { "jitter": 1000 }
}
Accetta: application/json
Payload di esempio:```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
### Rotte
#### GET /servers/:id/routes
#### POST /servers/:id/routes
Accetta: `application/json`
Esempio di payload:```js
{
"path": "/foo", // Required
"method": "GET", // use ALL for all the methods
"forward": "http://my.server", // Optional custom forward server URL
}
Accetta: application/json
Esempio di payload:```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
### Veleni di route
#### GET /servers/:id/routes/:id/poisons
#### POST /servers/:id/routes/:id/poisons
Accetta: `application/json`
Esempio di payload:```js
{
"name": "latency",
"phase": "outgoing",
"options": { "jitter": 1000 }
}
Accetta: application/json
Esempio di payload:```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 programmatica
Il server amministrativo HTTP integrato fornisce anche un'interfaccia semplice aperta a scopi di estensibilità e hacking.
Ad esempio, è possibile aggiungere middleware aggiuntivo al server amministrativo o registrare nuove rotte.
#### toxy.admin([ opts ])
Returns: `Admin`
**Opzioni supportate**:
- **apiKey** `string` - Chiave API opzionale per proteggere il server
- **port** `number` - Opzionale. Porta TCP su cui ascoltare
- **cors** `boolean` - Abilita CORS per l'accesso dal browser web
- **middleware** `array<function>` - Aggiungi middleware aggiuntivo
- **ssl** `object` - Server HTTPS Node.js [Opzioni TLS](https://nodejs.org/api/tls.html#tls_tls_createserver_options_secureconnectionlistener).
##### Admin#listen([ port, host ])
Avvia l'ascolto sulla rete.
##### Admin#manage(toxy)
Gestisci un'istanza del server `toxy`.
##### Admin#find(toxy)
Trova un'istanza toxy. Accetta l'ID del server toxy o l'istanza toxy.
##### Admin#remove(toxy)
Interrompi la gestione di un'istanza toxy.
##### Admin#use(...middleware)
Registra un middleware.
##### Admin#param(...middleware)
Registra un middleware per parametri.
##### Admin#get(path, [ ...middleware ])
Registra una rotta GET.
##### Admin#post(path, [ ...middleware ])
Registra una rotta POST.
##### Admin#put(path, [ ...middleware ])
Registra una rotta PUT.
##### Admin#delete(path, [ ...middleware ])
Registra una rotta DELETE.
##### Admin#patch(path, [ ...middleware ])
Registra una rotta PATCH.
##### Admin#all(path, [ ...middleware ])
Registra una rotta che accetta qualsiasi metodo HTTP.
##### Admin#middleware(req, res, next)
Middleware da aggiungere con connect/express.
##### Admin#close(cb)
Ferma il server.
## License
MIT - Tomas Aparicio
[](https://sourcegraph.com/github.com/h2non/toxy)