# Reenvía peticiones a otro servidor

> Usa PROXY() para asignar un prefijo de URL a un servidor de destino, elige cómo se copia la ruta y usa $.proxy() para reenviar una sola ruta.

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

`PROXY(prefix, target)` reenvía a otro servidor todas las peticiones bajo un prefijo de URL y devuelve la respuesta en streaming, de modo que una aplicación Total.js puede situarse delante de varios servicios. Se ejecuta antes que las rutas, así que un prefijo gestionado por `PROXY()` nunca llega a `ROUTE()`. La petición se transmite con su método, cabeceras y cuerpo; las cabeceras `x-forwarded-for`, `x-forwarded-url` y `x-forwarded-host` informan al destino de la petición original. `PROXY(prefix)` sin destino elimina el proxy.

El objeto que devuelve configura el proxy: `.copy(type)` elige qué parte de la ruta se envía al destino (ver abajo), `.timeout(ms)` limita la espera, `.check(fn)` hace que el proxy solo se aplique cuando `fn(ctrl)` devuelve true y `.before(uri, ctrl)` puede modificar la petición saliente, por ejemplo para añadir una cabecera.

`.copy()` admite `none` (el valor por defecto), `extend` o `replace`. Con **`none`** el destino solo recibe la ruta del destino más la query string: `/none/a/b/?q=1` se convierte en `/base/?q=1` para el destino `http://host/base/`. Con **`extend`** el resto de la ruta de la petición se añade a la ruta del destino: `/extend/a/b/?q=1` se convierte en `/base/a/b/?q=1`, que es lo que quieres para una pasarela. `replace` se comporta como `extend` cuando el destino tiene ruta propia; cuando el destino es solo un host envía el resto de la ruta **sin la query string**, así que es preferible `extend`.

Para una sola ruta usa `$.proxy(url)`: envía la petición actual (método, query string, cuerpo y cabeceras) a `url` y devuelve la respuesta del destino con su código de estado.

```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/');
}
```
