1// Copyright Joyent, Inc. and other Node contributors. 2// 3// Permission is hereby granted, free of charge, to any person obtaining a 4// copy of this software and associated documentation files (the 5// "Software"), to deal in the Software without restriction, including 6// without limitation the rights to use, copy, modify, merge, publish, 7// distribute, sublicense, and/or sell copies of the Software, and to permit 8// persons to whom the Software is furnished to do so, subject to the 9// following conditions: 10// 11// The above copyright notice and this permission notice shall be included 12// in all copies or substantial portions of the Software. 13// 14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 17// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 18// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 19// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 20// USE OR OTHER DEALINGS IN THE SOFTWARE. 21 22'use strict'; 23const common = require('../common'); 24 25// Ref: https://github.com/nodejs/node-v0.x-archive/issues/5504 26// 27// This test only fails with CentOS 6.3 using kernel version 2.6.32. 28// On other Linuxes and macOS, the `read` call gets an ECONNRESET in 29// that case. On sunos, the `write` call fails with EPIPE. 30// 31// However, old CentOS will occasionally send an EOF instead of an 32// ECONNRESET or EPIPE when the client has been destroyed abruptly. 33// 34// Make sure we don't keep trying to write or read more in that case. 35 36switch (process.argv[2]) { 37 case 'server': return server(); 38 case 'client': return client(); 39 case undefined: return parent(); 40 default: throw new Error('invalid'); 41} 42 43function server() { 44 const net = require('net'); 45 const content = Buffer.alloc(64 * 1024 * 1024, '#'); 46 net.createServer(function(socket) { 47 this.close(); 48 socket.on('end', function() { 49 console.error('end'); 50 }); 51 socket.on('_socketEnd', function() { 52 console.error('_socketEnd'); 53 }); 54 socket.write(content); 55 }).listen(common.PORT, common.localhostIPv4, function() { 56 console.log('listening'); 57 }); 58} 59 60function client() { 61 const net = require('net'); 62 const client = net.connect({ 63 host: common.localhostIPv4, 64 port: common.PORT 65 }, function() { 66 client.destroy(); 67 }); 68} 69 70function parent() { 71 const spawn = require('child_process').spawn; 72 const node = process.execPath; 73 74 const s = spawn(node, [__filename, 'server'], { 75 env: Object.assign(process.env, { 76 NODE_DEBUG: 'net' 77 }) 78 }); 79 80 wrap(s.stderr, process.stderr, 'SERVER 2>'); 81 wrap(s.stdout, process.stdout, 'SERVER 1>'); 82 s.on('exit', common.mustCall()); 83 84 s.stdout.once('data', common.mustCall(function() { 85 const c = spawn(node, [__filename, 'client']); 86 wrap(c.stderr, process.stderr, 'CLIENT 2>'); 87 wrap(c.stdout, process.stdout, 'CLIENT 1>'); 88 c.on('exit', common.mustCall()); 89 })); 90 91 function wrap(inp, out, w) { 92 inp.setEncoding('utf8'); 93 inp.on('data', function(chunk) { 94 chunk = chunk.trim(); 95 if (!chunk) return; 96 out.write(`${w}${chunk.split('\n').join(`\n${w}`)}\n`); 97 }); 98 } 99} 100