-
Notifications
You must be signed in to change notification settings - Fork 30k
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
http
requests with socketPath
lead to EPIPE
error
#41062
Comments
I believe the key part of the reproduction is the // change
request.write('{}', null, () => {
request.end()
})
// to
request.end('{}') This may be a viable workaround, although userland packages like |
From a quick look the problem is in the server code. The socket is destroyed when const http = require('http')
http.createServer((req, res) => {
req.resume()
res.writeHead(200, {'Content-Type': 'text/plain'})
req.on('end', () => {
res.end('ok')
});
}).listen('sock.sock') |
Waiting for the |
I can reproduce with Node.js v16.7.0 but not with Node.js v16.6.2 so I guess this is caused by #39525. |
@lpinca Do you think this is a bug or an intended change in behavior? |
It is a bug. With #41062 (comment) server code no error should be emitted. |
Do you think it's a bug in |
I honestly don't know. The libuv update might have uncovered a latent Node.js bug. |
cc: @vtjnash @nodejs/libuv |
If I revert libuv/libuv@23bebf0 I can no longer reproduce the issue. cc: @twose |
It sounds somewhat similar to the bug I fixed in nodejs's TLS around connection management (#36111). That libuv commit is not the primary cause, but it does exacerbate some known bugs in nodejs's network stack. However, it doesn't look like this is using TLS, so that commit won't itself fix this bug. Instead, this is probably the same as the related issues there #39363 and #39683, whereby a malicious client apparently can cause recent versions of nodejs http server to abort the process, by disconnecting network access in the middle of communication. |
I agree with @vtjnash , there are no incompatible or destructive behavior changes in the libuv patch, it just simplifies the code. |
I cannot reproduce the issue if I remove the HTTP layer (using only the |
One more thing. I cannot reproduce the issue if the |
The problem here is that Line 883 in 32f7218
might be called right after Line 823 in 32f7218
That final empty chunk should technically not be sent as all the data specified by the I'm not sure how to fix this. Replacing |
Yes, that was my thinking too. This patch seems to fix the issue and the tests, but one which looks easily fixable, seem to be fine with it on Linux. WDYT?
|
@santigimeno it also fixes the issue on macOS. It seems good to me. |
On a second look I think that the patch prevents the |
When calling OutgoingMessage.end() with empty data argument, avoid writing to the socket unless there's still pending data to be sent. Fixes: nodejs#41062
When calling OutgoingMessage.end() with empty data argument, avoid writing to the socket unless there's still pending data to be sent. Fixes: nodejs#41062
When calling OutgoingMessage.end() with empty data argument, avoid writing to the socket unless there's still pending data to be sent. Fixes: #41062 PR-URL: #41116 Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Gerhard Stöbich <deb2001-github@yahoo.de> Reviewed-By: James M Snell <jasnell@gmail.com>
When calling OutgoingMessage.end() with empty data argument, avoid writing to the socket unless there's still pending data to be sent. Fixes: #41062 PR-URL: #41116 Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Gerhard Stöbich <deb2001-github@yahoo.de> Reviewed-By: James M Snell <jasnell@gmail.com>
When calling OutgoingMessage.end() with empty data argument, avoid writing to the socket unless there's still pending data to be sent. Fixes: #41062 PR-URL: #41116 Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Gerhard Stöbich <deb2001-github@yahoo.de> Reviewed-By: James M Snell <jasnell@gmail.com>
When calling OutgoingMessage.end() with empty data argument, avoid writing to the socket unless there's still pending data to be sent. Fixes: #41062 PR-URL: #41116 Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Gerhard Stöbich <deb2001-github@yahoo.de> Reviewed-By: James M Snell <jasnell@gmail.com>
When calling OutgoingMessage.end() with empty data argument, avoid writing to the socket unless there's still pending data to be sent. Fixes: #41062 PR-URL: #41116 Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Gerhard Stöbich <deb2001-github@yahoo.de> Reviewed-By: James M Snell <jasnell@gmail.com>
When calling OutgoingMessage.end() with empty data argument, avoid writing to the socket unless there's still pending data to be sent. Fixes: nodejs#41062 PR-URL: nodejs#41116 Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Gerhard Stöbich <deb2001-github@yahoo.de> Reviewed-By: James M Snell <jasnell@gmail.com>
When calling OutgoingMessage.end() with empty data argument, avoid writing to the socket unless there's still pending data to be sent. Fixes: #41062 PR-URL: #41116 Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Gerhard Stöbich <deb2001-github@yahoo.de> Reviewed-By: James M Snell <jasnell@gmail.com>
Version
v16.7.0
Platform
Linux e332ae582690 5.10.47-linuxkit #1 SMP Sat Jul 3 21:51:47 UTC 2021 x86_64 Linux
Subsystem
No response
What steps will reproduce the bug?
Start a server and client using the following scripts:
server.js
:client.js
:On
v16.7.0
, this leads to anEPIPE
error after a few hundred requests. Onv16.6.2
, it does not hit anEPIPE
error after many thousands of requests.A full Docker Linux reproduction is here: https://github.com/mhassan1/node-16-7-0-request-epipe
How often does it reproduce? Is there a required condition?
It reproduces every time within a few hundred requests.
What is the expected behavior?
No
EPIPE
.What do you see instead?
EPIPE
after a few hundred requests:node:events:371 throw er; // Unhandled 'error' event ^ Error: write EPIPE at afterWriteDispatched (node:internal/stream_base_commons:164:15) at writeGeneric (node:internal/stream_base_commons:155:3) at Socket._writeGeneric (node:net:780:11) at Socket._write (node:net:792:8) at writeOrBuffer (node:internal/streams/writable:389:12) at _write (node:internal/streams/writable:330:10) at Socket.Writable.write (node:internal/streams/writable:334:10) at ClientRequest._writeRaw (node:_http_outgoing:362:17) at ClientRequest._send (node:_http_outgoing:338:15) at ClientRequest.end (node:_http_outgoing:880:10) Emitted 'error' event on ClientRequest instance at: at Socket.socketErrorListener (node:_http_client:447:9) at Socket.emit (node:events:394:28) at emitErrorNT (node:internal/streams/destroy:157:8) at emitErrorCloseNT (node:internal/streams/destroy:122:3) at processTicksAndRejections (node:internal/process/task_queues:83:21) { errno: -32, code: 'EPIPE', syscall: 'write' }
Additional information
http
proxy withsocketPath
leads toEPIPE
error #40553v14.18.0
but notv14.17.6
The text was updated successfully, but these errors were encountered: