diff options
author | isaacs <i@izs.me> | 2013-06-14 15:57:11 -0700 |
---|---|---|
committer | isaacs <i@izs.me> | 2013-06-16 19:06:27 -0700 |
commit | 3c7945bda10567af23daf5302842d99d4f9f3db0 (patch) | |
tree | eef26442dbe666a4373712c21279b3a0a4fc3684 | |
parent | 10133aaa467648b62e537bd7160bea2e4e33824d (diff) | |
download | node-3c7945bda10567af23daf5302842d99d4f9f3db0.tar.gz |
net: Do not destroy socket mid-write
The fix in e0519ace315c7ce14278d5eaab8d1d72a0a0a054 is overly zealous,
and can destroy a socket while there are still outstanding writes in
progress.
Closes GH-5688
-rw-r--r-- | lib/net.js | 3 | ||||
-rw-r--r-- | test/simple/test-child-process-stdio-big-write-end.js | 79 |
2 files changed, 81 insertions, 1 deletions
diff --git a/lib/net.js b/lib/net.js index 620fd29a3..93d942a9f 100644 --- a/lib/net.js +++ b/lib/net.js @@ -411,7 +411,8 @@ function maybeDestroy(socket) { if (!socket.readable && !socket.writable && !socket.destroyed && - !socket._connecting) { + !socket._connecting && + !socket._writableState.length) { socket.destroy(); } } diff --git a/test/simple/test-child-process-stdio-big-write-end.js b/test/simple/test-child-process-stdio-big-write-end.js new file mode 100644 index 000000000..845a23e66 --- /dev/null +++ b/test/simple/test-child-process-stdio-big-write-end.js @@ -0,0 +1,79 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +var common = require('../common'); +var assert = require('assert'); +var BUFSIZE = 1024; + +switch (process.argv[2]) { + case undefined: + return parent(); + case 'child': + return child(); + default: + throw new Error('wtf?'); +} + +function parent() { + var spawn = require('child_process').spawn; + var child = spawn(process.execPath, [__filename, 'child']); + var sent = 0; + + var n = ''; + child.stdout.setEncoding('ascii'); + child.stdout.on('data', function(c) { + n += c; + }); + child.stdout.on('end', function() { + assert.equal(+n, sent); + console.log('ok'); + }); + + // Write until the buffer fills up. + do { + var buf = new Buffer(BUFSIZE); + buf.fill('.'); + sent += BUFSIZE; + } while (child.stdin.write(buf)); + + // then write a bunch more times. + for (var i = 0; i < 100; i++) { + var buf = new Buffer(BUFSIZE); + buf.fill('.'); + sent += BUFSIZE; + child.stdin.write(buf); + } + + // now end, before it's all flushed. + child.stdin.end(); + + // now we wait... +} + +function child() { + var received = 0; + process.stdin.on('data', function(c) { + received += c.length; + }); + process.stdin.on('end', function() { + console.log(received); + }); +} |