2012-04-19 3 views
2

Я пытаюсь создать простой node.js прокси-сервер для экспериментальных целей, и я придумал этот простой сценарий:Реализация простой прокси-сервер с помощью Node.js

var url = require("url"); 
var http = require("http"); 
var https = require("https"); 

http.createServer(function (request, response) { 
    var path = url.parse(request.url).path; 

    if (!path.indexOf("/resource/")) { 
     var protocol; 
     path = path.slice(10); 
     var location = url.parse(path); 

     switch (location.protocol) { 
     case "http:": 
      protocol = http; 
      break; 
     case "https:": 
      protocol = https; 
      break; 
     default: 
      response.writeHead(400); 
      response.end(); 
      return; 
     } 

     var options = { 
      host: location.host, 
      hostname: location.hostname, 
      port: +location.port, 
      method: request.method, 
      path: location.path, 
      headers: request.headers, 
      auth: location.auth 
     }; 

     var clientRequest = protocol.request(options, function (clientResponse) { 
      response.writeHead(clientResponse.statusCode, clientResponse.headers); 
      clientResponse.on("data", response.write); 
      clientResponse.on("end", function() { 
       response.addTrailers(clientResponse.trailers); 
       response.end(); 
      }); 
     }); 

     request.on("data", clientRequest.write); 
     request.on("end", clientRequest.end); 
    } else { 
     response.writeHead(404); 
     response.end(); 
    } 
}).listen(8484); 

Я не знаю, где Я буду неправ, но это дает мне следующую ошибку, когда я пытаюсь загрузить любую страницу:

http.js:645 
    this._implicitHeader(); 
     ^
TypeError: Object #<IncomingMessage> has no method '_implicitHeader' 
    at IncomingMessage.<anonymous> (http.js:645:10) 
    at IncomingMessage.emit (events.js:64:17) 
    at HTTPParser.onMessageComplete (http.js:137:23) 
    at Socket.ondata (http.js:1410:22) 
    at TCP.onread (net.js:374:27) 

Интересно, что эта проблема может быть. Отладка в node.js гораздо сложнее, чем в Rhino. Любая помощь будет оценена.

+0

Я запустил код на своем компьютере. Таким образом, я открыл его в своем веб-браузере, перейдя на http: // localhost: 8484/resource/http: // code.jquery.com/jquery.js'. Он должен был извлечь файл 'jquery.js' и перенаправить его, но вместо этого он дал мне вышеупомянутую ошибку. –

+0

Мое первоначальное предположение состояло в том, что это связано с тем, как вы передаете функции «данным» и «концу». Можете ли вы попробовать передать анонимные функции, которые вызывают 'clientRequest.write()' и 'clientRequest.end()'? Теперь у вас есть это, вы передаете функцию, но когда она будет вызвана, она не будет иметь соответствующий контекст ('this'). – loganfsmyth

+0

Вы пытаетесь получить содержимое URL-адреса? URL-адрес после «resource» –

ответ

3

Как я уже упоминал в комментариях, ваша основная проблема заключается в том, что ваши вызовы .write10 и .end не привязаны должным образом к контексту, поэтому они просто перевернут и выбросят ошибки на всем протяжении.

С учетом этого исправления просьба дает 404, так как свойство headers будет тянуть в заголовке host исходного кода, localhost:8484. Следуя вашему примеру, он будет отправлен на сервер jquery.com, и он будет 404. Перед проксированием вам нужно удалить заголовок host.

Добавить это до звонка protocol.request.

delete options.headers.host; 
+0

Благодарим за помощь. Отлично работает. Я подумал, что было бы неплохо установить 'options.headers.host', чтобы указать на' location.host', а не удалять его. знак равно –