fix(intercept): Add support for node 10.x ClientRequest#1428
fix(intercept): Add support for node 10.x ClientRequest#1428
Conversation
paulmelnikow
left a comment
There was a problem hiding this comment.
Hi! Thanks so much for this contribution. I left some comments about it.
lib/intercept.js
Outdated
|
|
||
| inherits(ErroringClientRequest, http.ClientRequest) | ||
|
|
||
| function urlToOptions(input) { |
There was a problem hiding this comment.
Is there some API and/or source code reference for this translation?
There was a problem hiding this comment.
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
| ) | ||
| } | ||
|
|
||
| if (typeof input === 'string' && typeof options === 'object') { |
There was a problem hiding this comment.
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.
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.
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.
@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.
There was a problem hiding this comment.
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.
👍
@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
| } | ||
|
|
||
| module.request = function(options, callback) { | ||
| module.request = function(input, options, callback) { |
There was a problem hiding this comment.
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
| * @param {boolean} legacy | ||
| */ | ||
| const overrideRequests = function(newRequest) { | ||
| const overrideRequests = function(newRequest, legacy) { |
There was a problem hiding this comment.
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.
| } | ||
| } | ||
| inherits(OverriddenClientRequest, http.ClientRequest) | ||
| function OverriddenClientRequest(input, options, cb) { |
There was a problem hiding this comment.
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.