# Inoltrare richieste a un altro server

> Usa PROXY() per associare un prefisso di URL a un server a monte, scegli come viene copiato il percorso e $.proxy() per inoltrare una singola rotta.

Framework: total5
Product: Total.js 5 (total5@0.0.19)
Language: it
Content-SHA256: 5f30d1b757ce588c5449429a9038beaac940b97a9201d33658802984632a1d1e
Snapshot: c0700e321579725c5cf4f5ace1ad7d2866d1b4f93c24a63c0b41b6b7998e976c
Sources: total5-installed@total5@0.0.19
Review: not-recorded

`PROXY(prefix, target)` inoltra a un altro server ogni richiesta sotto un prefisso di URL e restituisce la risposta in streaming, così un'applicazione Total.js può stare davanti a più servizi. Viene eseguito prima delle rotte, quindi un prefisso gestito da `PROXY()` non raggiunge mai `ROUTE()`. La richiesta viene passata con il suo metodo, gli header e il corpo; gli header `x-forwarded-for`, `x-forwarded-url` e `x-forwarded-host` informano il server a monte della richiesta originale. `PROXY(prefix)` senza destinazione rimuove il proxy.

L'oggetto che restituisce configura il proxy: `.copy(type)` sceglie quale parte del percorso viene inviata a monte (vedi sotto), `.timeout(ms)` limita l'attesa, `.check(fn)` fa sì che il proxy si applichi solo quando `fn(ctrl)` restituisce true e `.before(uri, ctrl)` può modificare la richiesta in uscita, ad esempio per aggiungere un header.

`.copy()` accetta `none` (predefinito), `extend` o `replace`. Con **`none`** il server a monte riceve solo il percorso della destinazione più la query string: `/none/a/b/?q=1` diventa `/base/?q=1` per la destinazione `http://host/base/`. Con **`extend`** il resto del percorso della richiesta viene aggiunto al percorso della destinazione: `/extend/a/b/?q=1` diventa `/base/a/b/?q=1`, che è ciò che vuoi per un gateway. `replace` si comporta come `extend` quando la destinazione ha un percorso proprio; quando la destinazione è solo un host invia il resto del percorso **senza la query string**, quindi preferisci `extend`.

Per una singola rotta usa `$.proxy(url)`: invia la richiesta corrente (metodo, query string, corpo e header) a `url` e restituisce la risposta del server a monte con il suo codice di stato.

```js controllers/proxy.js
const Http = require('http');

// A small upstream server that reports what it received
Http.createServer(function(req, res) {
	res.writeHead(200, { 'content-type': 'application/json' });
	res.end(JSON.stringify({ method: req.method, url: req.url, token: req.headers['x-token'] || null, forwarded: !!req.headers['x-forwarded-url'] }));
}).listen(9411, '127.0.0.1');

// One proxy per copy mode, to see the difference (the target has the path /base/)
PROXY('/none/', 'http://127.0.0.1:9411/base/');
PROXY('/extend/', 'http://127.0.0.1:9411/base/').copy('extend');
PROXY('/plain/', 'http://127.0.0.1:9411/base/').copy('replace');

// Everything below /service/ goes to the upstream, and a header is added on the way
PROXY('/service/', 'http://127.0.0.1:9411/').copy('extend').before(function(uri, ctrl) {
	uri.headers['x-token'] = 'secret';
});

exports.install = function() {
	ROUTE('GET /single/', single);
};

function single($) {
	$.proxy('http://127.0.0.1:9411/from-route/');
}
```
