-
-
Notifications
You must be signed in to change notification settings - Fork 530
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
socket connect
event is not emitted when sending multiple requests concurrently with a http agent keepAlive: true
#2259
Comments
This is golden! Linking mswjs/interceptors#594 for reference. |
We encountered this issue in our test-suite with Stripe too |
DiscoveryThis turned out to be a really interesting one! It has nothing to do with reusing sockets or The root cause for this issue is that Interceptors require the request header to be written to the socket in order to dispatch the You can circumvent this by flushing request headers preemptively: req.on('socket', (socket) => {
socket.on('connect', () => req.end()
})
+req.flushHeaders()
By default, Node.js buffers Socket writes before you call Alas, there is no way to listen when Node.js does its buffering (which happens here). I'd rather we kept the number of workarounds to the minimum. What we should do, is somehow know if you've flushed the request headers or not (or called this._read = () => {
const headerSent = !!this.parser?.outgoing._headerSent
console.log('headers sent?', { headerSent })
} This is less hacky but still not ideal. From what I can see, there is nothing else on the Node.js also starts the request stream processing if you write something to a request ( |
This comes down to the Socket determining only the fact of a network connection (no requests sent yet), and the interceptor controlling the network on the request basis (so the request has to happen). There are no plans to give you any network-based APIs, those would be too low level and would only work in Node.js. |
I've opened a fix at mswjs/interceptors#643. |
SolutionAfter testing this a bit and giving it some more thought, I think this use case is an inherent limitation of the interception algorithm we have:
These two are contradictory. You are locking the request header send by deferring How to fix this?You have two options to fix this problem. Option 1: Call
|
For those who also end up here due to the stripe SDK's requests not being intercepted: Here's a potential workaround, which applies to you, if:
Workaround: tell stripe to use fetch instead! const stripe = new Stripe(<STRIPE_SECRET_KEY>, {
apiVersion: "<API_VERSION>",
httpClient: Stripe.createFetchHttpClient(),
}); |
Prerequisites
Environment check
msw
versionNode.js version
v22.7.0
Reproduction repository
https://github.com/mizozobu/msw-socket-mre
Snapshot of the repo for future reference. (I'll delete it once this issue gets resolved).
Reproduction steps
npm i
node index.mjs
Current behavior
3 sockets are created, but only 1 socket emits
connect
event.I encountered this when I was using msw with stripe. Some reproduction code was taken from the repo.
Expected behavior
All sockets emit
connect
event.The text was updated successfully, but these errors were encountered: