Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is remoteAddress going to always be the same for applications behind a proxy? #6

Open
vanwagonet opened this issue May 29, 2014 · 11 comments · May be fixed by #17
Open

Is remoteAddress going to always be the same for applications behind a proxy? #6

vanwagonet opened this issue May 29, 2014 · 11 comments · May be fixed by #17

Comments

@vanwagonet
Copy link

Sticky session will always send the connections to a single worker when run behind a proxy, since it does not check the X-Forwarded-For header, and relies solely on socket.remoteAddress.

@indutny
Copy link
Owner

indutny commented May 31, 2014

Hm... sounds like an awesome configuration option. What do you think about sending a PR that will implement it? ;)

@vanwagonet
Copy link
Author

I'll give it a shot when I get some time.

@vanwagonet
Copy link
Author

My first pass didn't fly. If I pass the connection from an http server, instead of from a net server, the protocol parser has already read the request from the socket, and the child's handler is never invoked.

server = http.createServer(function(req, res) {
  // Get int31 hash of ip
  var worker, getIP = require('proxy-addr'),
      ip = trustProxy && getIP(req, trustProxy) || req.connection.remoteAddress,
      ipHash = hash((ip || '').split(/\./g), seed);

  // Pass connection to worker
  worker = workers[ipHash % workers.length];
  worker.send('sticky-session:connection', req.connection);
});

Any ideas?

@samcday
Copy link

samcday commented Jun 29, 2014

@thetalecrafter I tried my hand at doing something like this too.

I tried some hacky voodoo, in that after the http Server request event is fired, I would serialize the parsed data (headers / url / etc), pause the socket stream, and then send() the serialized request payload + socket to the forked child. On the child end I would reconstruct an http.IncomingRequest and http.ServerResponse with the underlying socket and serialized payload.

It actually worked too, I had fully functioning req and res reconstructed on the child side. Except the problem is more often than not at the point that you handle a request event on the master side, the HTTP parser impl has already read a chunk or two of the http body too. So unless you also figure out a way to grab the chunks of the body that have been read so far and send those in the payload, it means the XHR-polling when a client has data will be broken.

So far it seems that Socket.IO 1.0 is 100% hostile to Heroku. If you have multiple dynos, that'll be broken due to Heroku's lack of session affinity. If you want to compromise and run a single dyno with a few cluster workers, you also can't do that, because even sticky-session will fall over - each request comes from a really big pool of instances in the Heroku routing layer - so XHR polling triggers a lot of handshake fails, as the same sid could come from any one of those routers, screwing up the consistent routing this module provides.

/rant

@nerdbeere
Copy link

Does anyone have a solution for this yet? I would hack it in there myself but I didn't come up with any solution so far.

@nike527
Copy link

nike527 commented Dec 23, 2014

I also encountered the same problem,the remoteAddress Always 127.0.0.1,why?

@esamattis
Copy link

Since that is the remote address of your proxy from the perspective of your application.

@nike527
Copy link

nike527 commented Dec 24, 2014

What is a good solution?

@cha0s
Copy link

cha0s commented Feb 7, 2015

You all might be interested in my latest pull request: #20

@diwu1989
Copy link

add port to part of the hash and you should be fine, even if its behind the same proxy, it'd be different port numbers for different clients

@binary-person
Copy link

For anyone stumbling upon this issue, I made a fork of this that solves this issue nicely, along with adding nice graceful shutdown options.

https://github.com/binary-person/sticky-session-custom
https://www.npmjs.com/package/sticky-session-custom

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
9 participants