-
-
Notifications
You must be signed in to change notification settings - Fork 3.2k
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
fix: should not destroy streams #612
Conversation
}, | ||
"engines": { | ||
"node": ">= 0.12.0", | ||
"iojs": ">= 1.0.0" | ||
"node": ">= 0.12.0" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
node >= 4
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we drop the support of node < 4 in koa@1 ? /cc @tj @jonathanong
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh, master is v1.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should be its own pull request
0da33f7
to
42382b4
Compare
42382b4
to
65f13fb
Compare
ping @jonathanong @fengmk2 |
LGTM |
- "4" | ||
- "5" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should be its own pull request
65f13fb
to
bbf850b
Compare
@juliangruber all fixed |
bbf850b
to
078cac0
Compare
var app = koa(); | ||
let stream1 = fs.createReadStream(__filename); | ||
let stream2 = fs.createReadStream(__filename); | ||
stream1.once('end', done); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i don't understand why this one would end as well? it's never read from
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we'll destroy(consume) all stream's that set to this.body
here https://github.com/koajs/koa/pull/612/files#diff-d86a59ede7d999db4b7bc43cb25a1c11R166
hmmm, this seems more like an edge case to me. are there other cases that would benefit from this change? |
The most serious problem now is http keepalive sockets will be destroyed, and we must fix this issue. Not sure any other side effect if we destroy the streams. |
are you sure destroying a http stream will affect other requests on the same socket? sounds more like a node bug to me |
If you destroy an That will affect other |
any suggestions? I'll merge this PR if no response in the next day. :) |
Hey man, no need to put a deadline on it. If you need it urgently use a fork or find a userland solution. |
I think this is just a bug fix. so if anyone doubt this patch, I'll leave it here and fix in our own framework for now. :) |
this patch fails if the body stream is endless, like for example: this.body = fs.createReadStream('/dev/urandom'); or more real-worldy this.body = serverSentEvents(createUpdateStream()); in the cases above it's required to destroy the stream. |
and trying to read it all out will never finish |
although i don't think pipe an endless stream to response meaningful. but maybe there is a solution has less impact. detect the stream in |
078cac0
to
a949d79
Compare
use black-hole-stream to make sure stream's data has been read
a949d79
to
d9c1ea3
Compare
@juliangruber how about this? |
too edge-casy. koa should not need to worry about this. Just to be sure, this would work for you, right? httpStream.destroy = blackHole.bind(null, httpStream);
this.body = httpStream; |
it is a common usage that use koa as a http proxy, and anybody who use |
maybe a better solution is to just wrap the http stream in another stream so you never set the http stream as the actual const PassThrough = require('stream').PassThrough
app.use(function * (next) {
this.body = httpStream.on('error', this.onerror).pipe(PassThrough())
}) would need docs on this though... super edge case |
what about documenting that a body stream can be |
|
onFinish(this.res, function(){ | ||
// don't destroy http IncomingMessage, keep `keep-alive` conncetion alive. | ||
if (val instanceof http.IncomingMessage) { | ||
if (val.readable) val.pipe(new BlackHoleStream()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why do you need black hole stream? just val.resume()
to dump it
anyways prefer going the documentation route. will close this when i or someone else adds documentation |
It's ok to add some warning in documentation. |
Didn't understand a thing from the documentation on what's happening here. |
@catamphetamine, they were warning not to set a http-request-alike-stream which has keep-alive enabled. Because the framework will close the stream by default, which will break keep-alive feature. Generally, it's OK with |
@dead-horse 有什么好的办法能避免这类错误吗? 谢谢 |
@dead-horse 马哥好,昨天夜里见到这个 issue 忘了跟你打招呼了,白天来踩一下。 ----- 骄傲的用中文交流 |
use black-hole-stream to make sure stream's data has been read.
since user may set
this.body
to a httpIncomingMessage
, if we destroy this stream, it will destroy the http socket that makekeep-alive
failed, and may affect other http requests reusing this socket.I think maybe we shouldn't destroy streams, only need to insure streams' data will be read and don't leak.