EzDevInfo.com

node-http-proxy

A full-featured http proxy for node.js nodejitsu/node-http-proxy · GitHub node-http-proxy - a full-featured http proxy for node.js

Check if request is in state of re-direct

There is a way with express check if the request is in status redirect (302) ,I use the( req,res ) I use the following ?

var http = require('http'),
httpProxy = require('http-proxy');

var proxy = httpProxy.createProxyServer({});   

proxy.on('proxyReq', function(proxyReq, req, res, options) {
    proxyReq.setHeader('X-Special-Proxy-Header', 'foobar');
});

proxy.on('proxyRes', function (proxyRes, req, res) {
    console.log('RAW Response from the target', JSON.stringify(proxyRes.headers, true, 2));
});

https://github.com/nodejitsu/node-http-proxy


Source: (StackOverflow)

proxy node request to new port and act like reverse proxy

I need to create an application that proxies a request from port A to Port B. For instance if a user connects on port 3000 he will be routed (under the hood) to port 3001, therefore the "original" application will run on port 3001 but in the client (browser) the user will put port 3000. Not redirect...

http://example.com:3000/foo/bar

A new server will be created which listens to port 3001 and all the call are actually to port 3000 running with the new server and new port. Since port 3000 is actually occupied,by my reverse proxy app? how should I test it...

Is there a way to test this to verify that this is working,e.g. by unit testing?

I've found this module https://github.com/nodejitsu/node-http-proxy which might be able to help.


Source: (StackOverflow)

Advertisements

Node.js http-proxy drops websocket requests

Okay, I've spent over a week trying to figure this out to no avail, so if anyone has a clue, you are a hero. This isn't going to be an easy question to answer, unless I am being a dunce.

I am using node-http-proxy to proxy sticky sessions to 16 node.js workers running on different ports.

I use Socket.IO's Web Sockets to handle a bunch of different types of requests, and use traditional requests as well.

When I switched my server over to proxying via node-http-proxy, a new problem crept up in that sometimes, my Socket.IO session cannot establish a connection.

I literally can't stably reproduce it for the life of me, with the only way to turn it on being to throw a lot of traffic from multiple clients to the server.

If I reload the user's browser, it can then sometimes re-connect, and sometimes not.

Sticky Sessions

I have to proxy sticky sessions as my app authenticates on a per-worker basis, and so it routes a request based on its Connect.SID cookie (I am using connect/express).

Okay, some code

This is my proxy.js file that runs in node and routes to each of the workers:

var http = require('http');
var httpProxy = require('http-proxy');

// What ports the proxy is routing to.
var data = {
  proxyPort: 8888,
  currentPort: 8850,
  portStart: 8850,
  portEnd: 8865,
};

// Just gives the next port number.
nextPort = function() {
  var next = data.currentPort++;
  next = (next > data.portEnd) ? data.portStart : next;
  data.currentPort = next;
  return data.currentPort;
};

// A hash of Connect.SIDs for sticky sessions.
data.routes = {}

var svr = httpProxy.createServer(function (req, res, proxy) {

  var port = false;

  // parseCookies is just a little function
  // that... parses cookies.
  var cookies = parseCookies(req);  

  // If there is an SID passed from the browser.
  if (cookies['connect.sid'] !== undefined) {

    var ip = req.connection.remoteAddress;

    if (data.routes[cookies['connect.sid']] !== undefined) {

      // If there is already a route assigned to this SID,
      // make that route's port the assigned port.
      port = data.routes[cookies['connect.sid']].port;
    } else {

      // If there isn't a route for this SID,
      // create the route object and log its
      // assigned port.
      port = data.currentPort;
      data.routes[cookies['connect.sid']] = {
        port: port,
      }

      nextPort();
    }

  } else {

    // Otherwise assign a random port, it will/
    // pick up a connect SID on the next go.
    // This doesn't really happen.
    port = nextPort();
  }

  // Now that we have the chosen port, 
  // proxy the request.
  proxy.proxyRequest(req, res, {
    host: '127.0.0.1',
    port: port
  });
}).listen(data.proxyPort);

// Now we handle WebSocket requests.
// Basically, I feed off of the above route
// logic and try to route my WebSocket to the
// same server regular requests are going to.
svr.on('upgrade', function (req, socket, head) {

  var cookies = parseCookies(req);  
  var port = false;

  // Make sure there is a Connect.SID,
  if (cookies['connect.sid'] != undefined) {

    // Make sure there is a route...
    if (data.routes[cookies['connect.sid']] !== undefined) {

      // Assign the appropriate port.
      port = data.routes[cookies['connect.sid']].port;
    } else {

      // this has never, ever happened, i've been logging it.
    }
  } else {

    // this has never, ever happened, i've been logging it.
  };

  if (port === false) {

    // this has never happened...
  };

  // So now route the WebSocket to the same port
  // as the regular requests are getting.
  svr.proxy.proxyWebSocketRequest(req, socket, head, {
    host: 'localhost',
    port: port
  });

});

Client Side / The Phenomena

Socket connects like so:

var socket = io.connect('http://whatever:8888');

After about 10 seconds on logging on, I get this error back on this listener, which doesn't help much.

socket.on('error', function (data) {
  // this is what gets triggered. ->
  // Firefox can't establish a connection to the server at ws://whatever:8888/socket.io/1/websocket/Nnx08nYaZkLY2N479KX0.
});

The Socket.IO GET request that the browser sends never comes back - it just hangs in pending, even after the error comes back, so it looks like a timeout error. The server never responds.

Server Side - A Worker

This is how a worker receives a socket request. Pretty simple. All workers have the same code, so you think one of them would get the request and acknowledge it...

app.sio.socketio.sockets.on('connection', function (socket) {
  // works... some of the time! all of my workers run this
  // exact same process.
});

Summary

That's a lot of data, and I doubt anyone is willing to confront it, but i'm totally stumped, don't know where to check next, log next, whatever, to solve it. I've tried everything I know to see what the problem is, to no avail.

UPDATE

Okay, I am fairly certain that the problem is in this statement on the node-http-proxy github homepage:

node-http-proxy is <= 0.8.x compatible, if you're looking for a >= 0.10 compatible version please check caronte

I am running Node.js v0.10.13, and the phenomena is exactly as some have commented in github issues on this subject: it just drops websocket connections randomly.

I've tried to implement caronte, the 'newer' fork, but it is not at all documented and I have tried my hardest to piece together their docs in a workable solution, but I can't get it forwarding websockets, my Socket.IO downgrades to polling.

Are there any other ideas on how to get this implemented and working? node-http-proxy has 8200 downloads yesterday! Sure someone is using a Node build from this year and proxying websockets....

What I am look for exactly

I want to accomplish a proxy server (preferrably Node) that proxies to multiple node.js workers, and which routes the requests via sticky sessions based on a browser cookie. This proxy would need to stably support traditional requests as well as web sockets.

Or...

I don't mind accomplishing the above via clustered node workers, if that works. My only real requirement is maintaining sticky sessions based on a cookie in the request header.

If there is a better way to accomplish the above than what I am trying, I am all for it.


Source: (StackOverflow)

How to update location in for http call

Im using the reverse proxy from the following link, currently Im getting some location and I want to update it(the location), How can I do that?

proxy.on('proxyRes', function (proxyRes, req, res) {

res.headers.location = 'http:/a/b/'

});

and I need to change it for example to be

res.headers.location = 'http:/c/d/' I will handle the logic how to change the URL but I want to know how to update it...

https://github.com/nodejitsu/node-http-proxy


Source: (StackOverflow)

Forward every request with node-http-proxy

I'm trying to setup a node-http-proxy that just forwards requests. In the end this proxy should inject javascript in every website I visit through the browser..

Right now, most pages are forwarded and displayed correctly, but some, like posterkoenig.ch or verkehrsclub.ch are returning either a blank page or there is an error on the page. Both sites work well without the proxy in place. What do I have to change, or what am I missing that gets not forwarded correctly?

