Skip to content

Instantly share code, notes, and snippets.

@alanhoff
Created May 13, 2015 19:43
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alanhoff/7f7e2e34f3f4db592aec to your computer and use it in GitHub Desktop.
Save alanhoff/7f7e2e34f3f4db592aec to your computer and use it in GitHub Desktop.
Proxy que valida os dados
var httpProxy = require('http-proxy');
var proxy = httpProxy.createProxyServer();
var http = require('http');
var Mock = require('mock-req');
var Busboy = require('busboy');
var config = {
url: '/teste', // A rota a ser protegida
method: 'POST', // O método a ser protegido
content: 'multipart/form-data', // O tipo de conteúdo
maxBody: 48000, // O tamanho máximo da requisição em bytes
target: 'http://localhost:8080',
field: {
name: 'hello', // Nome do campo não permitido
value: 'world', // Valor do campo não permitido
}
};
http.createServer(function(req, res) {
// Repassamos tododas as requisições que não queremos filtrar
if (req.url !== config.url ||
req.method !== config.method ||
req.headers['content-type'].indexOf(config.content) !== 0) {
return proxy.web(req, res, {
target: config.target
});
}
// Iniciamos um buffer para alocar a memória e escrever
// mais rápido os dados da requisição
var data = new Buffer(config.maxBody);
var cursor = 0;
var safe = true;
// Iniciamos o nosso parser assíncrono
var busboy = new Busboy({
headers: req.headers
});
// Precisamos guardar para mais tarde fazer o reply da requisição
req.on('data', function(buff) {
// Precisamos garantir que não tentaram derrubar o proxy
if ((buff.length + cursor) > data.length) {
safe = false;
req.pause();
res.statusCode = 413;
return res.end('Request Entity Too Large');
}
buff.copy(data, cursor);
cursor += buff.length;
});
// Analisamos todos os fields recebidos pelo busboy. Esta
// parte é o centro da validação, altere aqui seu método
busboy.on('field', function(name, value) {
// Se o campo não for importante, não fazemos nada
if (name !== config.field.name || value !== config.field.value)
return;
// Campo maligno encontrado
req.pause();
res.statusCode = 400;
res.end('Bad request');
safe = false;
});
// A requisição terminou, hora de fazer o proxy
busboy.on('finish', function() {
// Verificamos se ela é segura
if (!safe)
return;
// Criamos uma requisição falsa, pois a anterior já foi consumida
var mock = new Mock({
method: req.method,
url: req.url,
headers: req.headers
});
// Pedimos ao http-proxy que encaminhe a requisição
proxy.web(mock, res, {
target: config.target
});
// Enviamos o corpo da mensagem para a fila da stream e marcamos
// a mesma como encerrada
mock.write(data.slice(0, cursor));
mock.end();
});
// Enviamos os dados recebidos para o busboy também
req.pipe(busboy);
}).listen(8081);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment