BrowserSync / browser-sync

Keep multiple browsers & devices in sync when building websites. https://browsersync.io
https://discord.gg/2d2xUThp
Apache License 2.0
12.17k stars 756 forks source link

[proxy] Cannot set Cache-Control header with middleware #719

Closed lookfirst closed 9 years ago

lookfirst commented 9 years ago
let expireHeaders = (req, res, next) => {
    res.setHeader('cache-control', 'public, max-age=0');
    next();
};
    proxy: {
        middleware: expireHeaders
    }

No matter what I do, the header always comes out as:

cache-control: public, max-age=600

I don't know where the issue is, foxy or http-proxy or somewhere else, but I'd like to be able to set this header.

Note that setting the Expires header works just fine, but the Server header doesn't. So, that makes me think that it is only possible to set headers which aren't already set.

lookfirst commented 9 years ago

@shakyShane If you want to point me in the right direction for where to look on this, I'll be happy to submit a PR.

shakyShane commented 9 years ago

@lookfirst thanks!

Sorry I've not had time to look at this just yet, as soon as I do I'll happily help you with a PR - thanks for the offer :)

shakyShane commented 9 years ago

Hmm actually this one caught my attention, so...

When you set a middleware on the proxy like this...

var bs = require('./').create();

bs.init({
    proxy: "http://www.bbc.co.uk",
    middleware: function (req, res, next) {
        res.setHeader('some-header', 'some-amazey-value');
        next();
    }
});

... providing that a header called some-header is NOT set by the server response, the one set in the middleware above will persist. However, should the header name clash, the one set by the server will always override it.

Getting this to work as expected is something which i think would be extremely helpful and a great addition to Browsersync - but work first needs to happen in the Foxy module.

Foxy uses node-http-proxy which emits the proxyRes event following the target's response - this is the point in which you can modify headers and such after the server has sent them. You can see how I register the proxyRes handler which just does some basic cookie/rewrite fixes etc.

I would suggest changing this to accept an array of functions as opposed to the 1 used currently. Then, you make foxy accept a new config property called proxyRes which can also be an array of functions. Concat these two together when registering the listener and boom, you have an extendable system for modifying the server response.

Finally, within Browsersync we'd just accept the proxy.proxyRes property from config and pass it through to Foxy.

Up for the challenge? I'd be happy to help along the way :)

lookfirst commented 9 years ago

@shakyShane

This change is super important. :smile: I use jspm and it loads a metric asston of files in 'development' mode... each JS import is a separate load. Being able to properly control the Expires headers for those files would really speed up development and churn on my machine.

I want to have DevTools open and uncheck the 'disable cache when devtools is open' setting and have browserSync properly send expires headers for my files. Especially important is the .map files which don't currently obey that setting in DevTools... debugging my ES6 code puts me on the wrong line unless I clear the chrome cache myself.

So, to be clear, proxyRes in BS will just accept an array of middleware functions (ie: => (req, res, next)? Sure, I'll start working on some PR's for foxy and bs... thanks for the guidance.