Im very new to nodejs and not even completely sure if my approach should work or not.

Here is what I've got so far:

var httpProxy = require('http-proxy');
var url = require('url');

httpProxy.createServer(function(req, res, proxy) {

  var urlObj = url.parse(req.url);

  proxy.proxyRequest(req, res, {
    host: urlObj.host,
    port: 80,
    changeOrigin: true,
    enable : { xforward: true }
  });
}).listen(9000, function () {
  console.log("Waiting for requests...");
});

Update

As suggested by @robertklep I removed changeOrigin and redefined req.headers.host and also req.headers.url

posterkoenig.ch: Now throws: An error has occurred: {"code":"ENOTFOUND","errno":"ENOTFOUND","syscall":"getaddrinfo"}

verkehrsclub.ch: The frontpage works now but subpages still throw a error on the page.

var httpProxy = require('http-proxy');
var url = require('url');

httpProxy.createServer(function(req, res, proxy) {

  var urlObj = url.parse(req.url);

  req.headers['host'] = urlObj.host;
  req.headers['url'] = urlObj.href;

  proxy.proxyRequest(req, res, {
    host: urlObj.host,
    port: 80,
    enable : { xforward: true }
  });
}).listen(9000, function () {
  console.log("Waiting for requests...");
});

Source: (StackOverflow)

Node http-proxy and express

I'm trying to do something like this:

// Setup prox to handle blog requests
httpProxy.createServer({
    hostnameOnly: true,
    router: {
        'http://localhost': '8080',
        'http://localhost/blog': '2368' 
    }
}).listen(8000);

Previously I was using this:

http.createServer(app).listen(app.get('port'), function(){
    console.log("Express server listening on port " + app.get('port'));
});

Basically, I want to still use express... but, when people go to http://localhost/blog get taken to the blog but still be served over port 8080 (which will eventually be port 80)

So I switched it to this and it worked better. The problem is that express takes over the routing (from what I can tell)

var options = {
    // pathnameOnly: true,
    router: {
        'localhost': 'localhost:8080',
        'localhost/blog': 'localhost:2368'
    }
}

// Setup prox to handle blog requests
var proxyServer = httpProxy.createServer(options);
proxyServer.listen(9000);

require('./app/server/router')(app);

http.createServer(app).listen(app.get('port'), function(){
    console.log("Express server listening on port " + app.get('port'));
});

Source: (StackOverflow)

Rewrite response headers with node-http-proxy

I'm using node-http-proxy and want to watch for a particular response header and rewrite it if necessary. Anyone here have suggestions on to do this?

My proxy server sits in front of a couple different node servers as well as a java webapp. The java app is setting a cookie, but the cookie has a path that is relative the the webapp's context. I need the cookie to be secure and have a path to root without modifying the Java application.

In other words, the following header is returned:

set-cookie: MYSPECIALCOOKIE=679b6291-d1cc-47be; Path=/app; HttpOnly

And I'd like to rewrite the Path value to:

set-cookie: MYSPECIALCOOKIE=679b6291-d1cc-47be; Path=/; HttpOnly; Secure

I'm not clear how I would do this using node-http-proxy. Suggestions? Is there middleware to help with this?


Source: (StackOverflow)

Load balancing with node.js using http-proxy

I'm trying to code a loadbalancing with node.js and http-proxy. I want a loadBalancer which share incoming request treatment between 2 servers.

var http = require('http'),
httpProxy = require('http-proxy');

 var servers =  [{host :'127.0.0.1', port :3000}, {host : 'remote_adr',port :3000}];

  httpProxy.createServer(function (req, res, proxy) {

  var target = servers.shift();
  proxy.proxyRequest(req, res, target);
  servers.push(target);


   }).listen(8000);

I thought that doing this, it would have made a loadBalancer which send requests alternately to serv1 and to serv2.

However, when I try it out, it seems to request the 2 servers in no particular order. In addition most of the requests are sent to my localhost node server ( 127.0.0.1:3000 )

