-
-
Notifications
You must be signed in to change notification settings - Fork 733
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
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.
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) { |
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.
Is there some API and/or source code reference for this translation?
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.
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') { |
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.
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+.
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 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
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 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.
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.
@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 |
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.
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.
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 |
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.
👍
@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) { |
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.
So we don't end up with three copies of this function, could you extract it to a helper function in common.js
?
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. |
542fe39
to
40aff4d
Compare
*/ | ||
const overrideRequests = function(newRequest) { | ||
const overrideRequests = function(newRequest, legacy) { |
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.
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) { |
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.
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?
I tried to update your branch with latest |
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! |
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. |
@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 Yeah, would be better if you or some other maintainer picked it up instead so I don't block. |
I've looked into this issue a bit already. I'll take a stab at it and see what happens. |
Closing in favor of #1588. |
Fixes #1227 and #1239.
Added two tests for the support of the new ClientRequest.