-
-
Notifications
You must be signed in to change notification settings - Fork 89
Add support for reverse proxies by checking req.hostname or req.host. Fixes #20 #21
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
base: master
Are you sure you want to change the base?
Add support for reverse proxies by checking req.hostname or req.host. Fixes #20 #21
Conversation
…ixes expressjs#20 This is so that the module works when express has `trust proxy` enabled and the `Host` header is expected to come from `X-Forwarded-Host`
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! Yes, as you noted in the other issue, we do strive to support raw Node.js server, not only Express. I think this is a good start, but has a few issues. I'll put together a more comprehensive list when I'm at a computer, but it's missing added docs, shouldn't be adding a connect dependency for tests, and you should not be applying that Host parsing to the result of hostname (nor req.host when express is below 5).
I've added docs to the readme. I've also removed the connect dependency from the tests. To do this i had to change the tests to execute on the nextTick of the event loop so that I have a chance modify the request object in Regarding the host parsing, is there any harm in doing it twice? We can definitely prevent it from happening in express v3 as this is documented to be void of portno http://expressjs.com/en/3x/api.html#req.host. Regarding express v4/v5 (both of them have We could do a check to see if express has been used and return early if you want?
|
I'll follow up on this next week. |
But the short, quick thought I have right now is that yes, you need to remove the double unwrapping and you need to find a better solution over adding that |
Also, keep in mind that this module strives to work with any server implementation, not just Express. This means that the presence of req.host / req.hostname doesn't mean Express is even being used. |
A good example of why double-parsing is not going to work: IPv6. Take the header |
I see that makes sense. I'm not too familiar with ipv6 addresses. Wouldn't the IPv6 issue already be a problem with this module, if the host header is We could look to use node's URL module to do this instead? That way we'd only need to perform the port removal if it doesnt exist? |
No, because that's not even a valid Host header. It would be |
test/test.js
Outdated
next() | ||
// Running tests on next tick so we can modify the request object via | ||
// the `request` event on http.Server | ||
process.nextTick(next) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs to be done some different way.
test/test.js
Outdated
|
||
request(app) | ||
.get('/') | ||
.set('Host', '::1') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not a valid Host header. Don't need to test that, imo.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My bad, from briefly reading the ipv6 wiki page i falsely assumed that they didnt need to have square brackets if there was no port.
test/test.js
Outdated
}) | ||
|
||
app.on('request', function (req) { | ||
req.host = '::1' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not a valid req.host.
I've removed the invalid host headers and the tests are all still passing even with the portless IPv6 addresses. I've also removed the |
Hi @domharrington , awesome! It looks like the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still pending fixing the double host decoding in express 4 and below.
test/test.js
Outdated
return http.createServer(function onRequest (req, res) { | ||
// This allows you to perform changes to the request/response | ||
// objects before our assertions | ||
pretest = pretest || function () {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typically, you don't want to reassign variables that represent function arguments.
test/test.js
Outdated
// objects before our assertions | ||
pretest = pretest || function () {} | ||
|
||
return http.createServer().on('request', pretest).on('request', function onRequest (req, res) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could probably just call pretest(req, res)
inside the onRequest
function rather than adding an additional listener.
I can't seem to reproduce express below 4 returning a Here are the outcomes for these properties in different versions of express: With the following express app: var app = require('express')()
app.get('/', function (req, res) {
res.end(JSON.stringify({ host: req.host, hostname: req.hostname }))
})
app.listen(3000) And the following curl command: curl "http://[::1]:3000" We get these outcomes: {"host":"[::1]"} {"host":"[::1]","hostname":"[::1]"} {"host":"[::1]:3000","hostname":"[::1]"} |
Huh. I'm sooo sorry if I made to run against nothing :/ I probably should have left the PR at my comment that I would revisit this next week. I got carried away thinking I could actually review thins on my phone with running the PR or really looking at the source code for anything. I think let's leave it as is for now and I take that real look next week, as promised :) |
Have you had a chance to review this? |
I haven't had a chance yet, due to machine issues :S I did just earlier today get a brand new machine! So been working on setting up git and such so I'll be taking a look this weekend 💃 |
Ohh that always takes longer than you want it to. No rush - good luck! |
Sorry I kinda forgot about this :/ Working on getting it fixed up & merged. I noticed that |
Any headway on this or anything that I can help with to get this moving? |
I've not had a chance to revisit this recently. @dougwilson mentioned that |
Noticed today while trying to put an express behind a load balancer that it does not work yet with X-Forwarded-Host. What is the current status of this PR? |
no issue - extracted from expressjs/vhost#21 - uses `req.hostname` if it's available. `req.hostname` is set to the `x-forwarded-host` value when `'trust proxy'` setting is enabled in express
Can someone please merge this |
no issue - extracted from expressjs/vhost#21 - uses `req.hostname` if it's available. `req.hostname` is set to the `x-forwarded-host` value when `'trust proxy'` setting is enabled in express
Just checking in, @dougwilson can this get merged and released? |
I feel it's a little passive aggressive to silently mark our comments asking for updates on this as spam. If you have no plans to merge this work in then maybe this PR should be closed out, or if this project is deprecated then maybe the repo should be archived, otherwise we would greatly appreciate it if you could tell us whatever we need to get this through the door. |
Hi @erunion I'm not sure who marked them that way, as the project has various triagers who help with issues. I unhid them if that makes you feel better. As I mentioned above, this PR ends up where the The project works just fine without this and is not deprecated. Perhaps instead of just ignoring the comment that there is an issue with the PR and demanding it be merged and released without any other comment, our triagers would not have marked your comment as spam. If you are looking for it to get released quicker, I look forward to you contributing the above fixes help to get it moving 👍 |
@dougwilson Sorry I wasn't demanding, we just wanted some clarification on what needed to be done here to wrap this up as it had been a couple years and all the tests are passing locally on versions of Node. |
@erunion I added some inline comments on the code issues. Tests can easily pass when they are incomplete, which is the case here. Tests need to be built out as well to cover all the scenarios, particularly the couple where they fail with the existing code. Also tests do pass, but |
@dougwilson Thanks for the comments, we'll work on getting these fixed up. What version of Node are you seeing |
Hi @erunion it was happened on the CI server (though that whole things needs to be migrated now that Travis CI is gone), but also locally on Node.js 18 (node v18.13.0). Just FYI I need to head out, but I may be back later this week if you have more questions. The CI system needs to get re-setup on GH Actions here before merge, which will also confirm if the |
I think this was a duplicate line from the one above, so this node-version wasn't getting applied when trying to install from 14.x
Hey! I just merged in your latest changes to get GH Actions CI working on my fork: https://github.com/domharrington/vhost/actions. Having some issues with getting the tests running... I think I fixed one issue with the 14.x version: domharrington@0f7cd48 Now there's a 500 coming back from the Node.js download for v11.x: https://github.com/domharrington/vhost/actions/runs/5068450197/jobs/9100808151. Any ideas? |
For those that are coming to this issue and want to use this code, you can run the following to install from my fork:
npm i "github:domharrington/vhost#496f19be396ab2531149862bfacfdd72e8ae1751"
This is so that the module works when express has
trust proxy
enabledand the
Host
header is expected to come fromX-Forwarded-Host