mirror of
https://github.com/nodejs/node.git
synced 2024-12-01 16:10:02 +01:00
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
|
||||
added: v0.11.3
|
||||
changes:
|
||||
- version: REPLACEME
|
||||
pr-url: https://github.com/nodejs/node/pull/27836
|
||||
description: Support the `allowHalfOpen` option.
|
||||
- version: v12.4.0
|
||||
pr-url: https://github.com/nodejs/node/pull/27816
|
||||
description: The `hints` option is now supported.
|
||||
@ -1217,6 +1220,10 @@ changes:
|
||||
Connection/disconnection/destruction of `socket` is the user's
|
||||
responsibility; calling `tls.connect()` will not cause `net.connect()` to be
|
||||
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
|
||||
verified against the list of supplied CAs. An `'error'` event is emitted if
|
||||
verification fails; `err.code` contains the OpenSSL error code. **Default:**
|
||||
|
@ -410,7 +410,7 @@ function TLSSocket(socket, opts) {
|
||||
|
||||
net.Socket.call(this, {
|
||||
handle: this._wrapHandle(wrap),
|
||||
allowHalfOpen: socket && socket.allowHalfOpen,
|
||||
allowHalfOpen: socket ? socket.allowHalfOpen : tlsOptions.allowHalfOpen,
|
||||
readable: false,
|
||||
writable: false
|
||||
});
|
||||
@ -1403,6 +1403,7 @@ exports.connect = function connect(...args) {
|
||||
const context = options.secureContext || tls.createSecureContext(options);
|
||||
|
||||
const tlssock = new TLSSocket(options.socket, {
|
||||
allowHalfOpen: options.allowHalfOpen,
|
||||
pipe: !!options.path,
|
||||
secureContext: context,
|
||||
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…
Reference in New Issue
Block a user