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

🚧 Gregor's code review and refactor #2252

Open
wants to merge 93 commits into
base: main
Choose a base branch
from
Open

🚧 Gregor's code review and refactor #2252

wants to merge 93 commits into from

Conversation

gr2m
Copy link
Member

@gr2m gr2m commented Nov 15, 2021

Not much to see here yet, I'm still messing around.

My goal is to change the codebase into ways that there are clear separations of concerns based on folders, with the goal to move the different folders into separate modules. I'm current working on the intercept part.

You can learn more at #2247

Remaining TODOs

  • In common.headersFieldNamesToLowerCase we no longer cover throwOnDuplicate not being truthy
  • Use Mitm or a similar module for intercepting requests instead of overwriting http.ClientRequest entirely
  • Use https://github.com/gr2m/http-recorder for recording requests

Non-breaking changes

I had to add these two methods but I think we shouldn't mention them because they will be removed again once we stop overwriting the entire http.ClientRequest class and instead hook into it by patching http.ClientRequest.prototype.onSocket

  • added: interceptedClientRequest.nockSendRealRequest()
  • added: interceptedClientRequest.nockGetRequestBodyChunks()

Breaking changes

  • Before, the intercept logic occurred directly in the overridden http.ClientRequest constructor, after the socket event was emitted. Now, the intercept logic is only called if an actual request is being sent (after the connect event was emitted)

    Before

    // called `errorHandler` immediately, before request is even sent
    new http.ClientRequest({ port: 12345, path: '/' }).on('error', errorHandler)

    After

    // called `errorHandler` not called until request is sent.
    const request = new http.ClientRequest({ port: 12345, path: '/' }).on(
      'error',
      errorHandler
    )
    request.end()
  • When a request is not intercepted, we call the interal request.nockSendRealRequest() method provided by the new intercept module. When that happens, the real request is sent out, but the orginal http.{get,request} methods are not called. The propor fix to this breaking change is to not override http.{get,request} and http.ClientRequest in the first place and instead hook into the http.ClientRequest constructor, as mitm does.

```js
const got = require('got')

const intercept = require('./modules/node-intercept')

run()

async function run() {
  const reset = intercept()

  console.log('Intercepted:')
  console.log(await got('https://example.com').text())
  // logs "Hello, world!"

  console.log('\n\nNot Intercepted:')
  reset()
  console.log(await got('https://example.com').text())
  // logs HTML from example.com
}
```
…thout arguments. Check if response callback is set before using
…methods are called in case a request is not intercepted
Copy link
Member Author

@gr2m gr2m left a comment

Choose a reason for hiding this comment

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

  • In common.headersFieldNamesToLowerCase we no longer cover throwOnDuplicate not being truthy

@@ -85,7 +85,7 @@ describe('Direct use of `ClientRequest`', () => {

it('should throw an expected error when creating with empty options', () => {
expect(() => new http.ClientRequest()).to.throw(
'Creating a ClientRequest with empty `options` is not supported in Nock'
'Making a request with empty `options` is not supported in Nock'
Copy link
Member Author

Choose a reason for hiding this comment

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

Technically a breaking change, but ... 🤷🏼❓

done()
}
)
request.end()
Copy link
Member Author

@gr2m gr2m Dec 26, 2021

Choose a reason for hiding this comment

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

See breaking changes

@@ -117,7 +117,7 @@ describe('Nock lifecycle functions', () => {
const req = http.request('http://example.test', () => {
done()
})
req.once('socket', () => {
req.once('connect', () => {
Copy link
Member Author

Choose a reason for hiding this comment

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

I'll try to restore the original behavior so that this test passes

tests/test_remove_interceptor.js Show resolved Hide resolved
// it is not intercepted has no longer access to the original `http.{get,request}` methods.
// This will become obsolete when don't overwrite these methods at all and instead
// hook into the `http.ClientRequest` constructor, as the `mitm` package does.
it.skip('TODO! when http.get and http.request have been overridden before nock overrides them, http.get calls through to the expected method', async () => {
Copy link
Member Author

Choose a reason for hiding this comment

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

I'll create follow up issue for these, I'd consider them known bugs until we finish the refactoring that no longer requires a custom http.ClientRequest implementation

Comment on lines -789 to +797
it('when http.get and http.request have been overridden before nock overrides them, http.request calls through to the expected method', async () => {
// Skipping for now because the new way a real request gets sent out in case
// it is not intercepted has no longer access to the original `http.{get,request}` methods.
// This will become obsolete when don't overwrite these methods at all and instead
// hook into the `http.ClientRequest` constructor, as the `mitm` package does.
it.skip('TODO! when http.get and http.request have been overridden before nock overrides them, http.request calls through to the expected method', async () => {
Copy link
Member Author

Choose a reason for hiding this comment

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

I'll create follow up issue for these, I'd consider them known bugs until we finish the refactoring that no longer requires a custom http.ClientRequest implementation

@cspotcode
Copy link
Contributor

Use Mitm or a similar module for intercepting requests instead of overwriting http.ClientRequest entirely

Is the goal still to use mitm, or to switch to @gr2m/node-net-interceptor?

I was looking also at https://mswjs.io/docs/ and see they use https://github.com/mswjs/interceptors. I don't know if collaboration makes sense to reduce workload. Their interceptor does not do socket-level net interception.

@gr2m
Copy link
Member Author

gr2m commented Jul 26, 2022

Is the goal still to use mitm, or to switch to @gr2m/node-net-interceptor?

The plan is to use these

I don't know if collaboration makes sense to reduce workload

Maybe? We need to decompose nock into smaller modules first, that will enable to swap out interceptors and maybe use the ServiceWorkers one from mswjs, but I haven't looked into that yet, there is still lots of work left to do.

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

Successfully merging this pull request may close these issues.

None yet

2 participants