Is somebody able to explain that behavior ?

Thx a lot,

Florent.


Source: (StackOverflow)

Node http proxy with proxytable and websockets

I'm trying to get websockets to also work with node-http-proxy. The difference is i'm using a proxytable:

var options = {
router: {
    'a.websterten.com': '127.0.0.1:150',
    'b.websterten.com' : '127.0.0.1:151',
}
};

var server = httpProxy.createServer(options);

I tried:

server.on('upgrade', function (req, socket, head) {
    server.proxy.proxyWebSocketRequest(req, socket, head);
});

But it doesn't seem to work. A quick check to see whether websockets work shows I get Unexpected response code: 400 from Chrome (works fine if I go directly)

Also doing a couple of checks server.on('upgrade',.. doesn't fire on a websocket request

How can I get my proxy server to route websockets correctly?

I've also tried this on node 0.8.23 as well as node 0.10.x (the later versions of node have a memory leak issue, but it wont work on 0.8.23 either)


Source: (StackOverflow)

Using node http-proxy to proxy websocket connections

I have an application that uses websockets via socket.io. For my application I would like to use a separate HTTP server for serving the static content and JavaScript for my application. Therefore, I need to put a proxy in place.

I am using node-http-proxy. As a starting point I have my websockets app running on port 8081. I am using the following code to re-direct socket.io communications to this standalone server, while using express to serve the static content:

var http = require('http'),
    httpProxy = require('http-proxy'),
    express = require('express');

// create a server
var app = express();
var proxy = httpProxy.createProxyServer({ ws: true });

// proxy HTTP GET / POST
app.get('/socket.io/*', function(req, res) {
  console.log("proxying GET request", req.url);
  proxy.web(req, res, { target: 'http://localhost:8081'});
});
app.post('/socket.io/*', function(req, res) {
  console.log("proxying POST request", req.url);
  proxy.web(req, res, { target: 'http://localhost:8081'});
});

// Proxy websockets
app.on('upgrade', function (req, socket, head) {
  console.log("proxying upgrade request", req.url);
  proxy.ws(req, socket, head);
});

// serve static content
app.use('/', express.static(__dirname + "/public"));

app.listen(8080);

The above application works just fine, however, I can see that socket.io is no longer using websockets, it is instead falling back to XHR polling.

I can confirm that by looking at the logs from the proxy code:

proxying GET request /socket.io/1/?t=1391781619101
proxying GET request /socket.io/1/xhr-polling/f-VVzPcV-7_IKJJtl6VN?t=13917816294
proxying POST request /socket.io/1/xhr-polling/f-VVzPcV-7_IKJJtl6VN?t=1391781629
proxying GET request /socket.io/1/xhr-polling/f-VVzPcV-7_IKJJtl6VN?t=13917816294
proxying GET request /socket.io/1/xhr-polling/f-VVzPcV-7_IKJJtl6VN?t=13917816294

Does anyone know how to proxy the web sockets communication? All the examples from node-http-proxy assume that you want to proxy all traffic, rather than proxying some and serving others.


Source: (StackOverflow)

Invoking an asynchronous method inside a middleware in node-http-proxy

I'm trying to create a proxy with node-http-proxy in Node.js that checks whether a request is authorized in a mongodb.

Basically, I created a middleware module for the node-http-proxy that I use like this:

httpProxy.createServer(
require('./example-middleware')(),
9005, 'localhost'
).listen(8005)

What the middleware module does is using mongojs to connect to mongodb and run a query to see if the user is authorized to access the resource:

module.exports = function(){
// Do something when first loaded!
console.log("Middleware loaded!");

return function (req, res, next) {
var record = extractCredentials(req);
var query = -- Db query --

//Debug:
log("Query result", query);

db.authList.find(query).sort({
    "url.len": -1
}, function(err, docs){
    console.log(docs);

    // Return the creator for the longest matching path:
    if(docs.length > 0) {
        console.log("User confirmed!");
        next();
    } else {
        console.log("User not confirmed!");
        res.writeHead(403, {
            'Content-Type': 'text/plain'
        });
        res.write('You are not allowed to access this resource...');
        res.end();
    }

});

}
}

Now the problem is that as soon as I add the asynchronous call to mongodb using mongojs the proxy hangs and never send the response back.

To clarify: on a "User not confirmed" everything works fine and the 403 is returned. On a "user confirmed" however I see the log but the browser then hangs forever and the request isn't proxied.

Now, if I remove the "user confirmed" and next() part outside of a callback it does work:

module.exports = function(){
// Do something when first loaded!
console.log("Middleware loaded!");

return function (req, res, next) {
    var record = extractCredentials(req);
    var query = --- query ---


    console.log("User confirmed!");
    next();
}

but I can't do that since the mongojs query is meant (rightfully I guess) to be executed asynchronously, the callback being triggered only when the db replied...

I also tried the version without using a middleware:

http.createServer(function (req, res) {
  // run the async query here!
  proxy.proxyRequest(req, res, {
  host: 'localhost',
  port: 9000
});
}).listen(8001);

But that did not help either...

Any clue? Note that I'm new to node.js so I suspect a misunderstanding on my side...


Source: (StackOverflow)

EC2 hosted Node.js application - can't remotely connect to port

Update: Turns out the only problem was that I was behind a firewall that blocked some ports, but not 8000.


Edit: TL;DR: can't connect to port 9000 remotely, but port 8000 is ok and I don't know why :(


I've got this node.js application that's running on port 8000 and another one (http-proxy) running on port 9000.

Running them on my machine is fine, but I have some problems when I put them up on a server (EC2 instance - I did open the ports in the web console security group[1]). The application works fine, but I can't connect to the proxy from outside. I tried to $ telnet localhost 9000 on the server and it connects, so I guess that's a good sign.

Another thing that I have noticed is that if I try to run the applications separately, I get the same results, i.e.: 8000 - OK, 9000 - NOTOK :<. However, if I change the port the proxy uses from 9000 to 8000, it works. And if I switch the ports, i.e. application:9000 and proxy:8000, I can connect to the proxy, but not to the application. I have also tried other numbers, but that wouldn't fix it either.

I guess there's something really stupid that has nothing to do with the application itself and that I'm missing, but I can't put my finger on it, so does anyone have any idea why this setup doesn't work?

server.js

var express = require('express.io');
var app = module.exports = express();

require('./proxy');

app.http().io();
app.listen(8000);
// ...

proxy.js

var httpProxy = require('http-proxy');
var url = require('url');

httpProxy.createServer(function(req, res, proxy) {

    // ... 
    proxy.proxyRequest(req, res, {
        host: destination.host,
        port: 80
    });

}).listen(9000);

$ netstat -pln | grep node output

tcp   0      0      0.0.0.0:9000    0.0.0.0:*       LISTEN  1487/node
tcp   0      0      0.0.0.0:8000    0.0.0.0:*       LISTEN  1487/node

Security group rules

1


Source: (StackOverflow)

Node hangs on POST request when using http-proxy and body-parser with express

I've also posted this to the relevant issue on http-proxy.

I'm using http-proxy with express so I can intercept requests between my client and api in order to add some cookies for authentication.

In order to authenticate the client must send a POST request with x-www-form-urlencoded as the the content-type. So I am using body-parser middleware to parse the request body so I can insert data in the request.

http-proxy has a problem with using body-parser supposedly because it parses the body as a stream and never closes it so the proxy never never completes the request.

There is a solution in the http-proxy examples that "re-streams" the request after it has been parsed which I have tried to use. I have also tried to use the connect-restreamer solution in the same issue with no luck.

My code looks like this

var express = require('express'),
    bodyParser = require('body-parser'),
    httpProxy = require('http-proxy');

var proxy = httpProxy.createProxyServer({changeOrigin: true});
var restreamer = function (){
  return function (req, res, next) { //restreame
    req.removeAllListeners('data')
    req.removeAllListeners('end')
    next()
    process.nextTick(function () {
      if(req.body) {
        req.emit('data', req.body) //error gets thrown here
      }
      req.emit('end')
    })
  }
}

var app = express();

app.use(bodyParser.urlencoded({extended: false, type: 'application/x-www-form-urlencoded'}));
app.use(restreamer());

app.all("/api/*", function(req, res) {
    //modifying req.body here
    //
    proxy.web(req, res, { target: 'http://urlToServer'});
});

app.listen(8080);

and I receive this error

/Code/project/node_modules/http-proxy/lib/http-proxy/index.js:119
throw err;
      ^
Error: write after end
    at ClientRequest.OutgoingMessage.write (_http_outgoing.js:413:15)
    at IncomingMessage.ondata (_stream_readable.js:540:20)
    at IncomingMessage.emit (events.js:107:17)
    at /Code/project/lib/server.js:46:25
    at process._tickCallback (node.js:355:11)

I have tried to debug the flow but am grasping for straws. Any suggestions please??


Source: (StackOverflow)

vhosts with http-proxy and express

I'm trying to emulate virtual hosts on nodeje express with http-proxy

code

httpProxy.createServer({
    hostnameOnly : true,
    router : {
        'secure.domain.com' : '127.0.0.1:9000'
    }
}).listen(8080);

(function(){
    var app = express();
    app.set('port', 9000);

    // Web request
    app.get('/*', function(request, response){
        response.end('wolla');
    });

    var server = http.createServer(app).listen(app.get('port'), function(){
      console.log('Express server listening on port '+app.get('port'));
    });
})();

easy example used to get inspiration but returns same error

var http = require('http'),
    httpProxy = require('http-proxy');
//
// Create a basic proxy server in one line of code...
//
// This listens on port 8000 for incoming HTTP requests 
// and proxies them to port 9000
httpProxy.createServer(9000, 'localhost').listen(8000);

//
// ...and a simple http server to show us our request back.
//
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);

error

/var/www/node/node_modules/http-proxy/lib/http-proxy/passes/web-incoming.js:103
    var proxyReq = (options.target.protocol === 'https:' ? https : http).reque
                                  ^
TypeError: Cannot read property 'protocol' of undefined
    at Array.stream [as 3] (/var/www/node/node_modules/http-proxy/lib/http-proxy/passes/web-incoming.js:103:35)
    at ProxyServer.<anonymous> (/var/www/node/node_modules/http-proxy/lib/http-proxy/index.js:83:21)
    at Server.closure (/var/www/node/node_modules/http-proxy/lib/http-proxy/index.js:116:43)
    at Server.EventEmitter.emit (events.js:98:17)
    at HTTPParser.parser.onIncoming (http.js:2108:12)
    at HTTPParser.parserOnHeadersComplete [as onHeadersComplete] (http.js:121:23)
    at Socket.socket.ondata (http.js:1966:22)
    at TCP.onread (net.js:525:27)
Worker 31599 died (8). Restarting...
Express server listening on port 9000

Source: (StackOverflow)

http-proxy forward to a specific path

While trying out http-proxy with node.js, I have the following piece of code:

var httpProxy = require('http-proxy');

httpProxy.createServer(
  require('proxy-by-url')({
  '/AAA': { port: 80, host: 'myDomain.com' },
  '/BBB': { port: 80, host: 'myDomain.com' }
  })
).listen(8000);

Obviously all requests to http://localhost:8000/AAA and http://localhost:8000/BBB are proxied to http://myDomain.com

I'm trying to proxy the requests to http://localhost:8000/AAA to http://myDomain.com/AAA/rss.xml but cannot figure out how to set that up.

I tried with:

'/AAA': { port: 80, host: 'myDomain.com/AAA/rss.xml' }

but it is throwing exceptions.

'/AAA': { port: 80, host: 'myDomain.com', url: '/AAA/rss.xml' }

or

'/AAA': { port: 80, host: 'myDomain.com', path: '/AAA/rss.xml' }

are inefficiency.

Does someone has an idea on how to set that up?


Source: (StackOverflow)