Skip to content
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

Added compatibility with node-http-proxy header altering #1484

Merged
merged 9 commits into from Jul 22, 2019

Conversation

AlexGilleran
Copy link
Contributor

Thanks so much for the great project, really really helpful for testing node microservices.

This PR makes it possible to test node-http-proxy using nock. Node-http-proxy is essentially a reverse proxy for node - you can get incoming http calls, modify them and redirect them to another url.

One of its features is being able to modify headers programmatically with code like this:

proxy.on('proxyReq', function(proxyReq, req, res, options) {
  proxyReq.setHeader('X-Special-Proxy-Header', 'foobar');
});

If you try to make it proxy to a nock mock, however, you'll find that the headers it recieves are always the unmodified ones (i.e. "X-Special-Proxy-Header" won't be present) because of how nock copies headers out of the original http.request call into options.

This adds a bit of code to copy the headers out of the req at the last moment in case they've changed, similar to how req.path is copied back into options.path for superagent compatibility.

@AlexGilleran
Copy link
Contributor Author

Coveralls is breaking because there's a line that looks for empty headers, but headers are never empty now because nock always sets host.

I'm not sure if having host always set for nock might break something not covered by the unit tests? Should I be filtering it out?

Might wait to see your comments (or if you think this is a good idea at all) before I proceed further :).

Copy link
Member

@paulmelnikow paulmelnikow left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi! Thanks for this contribution!

I think this change makes sense… I left a note about the test and also about the implementation. Please take a look!

const reqHeaders = req.getHeaders ? req.getHeaders() : req._headers
if (Object.keys(reqHeaders).length > 0) {
options.headers = req.getHeaders ? req.getHeaders() : req._headers
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this be replaced with options.headers = req.getHeaders()? The req.getHeaders truthiness check is unnecessary in the Node versions we support. That would also fix the coverage issue you mentioned.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep sounds simpler - the only problem is that is causes some of the other tests that are expecting headers: undefined to fail because they now get headers: {}, but that's easy enough to change in the test if you're happy with it :).

@@ -1711,3 +1712,43 @@ test('teardown', t => {
t.deepEqual(leaks, [], 'No leaks')
t.end()
})

test('works when headers removed by http-proxy', t => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're in the process of changing the way we test nock–client integration issues. These issues are important, though it's unwieldy to include large-bracket tests in this repo because it doesn't tell nock developers what the problem is. In addition, the internals of client libraries can change. While this is a decent regression test for the integration, it doesn't prevent against regression of the specific behaviors we want to ensure.

The idea is to build nock–client integration tests in separate repositories, which test the latest development version of nock against. We'd really welcome help getting that started! See a discussion in #1427 which goes into more detail about it.

What we need here is a unit test, probably using the http module, which exercises the issue you're seeing, in a way that a future developer working on nock can understand. Is it possible to express the bug that way?

In general we want to do the standard thing, not implement workarounds for libraries, so writing the test using http should help make it clear whether what we're doing here is sufficiently standard. (It sounds like it is, though TBH it's we're all still getting up to speed with the Nock codebase.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair enough - I think I can probably pull out what http-proxy is doing into the test itself and remove the dependency :).

@paulmelnikow
Copy link
Member

Hey @AlexGilleran, thought I would follow up on this! Would you have time to take a look at writing a more isolated test?

@AlexGilleran
Copy link
Contributor Author

Oops yep sorry, I'll get back on it :)

@AlexGilleran
Copy link
Contributor Author

@paulmelnikow - simplified the code change and rewrote the tests to only depend on http, ready for another review :).

@mastermatt
Copy link
Member

@AlexGilleran Could you remove your changes from package-lock.json and merge the beta branch into your branch again? There is a conflict because some other tests were also added to the end of test_intercept.js.

@AlexGilleran
Copy link
Contributor Author

@mastermatt done!

Thing is that because options.headers is now coming from req.getHeaders(), options.headers is never undefined (at least I don't think it ever returns undefined??), so I had to remove some falsiness checks to get the coverage to 100%, because I can't figure out any way to make options.headers falsy.

There's also a few formatting changes even after I manually prettier-ified everything using the version in package.json - I can manually revert if needed.

Copy link
Member

@mastermatt mastermatt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@AlexGilleran Thanks, this looks great.

I expected those header checks to go away, so I think we're good to go here.

@nockbot
Copy link
Collaborator

nockbot commented Aug 12, 2019

🎉 This PR is included in version 11.0.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants