Skip to content

Commit

Permalink
net: do not inherit the no-half-open enforcer
Browse files Browse the repository at this point in the history
`Socket.prototype.destroySoon()` is called as soon as `UV_EOF` is read
if the `allowHalfOpen` option is disabled. This already works as a
"no-half-open enforcer" so there is no need to inherit another from
`stream.Duplex`.
  • Loading branch information
lpinca committed Mar 7, 2018
1 parent dc3969e commit 5b73a79
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 10 deletions.
11 changes: 7 additions & 4 deletions lib/net.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ const {
ERR_SOCKET_BAD_PORT,
ERR_SOCKET_CLOSED
} = errors.codes;
const DuplexBase = require('internal/streams/duplex_base');
const dns = require('dns');

const kLastWriteQueueSize = Symbol('lastWriteQueueSize');
Expand Down Expand Up @@ -238,7 +239,11 @@ function Socket(options) {
// For backwards compat do not emit close on destroy.
options.emitClose = false;

stream.Duplex.call(this, options);
// `DuplexBase` is just a slimmed down constructor for `Duplex` which allow
// us to not inherit the "no-half-open enforcer" as there is already one in
// place. Instances of `Socket` are still instances of `Duplex`, that is,
// `socket instanceof Duplex === true`.
DuplexBase.call(this, options);

if (options.handle) {
this._handle = options.handle; // private
Expand All @@ -263,8 +268,6 @@ function Socket(options) {
this._writev = null;
this._write = makeSyncWrite(fd);
}
this.readable = options.readable !== false;
this.writable = options.writable !== false;
} else {
// these will be set once there is a connection
this.readable = this.writable = false;
Expand All @@ -282,7 +285,7 @@ function Socket(options) {
this._writableState.decodeStrings = false;

// default to *not* allowing half open sockets
this.allowHalfOpen = options && options.allowHalfOpen || false;
this.allowHalfOpen = options.allowHalfOpen || false;

// if we have a handle, then start the flow of data into the
// buffer. if not, then this will happen when we connect
Expand Down
7 changes: 1 addition & 6 deletions test/parallel/test-http-connect.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,12 +75,7 @@ server.listen(0, common.mustCall(() => {
assert.strictEqual(socket.listeners('connect').length, 0);
assert.strictEqual(socket.listeners('data').length, 0);
assert.strictEqual(socket.listeners('drain').length, 0);

// the stream.Duplex onend listener
// allow 0 here, so that i can run the same test on streams1 impl
assert(socket.listenerCount('end') <= 2,
`Found ${socket.listenerCount('end')} end listeners`);

assert.strictEqual(socket.listeners('end').length, 1);
assert.strictEqual(socket.listeners('free').length, 0);
assert.strictEqual(socket.listeners('close').length, 0);
assert.strictEqual(socket.listeners('error').length, 0);
Expand Down
11 changes: 11 additions & 0 deletions test/parallel/test-net-socket-no-halfopen-enforcer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
'use strict';
require('../common');

// This test ensures that `net.Socket` does not inherit the no-half-open
// enforcer from `stream.Duplex`.

const { Socket } = require('net');
const { strictEqual } = require('assert');

const socket = new Socket({ allowHalfOpen: false });
strictEqual(socket.listenerCount('end'), 1);

0 comments on commit 5b73a79

Please sign in to comment.