J'essaie de créer un serveur proxy pour passer HTTP GET
demandes d’un client à un site Web tiers (par exemple Google). Mon mandataire doit simplement mettre en miroir les demandes entrantes dans le chemin correspondant sur le site cible. Par conséquent, si l'URL demandée par mon client est:
127.0.0.1/images/srpr/logo11w.png
la ressource suivante devrait être servie:
http://www.google.com/images/srpr/logo11w.png
voici ce que je suis venu avec:
http.createServer(onRequest).listen(80);
function onRequest (client_req, client_res) {
client_req.addListener("end", function() {
var options = {
hostname: 'www.google.com',
port: 80,
path: client_req.url,
method: client_req.method
headers: client_req.headers
};
var req=http.request(options, function(res) {
var body;
res.on('data', function (chunk) {
body += chunk;
});
res.on('end', function () {
client_res.writeHead(res.statusCode, res.headers);
client_res.end(body);
});
});
req.end();
});
}
cela fonctionne bien avec les pages html, mais pour les autres types de fichiers, il ne renvoie qu'une page vierge ou un message d'erreur du site cible (qui varie selon les sites).
Je ne pense pas que ce soit une bonne idée de traiter les réponses reçues du serveur tiers. Cela ne fera qu'augmenter l'encombrement de la mémoire de votre serveur proxy. De plus, c'est la raison pour laquelle votre code ne fonctionne pas.
Essayez plutôt de transmettre la réponse au client. Pensez à l'extrait suivant:
var http = require('http');
http.createServer(onRequest).listen(3000);
function onRequest(client_req, client_res) {
console.log('serve: ' + client_req.url);
var options = {
hostname: 'www.google.com',
port: 80,
path: client_req.url,
method: client_req.method,
headers: client_req.headers
};
var proxy = http.request(options, function (res) {
client_res.writeHead(res.statusCode, res.headers)
res.pipe(client_res, {
end: true
});
});
client_req.pipe(proxy, {
end: true
});
}
Voici une implémentation utilisant node-http-proxy
de nodejitsu.
var http = require('http');
var httpProxy = require('http-proxy');
var proxy = httpProxy.createProxyServer({});
http.createServer(function(req, res) {
proxy.web(req, res, { target: 'http://www.google.com' });
}).listen(3000);
Voici un serveur proxy utilisant request qui gère les redirections. Utilisez-le en tapant votre URL de proxy http://domain.com:3000/?url= [your_url]
var http = require('http');
var url = require('url');
var request = require('request');
http.createServer(onRequest).listen(3000);
function onRequest(req, res) {
var queryData = url.parse(req.url, true).query;
if (queryData.url) {
request({
url: queryData.url
}).on('error', function(e) {
res.end(e);
}).pipe(res);
}
else {
res.end("no url found");
}
}
Votre code ne fonctionne pas pour les fichiers binaires car ils ne peuvent pas être convertis en chaînes dans le gestionnaire d'événements de données. Si vous avez besoin de manipuler des fichiers binaires, vous devez utiliser un tampon . Désolé, je n'ai pas d'exemple d'utilisation de tampon car, dans mon cas, je devais manipuler des fichiers HTML. Je vérifie simplement le type de contenu, puis pour les fichiers texte/html, mettez-les à jour si nécessaire:
app.get('/*', function(clientRequest, clientResponse) {
var options = {
hostname: 'google.com',
port: 80,
path: clientRequest.url,
method: 'GET'
};
var googleRequest = http.request(options, function(googleResponse) {
var body = '';
if (String(googleResponse.headers['content-type']).indexOf('text/html') !== -1) {
googleResponse.on('data', function(chunk) {
body += chunk;
});
googleResponse.on('end', function() {
// Make changes to HTML files when they're done being read.
body = body.replace(/google.com/gi, Host + ':' + port);
body = body.replace(
/<\/body>/,
'<script src="http://localhost:3000/new-script.js" type="text/javascript"></script></body>'
);
clientResponse.writeHead(googleResponse.statusCode, googleResponse.headers);
clientResponse.end(body);
});
}
else {
googleResponse.pipe(clientResponse, {
end: true
});
}
});
googleRequest.end();
});
Super simple et lisible, voici comment créer un serveur proxy local sur un serveur HTTP local avec juste Node.js (testé sur v8.1.0 ). Je l'ai trouvé particulièrement utile pour les tests d'intégration, alors voici ma part:
/**
* Once this is running open your browser and hit http://localhost
* You'll see that the request hits the proxy and you get the HTML back
*/
'use strict';
const net = require('net');
const http = require('http');
const PROXY_PORT = 80;
const HTTP_SERVER_PORT = 8080;
let proxy = net.createServer(socket => {
socket.on('data', message => {
console.log('---PROXY- got message', message.toString());
let serviceSocket = new net.Socket();
serviceSocket.connect(HTTP_SERVER_PORT, 'localhost', () => {
console.log('---PROXY- Sending message to server');
serviceSocket.write(message);
});
serviceSocket.on('data', data => {
console.log('---PROXY- Receiving message from server', data.toString();
socket.write(data);
});
});
});
let httpServer = http.createServer((req, res) => {
switch (req.url) {
case '/':
res.writeHead(200, {'Content-Type': 'text/html'});
res.end('<html><body><p>Ciao!</p></body></html>');
break;
default:
res.writeHead(404, {'Content-Type': 'text/plain'});
res.end('404 Not Found');
}
});
proxy.listen(PROXY_PORT);
httpServer.listen(HTTP_SERVER_PORT);
https://Gist.github.com/fracasula/d15ae925835c636a5672311ef584b999
Je viens d’écrire un proxy dans nodejs qui s’occupe de HTTPS avec décodage optionnel du message. Ce proxy peut également ajouter un en-tête d'authentification de proxy afin de passer par un proxy d'entreprise. Vous devez donner comme argument l'URL pour trouver le fichier proxy.pac afin de configurer l'utilisation du proxy d'entreprise.