Respect X-Forwarded-Proto header
This is an attempt to resolve #86
Coverage increased (+0.02%) to 82.627% when pulling 9f1501b2003f0af47a340d8e84cbf689127f8899 on neos-uk:no-forwarded-proto-overwrite into 52e57c0a2b7f1732fb6f78ace91ea04f65e3be01 on socketry:master.
All three of these commits actually have the same effect (I was thrown off by #88), so take your pick which one you'd like and I'll rebase things.
Thanks @bryanp - X-Forwarded-Proto is also not standardised... there is another header which is specified by the RFC... I need to review it.
The security issues are less of a concern, but I do want to hear more about it if anyone has any other concerns. Using the user facing headers... should probably be something explicit in the app... as it stands, the protocol reported by falcon is the last hop... but in this case we want the first hop...
Typically this header will get explicitly set by the server doing SSL termination. I've tested this on Heroku and even if I send X-Forwarded-Proto: https on an HTTP request by the time it gets to my application server its been rewritten to http by their load balancer. In other places I've injected the header in nginx with similar behaviour.
Sorry, I have not come back to this and it's been sitting for a while.
There are a few options:
- This PR, which is great.
- Prefer
Forwardedheader. - Something more elaborate like Puma.
There is one other issue.
The HTTP/2 pseudo header :scheme should probably be preferred which comes via request.scheme.
I don't really have a strong feeling on this right now, except that what we are doing is already the simplest and most straight forward approach.
Should RACK_URL_SCHEME reflect the pseudo header? Or should we allow other headers to override it?
What's stopping applications from parsing out the X-Forwarded-Proto if that's what they want? Should we do this by default?
I'm all for making those headers easier to work with, and I don't even mind if we should use a more elaborate method for setting the default RACK_URL_SCHEME (e.g. this PR). I'm also wary of imposing more complex logic into the field, which then becomes a bit of "technical debt" going forward, and will only get more complex when we need to deal with Forwarded: (multi-hop) as well as X-Forwarded-Proto.
Thoughts?
Bearing in mind, that if the client connection is HTTP, but the internal connection is HTTPS, that's also confusing.
What is RACK_URL_SCHEME used for? Determining if the connection is secure from end to end? Generating URLs?