summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorisaacs <i@izs.me>2013-06-14 15:57:11 -0700
committerisaacs <i@izs.me>2013-06-16 19:06:27 -0700
commit3c7945bda10567af23daf5302842d99d4f9f3db0 (patch)
treeeef26442dbe666a4373712c21279b3a0a4fc3684
parent10133aaa467648b62e537bd7160bea2e4e33824d (diff)
downloadnode-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.js3
-rw-r--r--test/simple/test-child-process-stdio-big-write-end.js79
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);
+ });
+}