-
Notifications
You must be signed in to change notification settings - Fork 122
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
333 - Implement customHeadersToSkipOnWeakVersion functionality #343
333 - Implement customHeadersToSkipOnWeakVersion functionality #343
Conversation
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 for your PR. It already looks excellent. I think it may benefit from a couple of improvements. What do you think?
res.set(componentResponse.headers); | ||
} else { | ||
//weak version request, therefore skip the blacklisted headers if any | ||
if (_.isEmpty(res.conf.customHeadersToSkipOnWeakVersion || [])) { |
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.
Isn't || []
redundant as you're already doing that in the options' sanitiser?
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.
Fixed
if (_.isEmpty(res.conf.customHeadersToSkipOnWeakVersion || [])) { | ||
res.set(componentResponse.headers); | ||
} else { | ||
var headersToSkip = new Set(res.conf.customHeadersToSkipOnWeakVersion); |
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.
Wouldn't be easier to use underscore's omit here?
var headersToSet = _.omit(componentResponse.headers.map(function(el){
return el.toLowerCase();
}), res.conf.customHeadersToSkipOnWeakVersion);
if(!_.isEmpty(headersToSet)) res.set(headersToSet);
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.
Fixed! Thanks for the idea ;-)
requestData.headers = options.headers || {}; | ||
requestData.method = 'get'; | ||
|
||
var req = require('http').request(requestData).on('response', function(response) { |
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.
I guess you're doing all of this because minimal-request
doesn't allow you to access response headers. This is not great, I can totally extend minimal-request to do that and then this test should look a bit more neat. Still, not a blocker for merging this, definitely a quick improvement for a later PR. Sorry for that 👍
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.
Completely agree with you. Will modify/fix this once we have the change in minimal-request.
var headersToSkip = new Set(res.conf.customHeadersToSkipOnWeakVersion); | ||
|
||
_.forEach(Object.keys(componentResponse.headers), function(header) { | ||
if (!headersToSkip.has(header.toLowerCase())) { |
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.
I was thinking that if we change setHeader to sanitise the headers by "lowercasing" it then we may not need to "lowercase" it here?
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.
Done
84b3223
to
ec01742
Compare
ec01742
to
526fe04
Compare
@matteofigus, all the requested changes are in place now. This one also includes upgrading of minimal-request to version 2.2.0 :-) |
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.
Just a couple more very minimal changes! Getting there!
Thanks 👍
@@ -465,6 +465,53 @@ describe('registry : routes : component', function(){ | |||
}); | |||
}); | |||
|
|||
describe('when getting a component with server.js that sets custom headers with empty customHeadersToSkipOnWeakVersion', 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.
"not empty"?
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.
Should be fixed
it('should not set the HTTP response test-headers', function() { | ||
expect(response.headers).to.not.be.null; | ||
expect(response.headers['test-header']).to.equal('test-value'); | ||
expect(headers).to.be.undefined; |
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.
I think here I got a bit confused by the response.headers and headers. Do we need here to test response.headers if what we care about is just expect(headers).to.be.undefined
to prove that should not set the HTTP response test-headers
?
Also, I think same would apply for line 456
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.
Yea, I see your point.
The idea of skipping some predefined headers from the response is to cope with the normal HTTP proxies that stay on the request-response route. Because of the GET request if they are going to do something with the response (like caching) they will do it based on the request string where we don't have a strong version. That's why we validate we don't set the HTTP response headers.
On the other hand in the response body we do have both the requested version and the actually returned version. That's why I'm exposing the headers there as well, so the response is something like:
{
"type": "oc-component-local",
"version": "1.0.1",
"requestVersion": "1.0.1",
"name": "hello-world",
"renderMode": "rendered",
"href": "http://localhost:3030/hello-world/1.0.1",
"headers": {
"test-header": "test-value"
},
"html": "...."
}
This allows us to have those custom headers in POST responses as well :-)
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.
But more and more I'm thinking over this and more I agree with your note here...
Regarding the consistency perhaps it's better to strip them from everywhere.
If you agree I can issue one more commit with this in place?
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.
I think I can't see any value for having headers
into the GET /component response body, as we should use the headers for that. So, for simplicity, I agree about stripping the headers from the headers 🤣 in case this setting is on, and I vote for just removing the headers
from the response in any case.
In case of the POST batch, I think it is a bit different. Using the response body for the headers is the simplest way to include the headers in each component. The way I would tackle it there, is to have a headers
key in the response that behaves exactly as the headers in the GET. Still, I think we can do the POST in a separate PR if you agree.
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.
I updated the change to include this -- I also put the logic for POST requests together with some tests
"from": "minimal-request@2.1.1", | ||
"resolved": "https://registry.npmjs.org/minimal-request/-/minimal-request-2.1.1.tgz" | ||
"from": "minimal-request@2.2.0", | ||
"resolved": "https://registry.npmjs.org/minimal-request/-/minimal-request-2.2.0.tgz" |
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.
I actually have done that on master already with #349 so I guess you just need to rebase from master here?
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.
Oh I actually was able to rebase here. Hope you don't mind 👍
- Introduced new registry option - customHeadersToSkipOnWekVersion which expects to be an array of strings denoting the headers that have to be omitted from the response in case a weak version is requested (i.e 1.x.x). The rational behind this is the need to control cache related headers - in case 1.x.x version is requested we would not like cache headers to be returned because otherwise the response will be cached. Next time when someone asks for 1.x.x it will get the cached response even though a new version may be available. - added unit and integration tests
- also context.setHeader function was extended a bit and now includes a sanity check for the arguments
05ec822
to
6658726
Compare
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.
Only one thing not very clear to me?
it('should skip Cache-Control header', function() { | ||
expect(result[0].response.version).to.equal('1.0.0'); | ||
expect(result[0].response.name).to.equal('hello-world-custom-headers'); | ||
expect(result[0].response.headers).to.be.deep.equal({'cache-control': 'public max-age=3600', 'test-header': 'Test-Value'}); |
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.
Shouldn't this skip 'Cache-Control' header and be eql to {'test-header': 'Test-Value'}
?
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 are right. It's more on that though. Actually I didn't realise the POST requests go to components.js instead of component.js. Now this is fixed. Also one of the big trouble with the tests for POST requests was that they are following after those for GET and they are working with an already set customHeadersToSkipOnWeakVersion. So I did a slight refactoring of the before/afters there as well.
Apologies for this mess :-)
And can I ask for one more review, please?
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.
No problem, looking now 👍
…and GET requests - for GET it will put the custom headers in the HTTP response headers - for POST it will put the custom headers in the response body - the setCustomHeaders was moved out of component.js to get-component.js under the name filterCustomHeaders. It's because in case of POST request the code path is different and goes to component(s).js instead of component.js. Now we do the filtering in one and the same place. - fixed a bug where we used to not take into account the custom headers in case of a unrendered component. For this reason the actual setting of response headers was moved from line 205 up to line 175. - fixed the registry acceptance tests. In their former variant when the GET tests passes they were used to leave the customHeadersToSkipOnWeakVersion settings so the POST tests were starting directly with this setting on. That's why new before/after sections were defined to reinitialize the registry before the tests and then recover it after them.
6658726
to
b2f17e4
Compare
Amazing work @ivan-dimitrov-skyscanner - I published and updated the docs here: https://github.com/opentable/oc/wiki/Registry#registry-configuration - what do you think about the description? |
Awesome :-) |
Thanks to you! Feel free to edit the wiki if you want, you should be enabled to do it ;) |
to be an array of strings denoting the headers to be omitted from
the response in case a weak version is requested (i.e 1.x.x). The rational
behind this is the need to control cache related headers - in case 1.x.x
version is requested we would not like cache headers to be returned because
otherwise the response will be cached. Next time when someone asks for 1.x.x
it will get the cached response even though a new version may be available.