Given:
When running in proxy mode, we need the following headers in order for the application to work properly:
X-Forwarded-Host: The host requested by the client (i.e. the proxy address, not the existing server's address)Host: The existing server's address (right now it is the proxy server's address, which is wrong). In https://github.com/BrowserSync/browser-sync/pull/120#issuecomment-39418996 you confirmed the behavior I am asking for, but the implementation does not match what you said it should be.The first header is needed for security reasons (ability to detect local vs remote clients). The second header is needed for redirecting clients (e.g. redirect the user to the login page).
this will be landing in BrowserSync soon which will allow you to define your own headers for each request.
:)
@shakyShane Hmm, I don't fully understand https://github.com/BrowserSync/browser-sync/blob/master/examples/proxy.headers.js#L27. Where is config.urlObj documented?
@cowwoc sorry it's not documented yet, but it's just the foxy config object https://github.com/shakyShane/foxy/blob/master/lib/server.js#L16-L21
You could log it out for now to see what you have access to.
browserSync({
files: ["app/css/*.css"],
proxy: {
target: "localhost:8000",
reqHeaders: function (config) {
console.log(config);
return {
"host": config.urlObj.host,
"accept-encoding": "identity",
"agent": false
}
}
}
});
Thank you, @shakyShane, it works:
browserSync({
proxy: {
target: '127.0.0.1:5000',
reqHeaders: function (config) {
return {
// prevent Host header overriding
//"host": config.urlObj.host,
"accept-encoding": "identity", // disable any compression
"agent": false
};
},
middleware: function (req, res, next) {
res.setHeader("X-Forwarded-For", req.ip);
res.setHeader("X-Forwarded-Host", req.headers.host);
next();
}
}
});
It seems bit tricky because 'http-proxy' has xfwd option.
Thanks @generalov .
@cowwoc - does the example from @generalov work for you?
If it does and this is a common use-case I will add to core behind a single option. :)
version 2.7.0 allows any of the node-http-proxy options to be passed through, so in your case, xfwd is the one you want.
var bs = require('browser-sync').create();
bs.init({
proxy: {
target: "www.bbc.co.uk",
proxyOptions: {
xfwd: true
}
}
});
Thanks!
Seems xfwd is missing "x-forwarded-host"
@ericfong I ran into the same issue -- X-Forwarded-Host wasn't populated by xfwd.
Here's how I ended up populating it:
#!/usr/bin/env node
var path = require('path')
var home = path.normalize(__dirname + '../../..')
var bs = require('browser-sync').create()
bs.init({
files: [
path.join(home, 'server/static/*.*')
],
proxy: {
target: 'localhost:8000',
middleware: function (req, res, next) {
req.headers['X-Forwarded-Host'] = req.headers.host
next()
}
}
})
How to enable Host: header forwarding using the command line browser-sync? Is this the function of the --host option (its description, Specify a hostname to use is not very clear)?
Good question -- I assumed that it wasn't because that flag would traditionally control what interface the server would accept requests on. Not sure my assumption holds in this case. If it is a way to control the X header, the flag should probably be renamed.
If you want to pass the Host header to the backend unchanged, use the following config:
proxy: {
target: "...",
proxyOptions: {
changeOrigin: false
}
},
By default, browser-sync passes changeOriginal: true to node-http-proxy, and this will change the Host header.
there is no proxy.proxyOptions description in API Documention
I think this is interesting. I found this by luck and some googleing and @dancon is right, I also did not find any mention of this proxy.proxyOptions nore the changeOrigin in the docs anywhere — despite finding it very useful.
So happy I found this here now.
Most helpful comment
version 2.7.0 allows any of the node-http-proxy options to be passed through, so in your case,
xfwdis the one you want.