tls: allow client-side sockets to be half-opened
Make `tls.connect()` support an `allowHalfOpen` option which specifies whether or not to allow the connection to be half-opened when the `socket` option is not specified. PR-URL: https://github.com/nodejs/node/pull/27836 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Ouyang Yadong <oyydoibh@gmail.com> Reviewed-By: Sam Roberts <vieuxtech@gmail.com>
This commit is contained in:
parent
f25bbf1255
commit
c3b8e50143
@ -1177,6 +1177,9 @@ being issued by trusted CA (`options.ca`).
|
|||||||
<!-- YAML
|
<!-- YAML
|
||||||
added: v0.11.3
|
added: v0.11.3
|
||||||
changes:
|
changes:
|
||||||
|
- version: REPLACEME
|
||||||
|
pr-url: https://github.com/nodejs/node/pull/27836
|
||||||
|
description: Support the `allowHalfOpen` option.
|
||||||
- version: v12.4.0
|
- version: v12.4.0
|
||||||
pr-url: https://github.com/nodejs/node/pull/27816
|
pr-url: https://github.com/nodejs/node/pull/27816
|
||||||
description: The `hints` option is now supported.
|
description: The `hints` option is now supported.
|
||||||
@ -1217,6 +1220,10 @@ changes:
|
|||||||
Connection/disconnection/destruction of `socket` is the user's
|
Connection/disconnection/destruction of `socket` is the user's
|
||||||
responsibility; calling `tls.connect()` will not cause `net.connect()` to be
|
responsibility; calling `tls.connect()` will not cause `net.connect()` to be
|
||||||
called.
|
called.
|
||||||
|
* `allowHalfOpen` {boolean} If the `socket` option is missing, indicates
|
||||||
|
whether or not to allow the internally created socket to be half-open,
|
||||||
|
otherwise the option is ignored. See the `allowHalfOpen` option of
|
||||||
|
[`net.Socket`][] for details. **Default:** `false`.
|
||||||
* `rejectUnauthorized` {boolean} If not `false`, the server certificate is
|
* `rejectUnauthorized` {boolean} If not `false`, the server certificate is
|
||||||
verified against the list of supplied CAs. An `'error'` event is emitted if
|
verified against the list of supplied CAs. An `'error'` event is emitted if
|
||||||
verification fails; `err.code` contains the OpenSSL error code. **Default:**
|
verification fails; `err.code` contains the OpenSSL error code. **Default:**
|
||||||
|
@ -410,7 +410,7 @@ function TLSSocket(socket, opts) {
|
|||||||
|
|
||||||
net.Socket.call(this, {
|
net.Socket.call(this, {
|
||||||
handle: this._wrapHandle(wrap),
|
handle: this._wrapHandle(wrap),
|
||||||
allowHalfOpen: socket && socket.allowHalfOpen,
|
allowHalfOpen: socket ? socket.allowHalfOpen : tlsOptions.allowHalfOpen,
|
||||||
readable: false,
|
readable: false,
|
||||||
writable: false
|
writable: false
|
||||||
});
|
});
|
||||||
@ -1403,6 +1403,7 @@ exports.connect = function connect(...args) {
|
|||||||
const context = options.secureContext || tls.createSecureContext(options);
|
const context = options.secureContext || tls.createSecureContext(options);
|
||||||
|
|
||||||
const tlssock = new TLSSocket(options.socket, {
|
const tlssock = new TLSSocket(options.socket, {
|
||||||
|
allowHalfOpen: options.allowHalfOpen,
|
||||||
pipe: !!options.path,
|
pipe: !!options.path,
|
||||||
secureContext: context,
|
secureContext: context,
|
||||||
isServer: false,
|
isServer: false,
|
||||||
|
73
test/parallel/test-tls-connect-allow-half-open-option.js
Normal file
73
test/parallel/test-tls-connect-allow-half-open-option.js
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const common = require('../common');
|
||||||
|
|
||||||
|
// This test verifies that `tls.connect()` honors the `allowHalfOpen` option.
|
||||||
|
|
||||||
|
if (!common.hasCrypto)
|
||||||
|
common.skip('missing crypto');
|
||||||
|
|
||||||
|
const assert = require('assert');
|
||||||
|
const fixtures = require('../common/fixtures');
|
||||||
|
const tls = require('tls');
|
||||||
|
|
||||||
|
{
|
||||||
|
const socket = tls.connect({ lookup() {} });
|
||||||
|
assert.strictEqual(socket.allowHalfOpen, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const socket = tls.connect({ allowHalfOpen: false, lookup() {} });
|
||||||
|
assert.strictEqual(socket.allowHalfOpen, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
const server = tls.createServer({
|
||||||
|
key: fixtures.readKey('agent1-key.pem'),
|
||||||
|
cert: fixtures.readKey('agent1-cert.pem'),
|
||||||
|
}, common.mustCall((socket) => {
|
||||||
|
server.close();
|
||||||
|
|
||||||
|
let message = '';
|
||||||
|
|
||||||
|
socket.setEncoding('utf8');
|
||||||
|
socket.on('data', (chunk) => {
|
||||||
|
message += chunk;
|
||||||
|
|
||||||
|
if (message === 'Hello') {
|
||||||
|
socket.end(message);
|
||||||
|
message = '';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on('end', common.mustCall(() => {
|
||||||
|
assert.strictEqual(message, 'Bye');
|
||||||
|
}));
|
||||||
|
}));
|
||||||
|
|
||||||
|
server.listen(0, common.mustCall(() => {
|
||||||
|
const socket = tls.connect({
|
||||||
|
port: server.address().port,
|
||||||
|
rejectUnauthorized: false,
|
||||||
|
allowHalfOpen: true,
|
||||||
|
}, common.mustCall(() => {
|
||||||
|
let message = '';
|
||||||
|
|
||||||
|
socket.on('data', (chunk) => {
|
||||||
|
message += chunk;
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on('end', common.mustCall(() => {
|
||||||
|
assert.strictEqual(message, 'Hello');
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
assert(socket.writable);
|
||||||
|
assert(socket.write('Bye'));
|
||||||
|
socket.end();
|
||||||
|
}, 50);
|
||||||
|
}));
|
||||||
|
|
||||||
|
socket.write('Hello');
|
||||||
|
}));
|
||||||
|
|
||||||
|
socket.setEncoding('utf8');
|
||||||
|
}));
|
38
test/parallel/test-tls-socket-allow-half-open-option.js
Normal file
38
test/parallel/test-tls-socket-allow-half-open-option.js
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const common = require('../common');
|
||||||
|
|
||||||
|
// Test the `allowHalfOpen` option of the `tls.TLSSocket` constructor.
|
||||||
|
|
||||||
|
if (!common.hasCrypto)
|
||||||
|
common.skip('missing crypto');
|
||||||
|
|
||||||
|
const assert = require('assert');
|
||||||
|
const net = require('net');
|
||||||
|
const stream = require('stream');
|
||||||
|
const tls = require('tls');
|
||||||
|
|
||||||
|
{
|
||||||
|
// The option is ignored when the `socket` argument is a `net.Socket`.
|
||||||
|
const socket = new tls.TLSSocket(new net.Socket(), { allowHalfOpen: true });
|
||||||
|
assert.strictEqual(socket.allowHalfOpen, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// The option is ignored when the `socket` argument is a generic
|
||||||
|
// `stream.Duplex`.
|
||||||
|
const duplex = new stream.Duplex({ allowHalfOpen: false });
|
||||||
|
const socket = new tls.TLSSocket(duplex, { allowHalfOpen: true });
|
||||||
|
assert.strictEqual(socket.allowHalfOpen, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const socket = new tls.TLSSocket();
|
||||||
|
assert.strictEqual(socket.allowHalfOpen, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// The option is honored when the `socket` argument is not specified.
|
||||||
|
const socket = new tls.TLSSocket(undefined, { allowHalfOpen: true });
|
||||||
|
assert.strictEqual(socket.allowHalfOpen, true);
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user