-
Notifications
You must be signed in to change notification settings - Fork 29.6k
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
fs / streams: file descriptor leak on connection abort #1834
Comments
Is it a bug? I thought it was a known limitation of streams. It seems that the only way to solve this is to propagate errors upstream |
Re the linked EMFILE issue I wonder if I hit something similar load testing a node server yesterday. I was doing exactly the same, pounding it with ab, and every once in a while EMFILE killed it. Was a little suspicious given a very short stack trace - IIRC TCP onconnection then events.js. If it is related it's been around aong time.. discovered I was still running 0.10.32. Anything I could do to help? |
Yep, this is a known issue with piping fs streams into http responses. I'll investigate fixing this. |
Also see #1180. They seem to be the same bug but I'm not sure which to close (or leave both open). I'll mark this issue as a bug. |
Is this something that could be fixed by something like: diff --git a/lib/_http_outgoing.js b/lib/_http_outgoing.js
index 99fa8ff..7aa362b 100644
--- a/lib/_http_outgoing.js
+++ b/lib/_http_outgoing.js
@@ -7,6 +7,7 @@ const util = require('util');
const internalUtil = require('internal/util');
const Buffer = require('buffer').Buffer;
const common = require('_http_common');
+const fs = require('fs');
const CRLF = common.CRLF;
const chunkExpression = common.chunkExpression;
@@ -81,6 +82,12 @@ function OutgoingMessage() {
this._headerNames = {};
this._onPendingData = null;
+
+ this.on('pipe', (source) => {
+ if (source instanceof fs.ReadStream) {
+ this.on('close', source.destroy.bind(source));
+ }
+ });
}
util.inherits(OutgoingMessage, Stream); or would it need to be fixed at the streams level? |
This would only fix this specific instance of the issue (http + fs). The general issue is that This is what npm module pump tries to do, and with more than two piped streams too. But it's hard to do with no standard for close/destroy. |
there is an defacto standard for close/destroy - all core streams have that, and many many userland streams get it for free via |
although, adding error propagation into node streams would have unpredictable effects. |
@bnoordhuis ... I assume this is still an issue? |
Yes, it's still unfixed. |
Hmm given what has been mentioned about destroy(), does that mean this issue could do with a positive outcome in the discussion at #4401? |
It's been a year, let's ask again... @bnoordhuis ... I assume this is still an issue? |
I do not think that is a bug, it's how streams work. Now we have We are tracking progress on this in: nodejs/readable-stream#283. I'm 👍 to close this, or remove 'confirmed bug' label, as it is not a bug. |
Closing. |
just for the record, pull-streams do not have this problem. |
purpose: * ensure that file descriptors are closed, and never leak - if a fd were to leak as the result of the file having been requested by a client and served by httpd, then the underlying file will remain open and cause the OS to prevent the file from being deleted until the process running `serve` terminates potential causes for fd leak: 1) bug in `serve` https://github.com/vercel/serve-handler/blob/6.1.3/src/index.js#L751 summary: - the fd is opened BEFORE checking ETag to conditionally return a 304 Not Modified Response - when this occurs, the fd is never piped to the response, and it is never closed 2) bug in `nodejs` nodejs/node#1180 nodejs/node#1834 summary: - if the client closes the connection before the piped fd stream is fully written to the response, it has been reported that the fd is never closed workaround: https://github.com/jshttp/on-finished#example
From nodejs/node-v0.x-archive#6041 (comment):
Hit with
ab
but ^C before it completes and check the open files afterwards:I think we should assign some prio to this even if it's an old bug because it's a great way to DoS a server.
/cc @nodejs/streams
The text was updated successfully, but these errors were encountered: