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

fix(intercept): Add support for node 10.x ClientRequest #1428

Closed
wants to merge 4 commits into from

Conversation

nijynot
Copy link

@nijynot nijynot commented Feb 2, 2019

Fixes #1227 and #1239.
Added two tests for the support of the new ClientRequest.

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 so much for this contribution. I left some comments about it.

lib/intercept.js Outdated
@@ -235,6 +235,27 @@ function ErroringClientRequest(error) {

inherits(ErroringClientRequest, http.ClientRequest)

function urlToOptions(input) {
Copy link
Member

Choose a reason for hiding this comment

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

Is there some API and/or source code reference for this translation?

Copy link
Author

Choose a reason for hiding this comment

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

Yes there is, it's from the Node.js' internal/url.js file. https://github.com/nodejs/node/blob/master/lib/internal/url.js#L1257

Added some comment to the urlToOptions function, and the link.

lib/intercept.js Outdated
@@ -256,6 +277,16 @@ function overrideClientRequest() {
)
}

if (typeof input === 'string' && typeof options === 'object') {
Copy link
Member

Choose a reason for hiding this comment

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

Am I correct this is this a Node-10-or-later feature? I wonder, is there harm in our supporting this in earlier versions of Node? I feel like that could lead to confusing disparity between nock and real ClientRequest. Perhaps we should conditionally support the new form when running in Node 10+.

Copy link
Author

Choose a reason for hiding this comment

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

Just checked on ClientRequest in Node master, it seems they do a typeof check in a similar way, and then re-assigning the input to options. I think it should be backwards compatible?
https://github.com/nodejs/node/blob/master/lib/_http_client.js#L63

Copy link
Member

Choose a reason for hiding this comment

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

I guess the question is: what happens if you're in Node 8 and you pass a string to a real ClientRequest? The behavior from ours should be the same.

Copy link
Author

@nijynot nijynot Feb 3, 2019

Choose a reason for hiding this comment

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

@paulmelnikow Ah, I see. I fixed it so that the Node 10 feature only work on Node 10 (see the requestParameters function). But I think this introduces some other problems, like testing. How do you test a Node 10 feature if you're on Node 8? Do we have a copy of Node 10 ClientRequest & Node <10 ClientRequest in nock so that tests work regardless of which Node you're testing with?

I guess easy solution would be to instead warn if someone uses Node 10 API when running on Node <10.

Edit: Nvm, ignore this

lib/intercept.js Outdated
if (input.username || input.password) {
options.auth = `${input.username}:${input.password}`
}
return options
Copy link
Member

Choose a reason for hiding this comment

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

It would be good to include tests to cover the rest of this function. It might be tempting to write these as unit tests, though we prefer to write functional tests via the public API because it helps ensure that all the code in the library is demanded by a real use case.

screen shot 2019-02-02 at 11 37 25 am

Copy link
Author

Choose a reason for hiding this comment

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

Added some more tests, specifically, tests that use http.request and http.get, which is what others will actually use.

* - Utility function that converts a URL object into an ordinary
* options object as expected by the http.request and https.request
* APIs.
* - https://github.com/nodejs/node/blob/7237eaa3353aacf284289c8b59b0a5e0fa5744bb/lib/internal/url.js#L1257
Copy link
Member

Choose a reason for hiding this comment

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

👍

@gr2m Since this is an internal Node API I think it makes sense to vendor in this function. Do you know if we need to acknowledge it somewhere besides what's done here, in order to comply with the license?

lib/common.js Outdated
@@ -94,7 +124,17 @@ const overrideRequests = function(newRequest) {
get: overriddenGet,
}

module.request = function(options, callback) {
module.request = function(input, options, callback) {
Copy link
Member

Choose a reason for hiding this comment

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

So we don't end up with three copies of this function, could you extract it to a helper function in common.js?

@paulmelnikow
Copy link
Member

Just a heads up that there are many lines of tests being moved in #1426 and it's a bit high risk, so I want to get that merged first. The tests here may need to be rebased after that lands.

*/
const overrideRequests = function(newRequest) {
const overrideRequests = function(newRequest, legacy) {
Copy link
Member

Choose a reason for hiding this comment

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

Hi! so sorry to be just now getting back to this!

I see you've added a parameter here, which it seems like must be set to true when running in Node 8 and false otherwise.

Could you do this in code instead, so the caller doesn't need figure out the correct value for this parameter? We used to have code that did semver.satisfies(process.version, '>=8') and I think the same approach would work well here (with '<10').

You can look at #1318 where one of these conditional checks was removed.

I see elsewhere you've added auto detection using ClientRequest.length.

I don't think this behavior should be, or needs to be, configurable. Could you export a single constant in common.js and condition everything on that? I am hoping it can tighten this up.

@@ -298,12 +307,73 @@ function overrideClientRequest() {
}
}
}
inherits(OverriddenClientRequest, http.ClientRequest)
function OverriddenClientRequest(input, options, cb) {
Copy link
Member

Choose a reason for hiding this comment

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

There is a lot of duplicated code here. If the legacy behavior is conditioned on a constant exported from common.js, could this be handled more simply, e.g. with an if statement around the part which differs?

@paulmelnikow
Copy link
Member

I tried to update your branch with latest beta and solve the merge conflict, but I don't have push access.

@paulmelnikow
Copy link
Member

paulmelnikow commented May 6, 2019

Pushed, thanks! By the way, GitHub provides a check box which makes it possible to give push access to the PR branch. That's an easier way to collaborate on PRs!

@nijynot
Copy link
Author

nijynot commented May 6, 2019

By the way, GitHub provides a check box which makes it possible to give push access to the PR branch

Oh, didn't know that, will keep that in mind. Definitely easier to collaborate that way. 😆

I'll also take a closer look at the PR again. I remember getting stuck at some things, but will try to figure them out this time in the following days, I hope.

@paulmelnikow
Copy link
Member

@nijynot Would you have some time to look at this? If not, no problem, I or one of the other maintainers could try to pick it up.

@paulmelnikow paulmelnikow mentioned this pull request Jun 8, 2019
6 tasks
@nijynot
Copy link
Author

nijynot commented Jun 9, 2019

@paulmelnikow Yeah, would be better if you or some other maintainer picked it up instead so I don't block.
I'll leave it as it is, so anyone is free to pick it up.

@mastermatt
Copy link
Member

I've looked into this issue a bit already. I'll take a stab at it and see what happens.

@paulmelnikow
Copy link
Member

Closing in favor of #1588.

11.x automation moved this from In progress to Done Jul 7, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
No open projects
11.x
  
Done
Development

Successfully merging this pull request may close these issues.

nock does not support the new Node.js 10.9 signature http.request(url[, options][, callback])
3 participants