Too many redirects #3

Merged
merged 3 commits into from Oct 24, 2012

Conversation

Projects
None yet
2 participants
Contributor

camwest commented Oct 14, 2012

I'm having an issue with too many redirects. I've published a public version of the proxy here:

https://github-com.proxy.kera.io/

It's hard to tell if I've misconfigured something or if there is a bug in xtend.

Owner

deanmao commented Oct 13, 2012

This is what I was talking about regarding x-forwarded-proto headers. my guess is that you're using a ssl tunnel like nginx that isn't connected to a separate node server specifically for ssl. When you have only 1 server for http & https, then it needs to differentiate between requests.

In this case, you're accessing https://github.com, but the xtend proxy thinks it is non-ssl, so it hits the non-ssl url, and github sends back with a location header for the ssl version, then your browser tries to redirect to the ssl version, and your proxy again thinks it's non-ssl so it makes the non-ssl request to github, ad inifinitum.

The easiest way to run xtend for ssl & non-ssl mode is to uncomment the lines in xtend-example that refer to ssl mode. You'll have to generate a self signed cert that corresponds to your internal domain, and you'll have to forward requests to port 443 to 8443 (the port that the ssl-branded node server is running on).

This is why if the x-forwarded-proto header is not sent from your ssl load balancer, (like you mentioned when you deploy to heroku) it would make the wrong request, and it would appear to the user as something broken, when it's merely a server configuration issue.

Contributor

camwest commented Oct 13, 2012

So even with a self signed cert it will work without a cert warning since its going through a proxy?

This is definitely the most confusing part that I guess I'm just not groking.

I made the chance to use the headed inside the filter as you suggested. Is that still not enough?

So even on Heroku I need to have two node servers running? One ssl and one not?

Cameron Westland

On Saturday, 13 October, 2012 at 2:04 AM, Dean Mao wrote:

This is what I was talking about regarding x-forwarded-proto headers. my guess is that you're using a ssl tunnel like nginx that isn't connected to a separate node server specifically for ssl. When you have only 1 server for http & https, then it needs to differentiate between requests.
In this case, you're accessing https://github.com, but the xtend proxy thinks it is non-ssl, so it hits the non-ssl url, and github sends back with a location header for the ssl version, then your browser tries to redirect to the ssl version, and your proxy again thinks it's non-ssl so it makes the non-ssl request to github, ad inifinitum.
The easiest way to run xtend for ssl & non-ssl mode is to uncomment the lines in xtend-example that refer to ssl mode. You'll have to generate a self signed cert that corresponds to your internal domain, and you'll have to forward requests to port 443 to 8443 (the port that the ssl-branded node server is running on).
This is why if the x-forwarded-proto header is not sent from your ssl load balancer, (like you mentioned when you deploy to heroku) it would make the wrong request, and it would appear to the user as something broken, when it's merely a server configuration issue.


Reply to this email directly or view it on GitHub (#3 (comment)).

Owner

deanmao commented Oct 13, 2012

I'm not sure what headers get sent on heroku as I've never tried running this there. I guess if you were able to specify the protocol of the request coming in as a header, then you wouldn't need to run 2 servers.

Contributor

camwest commented Oct 13, 2012

According to this: http://stackoverflow.com/questions/7185074/heroku-nodejs-http-to-https-ssl-forced-redirect they send the x-forwarded-proto header, so in theory the pull request that I just had merged should solve the problem right? Well I'm still getting the too many redirects issue with it. Could there be somewhere else that this needs to be specified?

Contributor

camwest commented Oct 13, 2012

I just verified and it's definitely sending the header correctly with 'https' but I'm still seeing a redirect loop.

The url going to the request() method on line 89 of filter.coffee is 'https://github.com/' so I'm really not sure what to think. This isn't happening in my dev environment when I run a separate https server so I'm wondering if there are other places that the x-forwarded-proto header needs to go.

Contributor

camwest commented Oct 13, 2012

Hey Dean, I added you to the kera-proxy project. I was hoping you could take a look if you had any free time. It's basically xtend-example switched around to work with Heroku. I know you don't have any experience with it but it really should be working since the x-forwarded-proto header is being set correctly.

Contributor

camwest commented Oct 14, 2012

Nevermind, I've reproduced the issue locally using xtend-example so its definitely a problem with using nginx as a forward proxy. http://f.cl.ly/items/0g0w092D34091A1D2m3j/nginx_redirect_loop.mov shows the issue with a very basic forward proxy config in nginx.

-C

Owner

deanmao commented Oct 14, 2012

so the header is being set, but the app isn't handling it as a ssl request?

Contributor

camwest commented Oct 14, 2012

It seems that way. It's hard to tell.

https://github.com/deanmao/xtend/blob/master/lib/filter.coffee#L81

is showing that it is using the header to construct the url, I've also updated

https://github.com/deanmao/xtend/blob/master/lib/filter.coffee#L87

to pass in the https protocol as well without any luck. Is there somewhere else where the protocol might be being misconfigured?

Contributor

camwest commented Oct 14, 2012

I turned on guide debugging:

Request headers --------->>>
{
    accept-charset: 'ISO-8859-1,utf-8;q=0.7,*;q=0.3',
    accept-language: 'en-US,en;q=0.8',
    user-agent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.94 Safari/537.4',
    x-real-ip: '127.0.0.1',
    x-forwarded-proto: 'https',
    accept-encoding: 'gzip,deflate,sdch',
    x-forwarded-for: '127.0.0.1',
    accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
    connection: 'close',
    cache-control: 'no-cache',
    pragma: 'no-cache',
    host: 'github.com'
}
Unmodified Response headers <<<---------
{
    content-length: '85',
    connection: 'close',
    cache-control: 'no-cache',
    location: 'https://github.com/',
    server: 'nginx',
    x-runtime: '1',
    content-type: 'text/html; charset=utf-8',
    date: 'Sun, 14 Oct 2012 18:14:21 GMT',
    status: '301 Moved Permanently'
}
Response headers <<<---------
{
    x-powered-by: 'Express',
    connection: 'close',
    cache-control: 'no-cache',
    location: 'https://github-com.xtend.dev/',
    server: 'nginx',
    x-runtime: '1',
    x-original-url: 'github.com/',
    content-type: 'text/html; charset=utf-8',
    date: 'Sun, 14 Oct 2012 18:14:21 GMT',
    status: '301 Moved Permanently'
}
Contributor

camwest commented Oct 14, 2012

Here is the remote request uri:

{
    hostname: 'github.com',
    host: 'github.com',
    href: 'https://github.com/',
    path: '/',
    slashes: true,
    protocol: 'https:',
    port: 443,
    pathname: '/'
}
Contributor

camwest commented Oct 14, 2012

I figured out the issue. Going to submit a pull request once I clean things up.

deanmao added a commit that referenced this pull request Oct 24, 2012

@deanmao deanmao merged commit 62813e1 into deanmao:master Oct 24, 2012

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment