Search code examples
javascriptnode.jshttp-proxy

Use localhost as an http proxy


I am trying to create a localhost Http proxy, but so far nothing works. What I am trying to do is send a request to a different URL using the localhost proxy hosted on port 8200. I have so far tried this using this node library

var http = require('http'),
    httpProxy = require('http-proxy');
//
// Create your proxy server and set the target in the options.
//
httpProxy.createProxyServer({target:'https://www.google.com/recaptcha/api.js'}).listen(8200); // 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); 

I send the requests using the requests npm library.

const request = require('request');


    var req = request.get({
      url: site,
      proxy: `http://127.0.0.1:8200`,
      timeout: 10000
    }) 

The error I receive is this:

Error: tunneling socket could not be established, cause=connect ECONNREFUSED 127.0.0.1:8200
    at ClientRequest.onError (/Users/project/node_modules/tunnel-agent/index.js:177:17)
    at Object.onceWrapper (events.js:282:20)
    at ClientRequest.emit (events.js:194:13)
    at Socket.socketErrorListener (_http_client.js:401:9)
    at Socket.emit (events.js:194:13)
    at emitErrorNT (internal/streams/destroy.js:91:8)
    at emitErrorAndCloseNT (internal/streams/destroy.js:59:3)
    at processTicksAndRejections (internal/process/task_queues.js:81:17)
Error: tunneling socket could not be established, cause=socket hang up
    at ClientRequest.onError (/Users/project/node_modules/tunnel-agent/index.js:177:17)
    at Object.onceWrapper (events.js:282:20)
    at ClientRequest.emit (events.js:194:13)
    at Socket.socketOnEnd (_http_client.js:435:9)
    at Socket.emit (events.js:199:15)
    at endReadableNT (_stream_readable.js:1141:12)
    at processTicksAndRejections (internal/process/task_queues.js:81:17)
Error: tunneling socket could not be established, cause=socket hang up
    at ClientRequest.onError (/Users/project/node_modules/tunnel-agent/index.js:177:17)
    at Object.onceWrapper (events.js:282:20)
    at ClientRequest.emit (events.js:194:13)
    at Socket.socketOnEnd (_http_client.js:435:9)
    at Socket.emit (events.js:199:15)
    at endReadableNT (_stream_readable.js:1141:12)
    at processTicksAndRejections (internal/process/task_queues.js:81:17)
Error: tunneling socket could not be established, cause=read ECONNRESET 

Is it possible to create a localhost HTTP proxy? If so, how should I go about doing so?


Solution

  • The http-proxy docs aren't really clear on how to set up a dynamic http proxy.

    The first .listen() in your code doesn't really setup a proxy server even though it's attached to .createProxyServer(). Instead, it just creates a regular http server just like the second .listen() that comes after .createServer().

    Based on the examples, I messed around with it a bit and came up with this as a bare minimum for proxying http requests. (It doesn't handle https and I'm not sure what other restrictions it might have):

    var http = require('http'),
        httpProxy = require('http-proxy');
    
    /* This creates a kind of agent used to fetch content on behalf of an 
       http proxy request. 
    */
    var proxy = httpProxy.createProxyServer();
    
    /* This creates a regular web server. Http proxies still use http,
       just a little differently than usual.
    */
    http.createServer(function (req, res) {
      /* Urls in proxy requests includes parts, like domain and port, that aren't
         included in the `GET` of regular http requests.
      */
      /* Serve up some content. Normally this would be some page content or 
         something but, since we're supposed to be an http proxy, we tell `proxy`
         to handle the request.
      */
      proxy.web(req, res, { target: req.url });
    }).listen(8200);