node-http-proxy
é uma biblioteca de proxy programável HTTP que oferece suporte a websockets. É adequado para implementar componentes como proxies reversos e balanceadores de carga.
npm install http-proxy --save
Voltar ao topo
Clique aqui
Voltar ao topo
Um novo proxy é criado chamando createProxyServer
e passando um objeto options
como argumento (propriedades válidas estão disponíveis aqui)
var httpProxy = require ( 'http-proxy' ) ;
var proxy = httpProxy . createProxyServer ( options ) ; // See (†)
†A menos que listen(..) seja invocado no objeto, isso não cria um servidor web. Veja abaixo.
Um objeto será retornado com quatro métodos:
req, res, [options]
(usado para proxy de solicitações HTTP(S) regulares)req, socket, head, [options]
(usado para proxy de solicitações WS(S))port
de escuta (uma função que agrupa o objeto em um servidor web, para sua conveniência)[callback]
(uma função que fecha o servidor web interno e para de escutar em determinada porta)É então possível fazer proxy de solicitações chamando essas funções
http . createServer ( function ( req , res ) {
proxy . web ( req , res , { target : 'http://mytarget.com:8080' } ) ;
} ) ;
Os erros podem ser ouvidos usando a API Event Emitter
proxy . on ( 'error' , function ( e ) {
...
} ) ;
ou usando a API de retorno de chamada
proxy . web ( req , res , { target : 'http://mytarget.com:8080' } , function ( e ) { ... } ) ;
Quando uma solicitação é proxy, ela segue dois pipelines diferentes (disponíveis aqui) que aplicam transformações ao objeto req
e res
. O primeiro pipeline (de entrada) é responsável pela criação e manipulação do fluxo que conecta seu cliente ao destino. O segundo pipeline (de saída) é responsável pela criação e manipulação do fluxo que, do seu alvo, retorna os dados ao cliente.
Voltar ao topo
var http = require ( 'http' ) ,
httpProxy = require ( 'http-proxy' ) ;
//
// Create your proxy server and set the target in the options.
//
httpProxy . createProxyServer ( { target : 'http://localhost:9000' } ) . listen ( 8000 ) ; // See (†)
//
// Create your target server
//
http . createServer ( function ( req , res ) {
res . writeHead ( 200 , { 'Content-Type' : 'text/plain' } ) ;
res . write ( 'request successfully proxied!' + 'n' + JSON . stringify ( req . headers , true , 2 ) ) ;
res . end ( ) ;
} ) . listen ( 9000 ) ;
†Invocar listen(..) aciona a criação de um servidor web. Caso contrário, apenas a instância do proxy será criada.
Voltar ao topo
Este exemplo mostra como você pode fazer proxy de uma solicitação usando seu próprio servidor HTTP e também pode colocar sua própria lógica para lidar com a solicitação.
var http = require ( 'http' ) ,
httpProxy = require ( 'http-proxy' ) ;
//
// Create a proxy server with custom application logic
//
var proxy = httpProxy . createProxyServer ( { } ) ;
//
// Create your custom server and just call `proxy.web()` to proxy
// a web request to the target passed in the options
// also you can use `proxy.ws()` to proxy a websockets request
//
var server = http . createServer ( function ( req , res ) {
// You can define here your custom logic to handle the request
// and then proxy the request.
proxy . web ( req , res , { target : 'http://127.0.0.1:5050' } ) ;
} ) ;
console . log ( "listening on port 5050" )
server . listen ( 5050 ) ;
Voltar ao topo
Este exemplo mostra como você pode fazer proxy de uma solicitação usando seu próprio servidor HTTP que modifica a solicitação de proxy de saída adicionando um cabeçalho especial.
var http = require ( 'http' ) ,
httpProxy = require ( 'http-proxy' ) ;
//
// Create a proxy server with custom application logic
//
var proxy = httpProxy . createProxyServer ( { } ) ;
// To modify the proxy connection before data is sent, you can listen
// for the 'proxyReq' event. When the event is fired, you will receive
// the following arguments:
// (http.ClientRequest proxyReq, http.IncomingMessage req,
// http.ServerResponse res, Object options). This mechanism is useful when
// you need to modify the proxy request before the proxy connection
// is made to the target.
//
proxy . on ( 'proxyReq' , function ( proxyReq , req , res , options ) {
proxyReq . setHeader ( 'X-Special-Proxy-Header' , 'foobar' ) ;
} ) ;
var server = http . createServer ( function ( req , res ) {
// You can define here your custom logic to handle the request
// and then proxy the request.
proxy . web ( req , res , {
target : 'http://127.0.0.1:5050'
} ) ;
} ) ;
console . log ( "listening on port 5050" )
server . listen ( 5050 ) ;
Voltar ao topo
Às vezes, quando você recebe um documento HTML/XML do servidor de origem, você deseja modificá-lo antes de encaminhá-lo.
Harmon permite que você faça isso em um estilo de streaming para manter a pressão sobre o proxy ao mínimo.
Voltar ao topo
var http = require ( 'http' ) ,
httpProxy = require ( 'http-proxy' ) ;
//
// Create a proxy server with latency
//
var proxy = httpProxy . createProxyServer ( ) ;
//
// Create your server that makes an operation that waits a while
// and then proxies the request
//
http . createServer ( function ( req , res ) {
// This simulates an operation that takes 500ms to execute
setTimeout ( function ( ) {
proxy . web ( req , res , {
target : 'http://localhost:9008'
} ) ;
} , 500 ) ;
} ) . listen ( 8008 ) ;
//
// Create your target server
//
http . createServer ( function ( req , res ) {
res . writeHead ( 200 , { 'Content-Type' : 'text/plain' } ) ;
res . write ( 'request successfully proxied to: ' + req . url + 'n' + JSON . stringify ( req . headers , true , 2 ) ) ;
res . end ( ) ;
} ) . listen ( 9008 ) ;
Voltar ao topo
Você pode ativar a validação de um certificado SSL seguro para a conexão de destino (evite certificados autoassinados), basta definir secure: true
nas opções.
//
// Create the HTTPS proxy server in front of a HTTP server
//
httpProxy . createServer ( {
target : {
host : 'localhost' ,
port : 9009
} ,
ssl : {
key : fs . readFileSync ( 'valid-ssl-key.pem' , 'utf8' ) ,
cert : fs . readFileSync ( 'valid-ssl-cert.pem' , 'utf8' )
}
} ) . listen ( 8009 ) ;
//
// Create the proxy server listening on port 443
//
httpProxy . createServer ( {
ssl : {
key : fs . readFileSync ( 'valid-ssl-key.pem' , 'utf8' ) ,
cert : fs . readFileSync ( 'valid-ssl-cert.pem' , 'utf8' )
} ,
target : 'https://localhost:9010' ,
secure : true // Depends on your needs, could be false.
} ) . listen ( 443 ) ;
//
// Create an HTTP proxy server with an HTTPS target
//
httpProxy . createProxyServer ( {
target : {
protocol : 'https:' ,
host : 'my-domain-name' ,
port : 443 ,
pfx : fs . readFileSync ( 'path/to/certificate.p12' ) ,
passphrase : 'password' ,
} ,
changeOrigin : true ,
} ) . listen ( 8000 ) ;
Voltar ao topo
Você pode ativar o suporte de websocket para o proxy usando ws:true
nas opções.
//
// Create a proxy server for websockets
//
httpProxy . createServer ( {
target : 'ws://localhost:9014' ,
ws : true
} ) . listen ( 8014 ) ;
Além disso, você pode fazer proxy das solicitações do websocket apenas chamando o método ws(req, socket, head)
.
//
// Setup our server to proxy standard HTTP requests
//
var proxy = new httpProxy . createProxyServer ( {
target : {
host : 'localhost' ,
port : 9015
}
} ) ;
var proxyServer = http . createServer ( function ( req , res ) {
proxy . web ( req , res ) ;
} ) ;
//
// Listen to the `upgrade` event and proxy the
// WebSocket requests as well.
//
proxyServer . on ( 'upgrade' , function ( req , socket , head ) {
proxy . ws ( req , socket , head ) ;
} ) ;
proxyServer . listen ( 8015 ) ;
Voltar ao topo
httpProxy.createProxyServer
oferece suporte às seguintes opções:
target : string de url a ser analisada com o módulo url
forward : string de url a ser analisada com o módulo url
agente : objeto a ser passado para http(s).request (veja o agente https do Node e os objetos do agente http)
ssl : objeto a ser passado para https.createServer()
ws : verdadeiro/falso, se você deseja fazer proxy de websockets
xfwd : verdadeiro/falso, adiciona cabeçalhos x-forward
seguro : verdadeiro/falso, se você deseja verificar os certificados SSL
toProxy : verdadeiro/falso, passa a URL absoluta como path
(útil para proxy para proxies)
prependPath : verdadeiro/falso, Padrão: verdadeiro - especifique se deseja anexar o caminho do destino ao caminho do proxy
ignorePath : verdadeiro/falso, Padrão: falso - especifique se deseja ignorar o caminho do proxy da solicitação recebida (nota: você terá que anexar / manualmente, se necessário).
localAddress : string de interface local para vincular conexões de saída
changeOrigin : verdadeiro/falso, Padrão: falso - altera a origem do cabeçalho do host para o URL de destino
preserveHeaderKeyCase : verdadeiro/falso, Padrão: falso - especifique se deseja manter letras maiúsculas e minúsculas da chave do cabeçalho de resposta
auth : Autenticação básica, ou seja, 'user:password' para calcular um cabeçalho de autorização.
hostRewrite : reescreve o nome do host do local nos redirecionamentos (201/301/302/307/308).
autoRewrite : reescreve o host/porta de localização em redirecionamentos (201/301/302/307/308) com base no host/porta solicitado. Padrão: falso.
protocolRewrite : reescreve o protocolo de localização em (201/301/302/307/308) redireciona para 'http' ou 'https'. Padrão: nulo.
cookieDomainRewrite : reescreve o domínio dos cabeçalhos set-cookie
. Valores possíveis:
false
(padrão): desabilita a reescrita de cookiescookieDomainRewrite: "new.domain"
. Para remover o domínio, use cookieDomainRewrite: ""
."*"
para corresponder a todos os domínios. Por exemplo, mantenha um domínio inalterado, reescreva um domínio e remova outros domínios: cookieDomainRewrite: {
"unchanged.domain": "unchanged.domain",
"old.domain": "new.domain",
"*": ""
}
cookiePathRewrite : reescreve o caminho dos cabeçalhos set-cookie
. Valores possíveis:
false
(padrão): desabilita a reescrita de cookiescookiePathRewrite: "/newPath/"
. Para remover o caminho, use cookiePathRewrite: ""
. Para definir o caminho para root, use cookiePathRewrite: "/"
."*"
para corresponder a todos os caminhos. Por exemplo, para manter um caminho inalterado, reescreva um caminho e remova outros caminhos: cookiePathRewrite: {
"/unchanged.path/": "/unchanged.path/",
"/old.path/": "/new.path/",
"*": ""
}
headers : objeto com cabeçalhos extras a serem adicionados às solicitações de destino.
proxyTimeout : tempo limite (em milissegundos) para solicitações de proxy de saída
timeout : tempo limite (em milissegundos) para solicitações recebidas
followRedirects : verdadeiro/falso, Padrão: falso - especifique se deseja seguir redirecionamentos
selfHandleResponse verdadeiro/falso, se definido como verdadeiro, nenhum dos passes webOutgoing será chamado e é sua responsabilidade retornar adequadamente a resposta ouvindo e agindo no evento proxyRes
buffer : fluxo de dados a ser enviado como corpo da solicitação. Talvez você tenha algum middleware que consuma o fluxo de solicitação antes de fazer proxy, por exemplo, se você ler o corpo de uma solicitação em um campo chamado 'req.rawbody', poderá transmitir novamente esse campo na opção de buffer:
'use strict';
const streamify = require('stream-array');
const HttpProxy = require('http-proxy');
const proxy = new HttpProxy();
module.exports = (req, res, next) => {
proxy.web(req, res, {
target: 'http://localhost:4003/',
buffer: streamify(req.rawBody)
}, next);
};
NOTA: options.ws
e options.ssl
são opcionais. options.target
e options.forward
não podem estar faltando
Se você estiver usando o método proxyServer.listen
, as seguintes opções também serão aplicáveis:
Voltar ao topo
error
: O evento de erro é emitido se a solicitação ao destino falhar. Não fazemos nenhum tratamento de erros de mensagens passadas entre cliente e proxy, e mensagens passadas entre proxy e destino, por isso é recomendável que você ouça os erros e trate-os.proxyReq
: Este evento é emitido antes dos dados serem enviados. Dá a você a chance de alterar o objeto de solicitação proxyReq. Aplica-se a conexões "web"proxyReqWs
: Este evento é emitido antes dos dados serem enviados. Dá a você a chance de alterar o objeto de solicitação proxyReq. Aplica-se a conexões "websocket"proxyRes
: Este evento é emitido se a solicitação ao destino obtiver uma resposta.open
: este evento é emitido quando o websocket proxy foi criado e canalizado para o websocket de destino.close
: Este evento é emitido quando o websocket do proxy é fechado.proxySocket
: Obsoleto em favor de open
. var httpProxy = require ( 'http-proxy' ) ;
// Error example
//
// Http Proxy Server with bad target
//
var proxy = httpProxy . createServer ( {
target : 'http://localhost:9005'
} ) ;
proxy . listen ( 8005 ) ;
//
// Listen for the `error` event on `proxy`.
proxy . on ( 'error' , function ( err , req , res ) {
res . writeHead ( 500 , {
'Content-Type' : 'text/plain'
} ) ;
res . end ( 'Something went wrong. And we are reporting a custom error message.' ) ;
} ) ;
//
// Listen for the `proxyRes` event on `proxy`.
//
proxy . on ( 'proxyRes' , function ( proxyRes , req , res ) {
console . log ( 'RAW Response from the target' , JSON . stringify ( proxyRes . headers , true , 2 ) ) ;
} ) ;
//
// Listen for the `open` event on `proxy`.
//
proxy . on ( 'open' , function ( proxySocket ) {
// listen for messages coming FROM the target here
proxySocket . on ( 'data' , hybiParseAndLogMessage ) ;
} ) ;
//
// Listen for the `close` event on `proxy`.
//
proxy . on ( 'close' , function ( res , socket , head ) {
// view disconnected websocket connections
console . log ( 'Client disconnected' ) ;
} ) ;
Voltar ao topo
var proxy = new httpProxy . createProxyServer ( {
target : {
host : 'localhost' ,
port : 1337
}
} ) ;
proxy . close ( ) ;
Voltar ao topo
Se quiser lidar com sua própria resposta após receber proxyRes
, você pode fazer isso com selfHandleResponse
. Como você pode ver abaixo, se usar esta opção, você poderá interceptar e ler o proxyRes
, mas também deve responder ao próprio res
, caso contrário o cliente original nunca receberá nenhum dado.
var option = {
target : target ,
selfHandleResponse : true
} ;
proxy . on ( 'proxyRes' , function ( proxyRes , req , res ) {
var body = [ ] ;
proxyRes . on ( 'data' , function ( chunk ) {
body . push ( chunk ) ;
} ) ;
proxyRes . on ( 'end' , function ( ) {
body = Buffer . concat ( body ) . toString ( ) ;
console . log ( "res from proxied server:" , body ) ;
res . end ( "my response to cli" ) ;
} ) ;
} ) ;
proxy . web ( req , res , option ) ;
Uma API de tabela de proxy está disponível por meio deste módulo complementar, que permite definir um conjunto de regras para traduzir rotas correspondentes em rotas de destino com as quais o proxy reverso se comunicará.
$ npm test
Logotipo criado por Diego Pasquali
Voltar ao topo
master
)Voltar ao topo
A Licença MIT (MIT)
Copyright (c) 2010 - 2016 Charlie Robbins, Jarrett Cruger e os colaboradores.
É concedida permissão, gratuitamente, a qualquer pessoa que obtenha uma cópia deste software e dos arquivos de documentação associados (o "Software"), para negociar o Software sem restrições, incluindo, sem limitação, os direitos de usar, copiar, modificar, mesclar , publicar, distribuir, sublicenciar e/ou vender cópias do Software e permitir que as pessoas a quem o Software seja fornecido o façam, sujeito às seguintes condições:
O aviso de direitos autorais acima e este aviso de permissão serão incluídos em todas as cópias ou partes substanciais do Software.
O SOFTWARE É FORNECIDO "COMO ESTÁ", SEM GARANTIA DE QUALQUER TIPO, EXPRESSA OU IMPLÍCITA, INCLUINDO, MAS NÃO SE LIMITANDO ÀS GARANTIAS DE COMERCIALIZAÇÃO, ADEQUAÇÃO A UM DETERMINADO FIM E NÃO VIOLAÇÃO. EM HIPÓTESE ALGUMA OS AUTORES OU DETENTORES DE DIREITOS AUTORAIS SERÃO RESPONSÁVEIS POR QUALQUER RECLAMAÇÃO, DANOS OU OUTRA RESPONSABILIDADE, SEJA EM UMA AÇÃO DE CONTRATO, ATO ILÍCITO OU DE OUTRA FORMA, DECORRENTE DE, OU EM CONEXÃO COM O SOFTWARE OU O USO OU OUTRAS NEGOCIAÇÕES NO SOFTWARE.