Подтвердить что ты не робот

Простой node.js прокси-сервер через HTTP-сервер http-подключения к HTTP-запросу

Попытка узнать больше о node.js, сделав простой HTTP-прокси-сервер. Сценарий использования прост: пользователь → прокси → сервер → прокси → пользователь

Следующий код работает до последнего шага. Не удалось найти путь к выводу соединителя контуров обратно пользователю.

#!/usr/bin/env node

var
    url = require('url'),
    http = require('http'),
    acceptor = http.createServer().listen(3128);

acceptor.on('request', function(request, response) {
    console.log('request ' + request.url);
    request.pause();
    var options = url.parse(request.url);
    options.headers = request.headers;
    options.method = request.method;
    options.agent = false;

    var connector = http.request(options);
    request.pipe(connector);
    request.resume();
//  connector.pipe(response); // doesn't work
//  connector.pipe(request); // doesn't work either
});

Используя tcpflow, я вижу входящий запрос из браузера, затем исходящий запрос прокси, затем ответ сервера обратно на прокси. Как-то я не смог выполнить повторную передачу ответа обратно в браузер.

Каков правильный способ реализации этой логики с помощью труб?

4b9b3361

Ответ 1

OK. Получил это.

ОБНОВЛЕНИЕ: NB! Как отмечается в комментариях, этот пример больше не работает. Скорее всего, из-за изменения API Streams2 (node 0,9 +)

Возврат обратно к клиенту происходит внутри обратного вызова соединителя следующим образом:

#!/usr/bin/env node

var
    url = require('url'),
    http = require('http'),
    acceptor = http.createServer().listen(3128);

acceptor.on('request', function(request, response) {
    console.log('request ' + request.url);
    request.pause();
    var options = url.parse(request.url);
    options.headers = request.headers;
    options.method = request.method;
    options.agent = false;

    var connector = http.request(options, function(serverResponse) {
            serverResponse.pause();
            response.writeHeader(serverResponse.statusCode, serverResponse.headers);
            serverResponse.pipe(response);
            serverResponse.resume();
    });
    request.pipe(connector);
    request.resume();
});

Ответ 2

вам не нужно "приостанавливать", просто "труба" в порядке

var connector = http.request(options, function(res) {
  res.pipe(response, {end:true});//tell 'response' end=true
});
request.pipe(connector, {end:true});

http-запрос не завершится, пока вы не скажете, что это "конец";

Ответ 3

Я использовал примеры из этого сообщения для прокси-запросов http/s. Столкнувшись с проблемой, что файлы cookie были где-то потеряны.

Итак, чтобы исправить это, вам нужно обрабатывать заголовки из ответа прокси.

Ниже рабочего примера:

req = service.request(options, function(res) {
    response.writeHead(res.statusCode, res.headers);
    return res.pipe(response, {end: true});
});
request.pipe(req, {end: true});